event 第55节 Event事件-Web前端开发之Javascript-零点程序员-王唯

日期: 2024-03-29 06:01:23|浏览: 96|编号: 40255

友情提醒:信息内容由网友发布,请自鉴内容实用性。

event 第55节 Event事件-Web前端开发之Javascript-零点程序员-王唯

,也可以称之为自顶向下的事件模型;

捕获事件流

事件捕获的用意在于,在事件到达预定目标之前捕获它;现代浏览器都支持捕获事件流,低版本IE不支持;

DOM2事件规范要求事件应该从对象开始,但标准浏览器都是从对象开始捕获事件的;

DOM事件流:

DOM同时支持两种事件模型,捕获型事件和冒泡型事件;DOM2事件规定事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段;

DOM事件流三个阶段

在DOM事件流中,实际的目标在捕获阶段不会接收到事件;目标阶段可以被看作是冒泡阶段的一部分;三个阶段的事件流会触及DOM中的所有对象,从对象开始,也在对象结束;

DOM2级事件规范明确要求,捕获阶段不会涉及事件目标;但现代浏览器都会在捕获阶段触发事件对象上的事件,其结果就是,有两次机会在目标对象上面操作事件;

注册事件处理程序/事件监听器:

用于响应某个事件而调用的函数称为事件处理程序(event ),或称为事件监听器(event );事件处理程序的返回值有时用来指示函数是否充分处理了事件,以及阻止浏览器的默认行为;

注册事件处理程序共有三种方式;

HTML事件处理程序:

在HTML元素的事件特性中指定,该事件特性的名称是“on”+事件名,且该事件特性中的值就是能够执行的代码,也就是HTML事件处理函数体;

不能在其中使用未经转义的HTML语法字符,如&、”、< >;

如果HTML事件处理程序里包含多条语句,必须使用分号分隔这些语句,或断开属性值使其可以跨越多行,如:

div1

甚至可以在其中定义函数,如:

div1

HTML事件处理程序也可以定义在页面其他位置,甚至是在一个外部的文件中;


Web前端开发

HTML事件处理程序,在后台会创建一个封装着元素属性(特性)值的函数,也就是由解释器动态创建的一个函数,该函数中还有一个局部变量event,也就是事件对象;

零点程序员

HTML事件处理程序中的this,指向事件的目标元素,如:

零点程序员

HTML事件处理程序中的作用域,比较特殊,它可以访问全局作用域中的任何变量和对象,但是它扩展作用域的方式,如同使用with语句,也就是说,在它内部可以像访问局部变量一样访问及该元素本身的成员,如:

function(){
    with(document){
        with(this){
            // 元素属性值
        }
    }
}

如此,事件处理程序在访问自己元素本身的属性(特性)就非常方便了,如:



如果当前元素是一个表单控件元素,则作用域中还会包含访问表单元素(父元素),如:

function(){
    with(document){
        with(this.form){
            with(this){
                // 元素属性值
            }
        }
    }
}

如此,事件处理程序不需要引用表单元素就能访问其他表单控件,如:

HTML事件处理程序缺点:

存在时间差:如果在响应时,当时的事件处理程序可能尚不具备执行条件,会出错;因此,为了避免这种错误发生,一是必须保证触发事件前,相关的处理程序必须定义好;二是可以把相关处理代码封装在try-catch中,如:

零点程序员

其特殊的扩展作用域链的方式在不同浏览器中可能会导致不同的结果;HTML与JS代码耦合性高;鉴于以上的缺点,因此HTML事件处理程序并不太常用;

DOM0级事件处理程序:

首先获得元素的引用,然后将函数赋值给该元素对应的事件处理函数属性;按照约定,事件处理程序的属性名以“on”为开头,以事件名为结尾;

window.onload = function(){
    console.log("loaded");
}
var oDiv = document.getElementById("mydiv");
oDiv.onclick = function(){
    alert("Web前端开发");
}

优点:简单,且具有跨浏览器的优势;

每个元素(包括和)都有自己的事件处理程序属性,并且这些属性名是区分大小写的,通常全部小写,即使属性名是由多个单词组成,例如:、、等;

这种事件处理程序被认为是元素的方法,因此,此时的事件处理程序是在元素的作用域中运行的,即其中的this引用当前元素,也就是事件目标;

var oDiv = document.getElementById("mydiv");
oDiv.onclick = function(){
    console.log(this);
    console.log(this.id);
    console.log(this.innerHTML);
}

因此,可以通过this访问该元素的任何属性和方法;

以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理;

document.documentElement.onclick = function(){
    console.log("html");
};
var oDiv = document.getElementById("mydiv");
oDiv.onclick = function(){
    console.log("div")
};
document.onclick = function(){
    console.log("document");
};
document.body.onclick = function(){
    console.log("body");
};
window.onclick = function(){
    console.log("window");
};

也可以删除事件这种事件处理程序,只需为其设置为null即可;如:

oDiv.onclick = null;

HTML事件处理程序和DOM0级事件处理程序的返回值:在某些情况下,可以为它们设置返回值;通常情况下,返回false,就是阻止浏览器默认行为,如:

链接

DOM0事件处理程序的缺点是,只能为目标元素的某种事件注册一个事件处理程序,如果注册多个,最后注册的会覆盖前面的,如:

var oDiv = document.getElementById("mydiv");
oDiv.onclick = function(){
    console.log("click");
};
oDiv.onclick = function(){
    console.log("click again");
};

DOM2级事件处理程序:

DOM2定义了标准的事件模型,为所有能成为事件目标的元素(包括和)定义了()方法,用于处理(注册)指定的事件处理程序;

该方法接受3个参数:要处理的事件名(不能加on,此处是标准的事件名)、作为事件处理程序的函数和一个布尔值;最后的参数值如果为true,表示在捕获阶段调用事件处理程序,如果false,表示在冒泡阶段调用事件处理程序,这个参数也可忽略,默认为false;

var oDiv = document.getElementById("mydiv");
oDiv.addEventListener("click", function(){
    console.log(this.id + ":被单击了");
}, false);
// 或
function clickHandle(){
    console.log(this.id + ":被单击了");
}
oDiv.addEventListener("click", clickHandle, false);

也可以为同一个事件注册多个事件处理程序;

function fn1(){console.log("第一个事件");}
function fn2(){console.log("第二个事件");}
oDiv.addEventListener("click", fn1, false);
oDiv.addEventListener("click", fn2, false);

同时定义HTML事件处理程序或DOM0级事件处理程序与DOM2级事件处理程序,如:

Web前端开发

()移除事件:通过()添加的事件处理程序只能用()方法来移除,移除时,所传入的与添加处理程序时的参数相同;

var oDiv = document.getElementById("mydiv");
function clickHandle(){
    console.log(this.id + ":被单击了");
    this.removeEventListener("click", clickHandle,false);
}
oDiv.addEventListener("click", clickHandle, false);

如果通过()添加匿名函数将无法移除,如:

oDiv.addEventListener("click", function(){
    console.log(this.id + ":被单击了");
}, false);
// 后期如果使用
oDiv.removeEventListener("click", function(){
    // 没有用的
},false);

但可以变相地移除,如:

oDiv.addEventListener("click", function(){
    console.log(this.id + ":被单击了");
    this.removeEventListener("click", arguments.callee,false);
}, false);

如果使用()将事件处理函数加入到捕获阶段,则必须在()中指明是捕获阶段,才能正确移除此事件,也就是第三个参数也必须相同;

function clickHandle(event){
    console.log(this.id + ":被单击了");
    this.removeEventListener("click", clickHandle,true);
}
oDiv.addEventListener("click", clickHandle, false);

也可以一次性移除多个事件,如:

function clickHandle(event){
    console.log(event.type);
    this.removeEventListener("mouseover", clickHandle,false);
    this.removeEventListener("mouseout", clickHandle,false);
    this.removeEventListener("click", clickHandle,false);
}
oDiv.addEventListener("click", clickHandle, false);
oDiv.addEventListener("mouseover", clickHandle, false);
oDiv.addEventListener("mouseout", clickHandle, false);

三个事件使用了相同的处理函数,此时,只要三个事件有中有一个事件被触发,三个事件处理程序都会被移除;

function clickHandle(event){
    console.log(event.type);
    this.removeEventListener("mouseover", overHandle,false);
    this.removeEventListener("mouseout", outHandle,false);
    this.removeEventListener("click", clickHandle,false);
}
function overHandle(){
    console.log("over");
}
function outHandle(){
    console.log("out");
}
oDiv.addEventListener("click", clickHandle, false);
oDiv.addEventListener("mouseover", overHandle, false);
oDiv.addEventListener("mouseout", outHandle, false);

分别使用了三个处理程序;

如果要获取Event事件对象,也是通过在事件处理函数的参数中指定;另外,事件处理程序中的this也是指当前元素;

oDiv.addEventListener("click", function(event){
    console.log(event);
    console.log(event.type);
    console.log(this.innerHTML);
}, false);

一般情况下,都将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度地兼容各种浏览器;

IE事件处理程序:

IE9及以下不支持DOM事件,但它实现了与DOM类似的事件,其为每个元素和对象添加了两个方法:(“”, ):用来给一个对象附加事件及事件处理函数;(“”, ):清除一个对象的事件及事件处理函数;两个方法都接受相同的两个参数:事件名称与处理函数,但事件名称必须以“on”开头,如;

var oDiv = document.getElementById("mydiv");
oDiv.attachEvent("onclick", function(){
    console.log("onclick");
});

(IE11不支持,IE10及以下支持)

也可以添加多个事件处理程序,但处理程序执行的顺序有可能与DOM不同,如;

var oDiv = document.getElementById("mydiv");
oDiv.attachEvent("onclick", function(){
    console.log("Web前端面开发");
});
oDiv.attachEvent("onclick", function(){
    console.log("大师哥王唯");
});
// 或
function fn1(){console.log("fn1");}
function fn2(){console.log("fn2");}
oDiv.attachEvent("onclick", fn1);
oDiv.attachEvent("onclick", fn2);

IE10和IE9的执行顺序与DOM相同,但IE8及以下,执行的顺序与DOM相反;

由于IE只支持事件冒泡(不支持事件捕获),所以以上方法会被添加到冒泡阶段;

oDiv.attachEvent("onclick", function(){
    console.log("div");
});
document.body.attachEvent("onclick", function(){
    console.log("body");
});
document.documentElement.attachEvent("onclick", function(){
    console.log("html");
});
document.attachEvent("onclick", function(){
    console.log("document");
});
window.attachEvent("onclick", function(){
    console.log("window");
});

对象上的并没有触发,说明IE的冒泡到顶层是对象;

使用()来移除()添加的事件处理程序,但也必须提供相同的参数,同时,它也不能移除添加的匿名函数,如:

var oDiv = document.getElementById("mydiv");
function clickHandler(){
    console.log("Web前端面开发");
    oDiv.detachEvent("onclick", clickHandler);
}
oDiv.attachEvent("onclick", clickHandler);
// 或
oDiv.attachEvent("onclick", function(){
    console.log("大师哥王唯");
    oDiv.detachEvent("onclick", arguments.callee);
});

使用()与使用DOM0级方法的主要区别在于事件处理程序的作用域,其会在全局作用域中运行,因此this等于;

oDiv.attachEvent("onclick", function(){
    console.log(this);  // window
    console.log(this === window); // true
});

可以封装一个函数,为一个元素添加某种类型的事件并注册相关的事件处理程序,并指定它的this为事件目标,如:

var oDiv = document.getElementById("mydiv");
function addEvent(target, type, handler){
    target.attachEvent("on" + type, function(event){
        // 把处理程序作为事件目标的方法调用,并传递事件对象
        return handler.call(target, event);
    });
}
// 在IE10以下测试
addEvent(oDiv, "click", function(event){
    console.log(event);
    console.log(this);  // div
});

在IE事件处理程序中,获取Event事件对象与DOM也不一样;

兼容DOM和IE注册事件处理程序:

var btn = document.getElementById("btn");
var handler = function(){
    console.log("Web前端开发");
};
if(btn.addEventListener)
    btn.addEventListener("click", handler, false);
else
    btn.attachEvent("onclick", handler);

跨平台添加/删除事件处理函数:

var EventUtil = {
    addHandler: function(element, type, handler){
        if(element.addEventListener)
            element.addEventListener(type, handler, false);
        else if(element.attachEvent)
            element.attachEvent("on" + type, handler);
        else
            element["on" + type] = handler;
    },
    removeHandler: function(element, type, handler){
        if(element.removeEventListener)
            element.removeEventListener(type, handler, false);
        else if(element.detachEvent)
            element.detachEvent("on" + type, handler);
        else
            element["on" + type] = null;
    }
}
// 应用
window.onload = function(){
    function clickHandler(){
        console.log("clickHandler");
        var oDiv = document.getElementById("mydiv");
        EventUtil.removeHandler(oDiv, "click", clickHandler);
    }
    var oDiv = document.getElementById("mydiv");
    EventUtil.addHandler(oDiv, "click", clickHandler);
}

Event事件对象:

在触发DOM上的某个事件时,会产生一个事件对象event,这个对象包含着所有与事件有关的信息;

var oDiv = document.getElementById("mydiv");
oDiv.addEventListener("click", function(event){
    console.log(event);  // MouseEvent,与鼠标事件相关的信息
});
document.addEventListener("keypress", function(event){
    console.log(event);  // KeyboardEvent,与按下的键相关的信息
});

获取事件信息很重要,一般会获取以下信息:引起事件的元素(对象)、事件的类型、事件发生时鼠标的信息、事件发生时键盘的信息等;不同的事件所包含的信息也不同,例如,鼠标致的事件对象中,会包含鼠标位置等相关的信息,而键盘操作导致的事件,会包含与按下的键有关的信息;

事件对象只在发生事件时才被创建,且只有事件处理函数才能访问;所有事件处理函数执行完毕后,事件对象就被销毁;所有浏览器都支持event事件对象,但支持方式不同,IE与DOM是用两种不同的方法实现事件对象;

DOM的事件对象:

在DOM中,event对象必须作为唯一的参数传给事件处理函数,DOM0级和DOM2级都是使用这个参数获取事件对象;

var oDiv = document.getElementById("mydiv");
oDiv.onclick = function(event){
    console.log(event);
}
oDiv.addEventListener("click", function(event){
    console.log(event);
});

在通过HTML特性添加的事件处理程序时,变量event保存着event对象,如:

Event类:

Event接口表示在 DOM 中出现的事件,其是其他类型事件的基类,包含适用于所有事件的属性和方法;构造函数:Event(),创建并返回一个 Event 对象;

语法:event = new Event(, );参数:,字符串,表示所创建事件的名称;可选,是 类型的字典对象,其接受以下字段:

var event = new Event("gohome", {"bubbles":true, "cancelable": false, "composed":false});
console.log(event);

但是IE不支持;有了事件后,就可以为某个元素添加这个事件,并注册其处理程序,如:

function goHomeHandler(event){
    console.log(event);
}
document.addEventListener("gohome", goHomeHandler,false);

使用()方法触发该事件,如:

document.dispatchEvent(event);
var oDiv = document.getElementById("mydiv");
oDiv.dispatchEvent(event);

由于这个事件是可以冒泡的,所以后代元素也可以触发该事件;

使用Event构造函数返回一个event对象的应用非常少,并且IE也不支持,后面我们会讲到另外一种创建自定义的Event对象的方法:.(“type”);如:

var event = document.createEvent("CustomEvent");
event.initCustomEvent("gohome",true,false,"我想家了");
function goHomeHandler(event){
    console.log(event);  // type为gohome的CustomEvent类型
    console.log(event.detail);
}

Event对象的属性和方法:

属性/方法类型读/写说明

Event对象包含与创建它的特定事件有关的属性和方法,但触发的事件类型不同,可用的属性和方法也不同;DOM事件对象还具有以下共同成员;

常见Event的子类:

type属性:

在需要通过一个函数处理多个事件时,可以使用type属性;

var btn = document.getElementById("btn");
btn.addEventListener("click", clickHandler, false);
btn.addEventListener("mouseover", clickHandler, false);
btn.addEventListener("mouseout", clickHandler, false);
function clickHandler(event){
    switch(event.type){
        case "click":
            console.log("click");
            break;
        case "mouseover":
            event.target.style.backgroundColor = "green";
            break;
        case "mouseout":
            event.target.style.backgroundColor = "";
            break;
    }
}

属性:返回由事件流所经过的DOM节点组成的Array;所有浏览器均未实现,但浏览器实现了一个类似的path属性;

// 在子元素div1上进入
var oDiv = document.getElementById("mydiv");
var div1 = document.getElementById("div1");
function handler(event){
    console.log(event.path);
}
// path数组中包括div1
oDiv.addEventListener("mouseover", handler,false);
// path数组中不包括div1
oDiv.addEventListener("mouseenter", handler,false);
composedPath():返回包含事件的路径的一个Array;
    console.log(event.composedPath());

返回的结束与path基本是一致的,但IE不支持此方法;

属性:

返回一个布尔值,表明当前事件是否会向DOM树上层元素冒泡;

// oDiv中有个id为div1的子元素
var oDiv = document.getElementById("mydiv");
function handler(event){
    console.log(event.type + ":"+event.bubbles +",target:" + event.target.id);
}
oDiv.addEventListener("mouseover", handler,false);
oDiv.addEventListener("mouseenter", handler,false);

例如可以检查该属性是否冒泡,如:

var oDiv = document.getElementById("mydiv");
function handler(event){
    if(!event.bubbles){
        console.log("不冒泡,做点什么事");
    }
    console.log("不管冒不冒泡,都去做");
}
// oDiv.addEventListener("mouseover", handler,false);
oDiv.addEventListener("mouseenter", handler,false);

this、、及属性:

var oDiv = document.getElementById("mydiv");
oDiv.addEventListener("mouseover", function(event){
    console.log(event.currentTarget);
    console.log(event.target);
    console.log(event.srcElement);
},false);

在事件处理程序内部,this始终等于的值,而则只包含事件的实际目标;如果直接将事件处理程序指定给了目标元素,则this、和包含相同的值;

var oDiv = document.getElementById("mydiv");
oDiv.addEventListener("click", function(event){
    console.log(event.currentTarget == this); // true
    console.log(event.target == this);  // true
},false);

如果事件处理程序被添加到元素的父节点上,三者就不相同,如:

document.body.addEventListener("click", function(event){
    console.log(event.currentTarget);
    console.log(this);
    console.log(event.currentTarget === document.body);
    console.log(this === document.body);
    console.log(event.target);
console.log(event.target == document.getElementById("mydiv"));
},false);

当将相同的事件处理程序注册到多个元素时,属性是很有用的,如:

function hide(event){
    event.currentTarget.style.visibility = "hidden";
    console.log(event.currentTarget);
}
var ps = document.getElementsByTagName("p");
for(var i=0,len=ps.length; i

对于属性,它本来是由IE6开始被引入的,与DOM事件的指向同一个对象,虽然现在被纳入标准,但在部分移动端浏览器中并不支持,所以在生产环境中,只是为了兼容老版的IE,并不把它作为标准的属性来使用;

属性:

事件对象的属性,返回一个整数值,用来确定事件当前正位于事件流的哪个阶段,如果没有事件正在被处理,该属性返回Event.NONE,值为0(这个值一般不会出现),如果在捕获阶段调用的事件处理程序,该属性返回Event.,值为1,如果事件处理程序处于目标对象上,则返回Event.,值为2,如果是在冒泡阶段调用的事件处理程序,返回Event.,值为3;

// 为mydiv添加一个子div,分别在子div和mydiv上单击
var oDiv = document.getElementById("mydiv");
oDiv.addEventListener("click", function(event){
    console.log(event.currentTarget);
    console.log(event.target);
    console.log(event.eventPhase);
},false);

目标对象本身的事件处理程序调用是第2个阶段;

如果事件处理程序被注册为捕获,那它会在事件传播的第1个阶段被调用;

document.body.addEventListener("click", function(event){
    console.log(event.currentTarget);
    console.log(event.target);
    console.log(event.eventPhase);
},true);

分别注册捕获型事件处理程序:

var div1 = document.getElementById("div1");
div1.addEventListener("click", function(event){
    console.log("div1:" + event.eventPhase);  // 1
},true);
var oDiv = document.getElementById("mydiv");
oDiv.addEventListener("click", function(event){
    console.log("div:" + event.eventPhase);  // 1
},true);
document.body.addEventListener("click", function(event){
    console.log("body:" + event.eventPhase);  // 1
},true);

事件捕获提供了在事件没有送达目标之前查看它们的机会;事件捕获能用于程序调试,或用于后面介绍的事件取消技术,过滤掉事件从而使目标事件处理程序绝不会被调用;

oDiv.addEventListener("click", function(event){
    console.log("div:" + event.eventPhase);
},false);
document.body.addEventListener("click", function(event){
    console.log("body:" + event.eventPhase);  // 1
    if(event.currentTarget !== event.target)
        event.stopPropagation();
},true);

事件捕获常用于处理鼠标拖放,因为要处理拖放事件的位置不能是这个元素内部的子元素;

示例:


使用捕获

d1
d2
d3
d4

取消事件(默认行为):

在HTML事件处理程序和DOM0级事件处理程序中使用返回false值,用于取消事件的默认行为;例如:阻止超连接导航行为(链接的默认行为就是在被单击时会导航到href指定的URL);

零点网络

在使用Event对象时,可以使用()方法阻止(或者称为取消)特定事件的默认行为;

var link = document.getElementById("myLink");
link.onclick = function(event){
    alert("跳不了");
    event.preventDefault();
}
var myform = document.getElementById("myform");
myform.addEventListener("submit", function(event){
    console.log("正在处理数据...");
    var flag = false;
    try {
        if(!flag)
            throw new Error("数据验证没通过");
    } catch (error) {
        console.log(error.message);
        event.preventDefault();
    }
});

在使用()方法时,只有属性为true时才可以阻止事件默认行为;如:

document.addEventListener("wheel", function(event){
    console.log(event.cancelable);
    if(typeof event.cancelable !== "boolean" || event.cancelable){
        console.log("可以被取消");
        event.preventDefault();
    }else{
        console.log("此事件默认行为不能被取消");
        console.dir(event);
    }
});

示例:验证数据输入,如:


event对象的属性,是DOM3事件中新增的,表示当前取消事件的状态,默认是false,如果调用了()方法,该属性值就为true,如:

document.body.addEventListener("click", function(event){
    console.log(event.defaultPrevented); // false
    event.preventDefault();
    console.log(event.defaultPrevented);  // true
},false);

属性:与()和属性作用相同,其由旧版IE引入的一个非标准历史属性,现被收入规范;默认情况下,它被设置为 true,即允许进行默认操作,将该属性设置为 false 即可阻止默认操作;

    // event.preventDefault();
    event.returnValue = false;  // 与preventDefault()作用相同;
    console.log(event.returnValue);  // false 值相反

取消事件传播:

使用(),用于立即停止事件在DOM层次中的传播,也就是取消进一步的事件捕获或冒泡,如:

var oDiv = document.getElementById("mydiv");
oDiv.addEventListener("click", function(event){
    console.log("wangwei");
    event.stopPropagation();
},false);
document.body.addEventListener("click", function(event){
    console.log("body");  // 当单击oDiv时,不会打印
},false);
// 或
var oDiv = document.getElementById("mydiv");
oDiv.addEventListener("click", function(event){
    console.log("div");  // 当单击oDiv时,不会打印
},true);
document.body.addEventListener("click", function(event){
    console.log("body");
    event.stopPropagation();
},true);

如果同一个对象注册了多个事件处理程序,即使调用了()方法,所有的事件处理程序还会执行,如:

document.body.addEventListener("click", function(event){
    console.log("body");
    event.stopPropagation();
},true);
document.body.addEventListener("click", function(event){
    console.log("body again");
},true);
document.body.addEventListener("click", function(event){
    console.log("body fianl");
},true);
document.body.addEventListener("mouseover", function(event){
    console.log("body mouseover");
},true);

,布尔值,可读写,设置是否阻止冒泡,是()方法的历史别名,设置为 true,就可以阻止事件继续冒泡;

    // event.stopPropagation();
    console.log(event.cancelBubble); // false
    event.cancelBubble = true;
    console.log(event.cancelBubble);  // true

DOM3中对event对象新增了一个tion()方法,其类似于()方法,用于阻止事件传播,同时也会阻止同一个对象上注册的同一事件的其他事件处理程序的调用,如:

document.body.addEventListener("click", function(event){
    console.log("body");
    event.stopImmediatePropagation();
}, true);
document.body.addEventListener("click", function(event){
    console.log("body again");
}, true);
document.body.addEventListener("click", function(event){
    console.log("body final");
}, true);
document.body.addEventListener("mouseover", function(event){
    console.log("body mouseover");
}, true);

如果多个事件处理程序被注册到相同元素的相同事件类型上,当此事件触发时,它们会按照它被添加的顺序被调用,如果在其中一个事件处理程序中执行 tion()方法,那么剩下的事件监听器都不会被调用,如:

document.body.addEventListener("click", function(event){
    console.log("body");
}, true);
document.body.addEventListener("click", function(event){
    console.log("body again");
    event.stopImmediatePropagation();
}, true);
document.body.addEventListener("click", function(event){
    console.log("body final");
}, true);

其他属性:,只读,事件创建时的时间戳,单位为毫秒;

document.addEventListener("click", function(event){
console.log(event.timeStamp);
    var minutes = 1000 * 60;
    console.log(event.timeStamp / minutes);
},false);

例如,可以计算鼠标移动速度,显示每秒移动的像素数量,如:

var previousX, previousY, previousT;
window.addEventListener("mousemove", function(event){
    if(previousX !== undefined && previousY != undefined && previousT !== undefined){
        var deltaX = event.screenX - previousX;
        var deltaY = event.screenY - previousY;
        // deltaD 斜线的长度
        var deltaD = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
        // 时间差
        var deltaT = event.timeStamp - previousT;
        console.log(deltaD / deltaT * 1000);
    }
    previousX = event.screenX;
    previousY = event.screenY;
    previousT = event.timeStamp;
});

,只读的布尔值,DOM3新增,为true,表示事件是由浏览器(例如用户点击)生成的,为false是由脚本创建的;

():为通过.()创建的事件对象初始化;

document.body.addEventListener("click", function(event){
    console.log(event.isTrusted); // true
},false);
oDiv.addEventListener("click", function(event){
    console.log(event.isTrusted); // false
},false);
oDiv.click();
var event = document.createEvent("MouseEvents");
event.initEvent("click",true,true);
document.addEventListener("click", function(e){
    console.log(e.isTrusted);  // false
},false);
document.dispatchEvent(event);

属性一般用来检查事件是否受信任,如果是用户操作的,肯定是值得信任的,但是在IE中,除了使用()方法创建的事件之外,所有事件都是可信任的;如:

function eventHandler(event){
    if("isTrusted" in event){
        if(event.isTrusted)
            console.log("这个:" + event.type + "是值得依赖的");
        else
            console.log("这个:" + event.type + "是不值得依赖的");
    }else{
        console.log("你的浏览器不支持");
    }
}
document.addEventListener("click", eventHandler, false);
oDiv.click();

IE中的事件对象:

在IE中,要访问event对象有几种方式,取决于指定事件处理程序的方法;在使用DOM0级方法时,事件对象是对象的一个属性event,如:

var btn = document.getElementById("btn");
btn.onclick = function(){
    var event = window.event;
    console.log(event);  // MouseEvent
    console.log(event.type);  // click
}

如果使用()添加的,那么就会有一个event对象作为参数被传入到事件处理程序函数中; 即使如此,也可以通过对象来访问event对象;

var btn = document.getElementById("btn");
btn.attachEvent("onclick", function(myevent){
    console.log(myevent);  // 在IE10及以下 MSEventObj
    console.log(myevent.type);  // click
    var e = window.event;
    console.log(e === myevent);  // false,指向不同的对象
    console.log(e);  // MSEventObj
    console.log(e.type);  // click
    console.log(event);
    console.log(event === e);  // false
    console.log(event === myevent);  // false
});

如果通过HTML特性指定的事件处理程序,那么可以通过一个名叫event的变量来访问event对象:

IE中的event对象属性和方法:

IE中的event对象同样也包含与创建它的事件相关的属性和方法;其中很多属性和方法都与DOM的事件对象属性和方法相对应;这些属性和方法也会因为事件类型的不同而不同,以下为共同成员:属性/方法类型读/写说明

IE中的事件处理程序的作用域是根据指定它的方式来确定的,所以不能认为this会始终等于事件目标,因此,最好使用event.,如:

var btn = document.getElementById("btn");
btn.onclick = function(){
    console.log(window.event.srcElement);
    console.log(this);
    console.log(window.event.srcElement === this); // true
};
btn.attachEvent("onclick", function(event){
    console.log(event.srcElement);
    console.log(event.srcElement === this);  // false
    console.log(this === window);  // true
});

属性相当于DOM中的()方法,它们的作用都是取消给定事件的默认行为,其默认为true,只要将该属性值设为false,就可以阻止默认行为,如:

var link = document.getElementById("mylink");
link.onclick = function(){
    window.event.returnValue = false;
}
// 或者
link.attachEvent("onclick", function(event){
    event.returnValue = false;
});

属性与DOM中的()方法作用相同,都是用来停止事件传播的,但由于IE不支持事件捕获,所以只能取消事件冒泡,而() 可以同时取消事件捕获和冒泡;

oDiv.attachEvent("onclick", function(){
    window.event.cancelBubble = true;
    console.log("div");
});
document.body.attachEvent("onclick", function(){
    console.log("body");
});

在.js中添加跨浏览器事件;

    getEvent: function(event){
        return event ? event : window.event;
    },
    getTarget: function(event){
        return event.target || event.srcElement;
    },
    preventDefault: function(event){
        if(event.preventDefault)
            event.preventDefault();
        else
            event.returnValue = false;
    },
    stopPropagation: function(event){
        if(event.stopPropagation)
            event.stopPropagation();
        else
            event.cancelBubble = true;
    }

应用:

var btn = document.getElementById("btn");
EventUtil.addHandler(btn, "click", handler);
function handler(event){
    event = EventUtil.getEvent(event);
    console.log(event.type);
    var target = EventUtil.getTarget(event);
    console.log(target.id);
    EventUtil.preventDefault(event);
    EventUtil.stopPropagation(event);
}
EventUtil.addHandler(document.body, "click", bodyClick);
function bodyClick(){
    console.log("body clicked");
}

提醒:请联系我时一定说明是从浚耀商务生活网上看到的!