深入学习之事件兼容2 以及二级事件
、 //pageX/pageY在IE6~8下不兼容
// e.pageX = e.pageX || (e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));
//e.pageY = e.pageY || (e.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
//target:当前事件源(行为是发生在哪个元素上的,这个元素就是当前的事件源)
//在IE6~8下不兼容
// e=e||window.event
//e.target= e.target|| e.srcElement;
//type:当前事件行为的类型 例如:"click"
//preventDefault:阻止事件的默认行为
//在IE6~8下不兼容
//e.preventDefault ? e.preventDefault() : e.returnValue = false;
//阻止冒泡传播
e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
//事件委托的原理:
//利用了事件默认会进行冒泡传播的机制,我们给最外层的元素绑定一个方法,当里面元素的相关行为触发的时候,最外面的绑定的方法也会执行,我们可以通过事件对象中的事件源判断当前点击的是哪一个元素,从而进行不一样的处理
function move() {
window.clearTimeout(oDiv.timer);
<js code>
oDiv.timer = window.setTimeout(move, 10);
}
/对于一个容器中我们多个元素都要绑定相关的行为,做不同的处理,我们测试后的结果发现:使用事件委托的方式处理,比一个个的单独绑定事件,在执行和处理的速度上提升了一倍(事件委托非常的重要)
//对于一些其他的需求,除了事件委托你是处理不了的
//给最外面的body绑定一个点击事件,当里面的某一个元素的点击行为被触发的时候,在不阻止冒泡传播的情况下,body的click行为都会被触发,我们为其绑定的那个方法也会执行
//e.target是事件源:就是我们当前点击的这个元素
//之前的代码存在一个问题:
//鼠标如果移动端的速度过快,盒子会跟不上鼠标移动端,导致鼠标从盒子上脱离;我们鼠标在盒子外面移动或者抬起和盒子是没有任何关系的了;这样的话我们之前给boxTop绑定的move和up都不能移除了;当鼠标再次进去我们的盒子,哪怕是没有按下,盒子也会跟着鼠标移动...
// ->"鼠标丢失问题"
//JS中,在IE和火狐浏览器下我们使用一个方法,把鼠标和元素强行的用绳子绑定到一起:setCapture
//谷歌下应用 鼠标即使滑动在快你也永远跑不出document,这样的话我们的move/up事件就不给boxTop,给document绑定
//DOM2级事件绑定 ->定义在当前元素原型链上的EventTarget这个类的prototype上 addEventListener/removeEventListener
//1、DOM2相对于DOM0增加了哪些的优势?
//1)DOM0只能给一个元素的同一个行为绑定一次方法,第二次绑定的会把第一次的给覆盖掉;DOM2可以给一个元素的同一个行为绑定多个不同的方法;-->事件池/事件队列
//2)DOM0在事件的默认传播机制中我们能够操作的只有冒泡阶段(但是捕获阶段也存在,我们不能操作而已)(事件委托、阻止冒泡传播...)
//DOM2是既可以操作冒泡阶段,也可以操作捕获阶段-->addEventListener最后一个参数是false,代表在冒泡阶段我们进行操控(最常用的);最后一个参数是true,代表我们是在捕获阶段操控;
//$(document).ready():只要页面中的HTML结构将加载完成就会执行对应的操作(一个页面可以使用多次)
//document.addEventListener("DOMContentLoaded",function(){},false);
//DOM0级事件绑定 ->定义在当前元素对象的私有的属性上的 oDiv.οnclick=function(e){}
//DOM2级事件绑定 ->定义在当前元素原型链上的EventTarget这个类的prototype上 addEventListener/removeEventListener
//1、DOM2相对于DOM0增加了哪些的优势?
//1)DOM0只能给一个元素的同一个行为绑定一次方法,第二次绑定的会把第一次的给覆盖掉;DOM2可以给一个元素的同一个行为绑定多个不同的方法;-->事件池/事件队列
//2)DOM0在事件的默认传播机制中我们能够操作的只有冒泡阶段(但是捕获阶段也存在,我们不能操作而已)(事件委托、阻止冒泡传播...)
//DOM2是既可以操作冒泡阶段,也可以操作捕获阶段-->addEventListener最后一个参数是false,代表在冒泡阶段我们进行操控(最常用的);最后一个参数是true,代表我们是在捕获阶段操控;
//3)DOM0中的事件行为DOM2中都有,DOM2中还提供了一些我们DOM0中没有的事件行为:DOMContentLoaded ->当页面上的HTML结构加载完成就会执行对应的操作
//window.onload:只有当页面中的HTML结构、图片、文字等所有资源都加载完成才会执行对应的操作 (在一个页面中只能使用一次,使用多次后面会把前面的覆盖掉->因为它是DOM0级事件绑定,如果改为DOM2事件绑定也是可以使用多次的) window.addEventListener("load",function(){},false);
//$(document).ready():只要页面中的HTML结构将加载完成就会执行对应的操作(一个页面可以使用多次)
//document.addEventListener("DOMContentLoaded",function(){},false);
//3)DOM0中的事件行为DOM2中都有,DOM2中还提供了一些我们DOM0中没有的事件行为:DOMContentLoaded ->当页面上的HTML结构加载完成就会执行对应的操作
//window.onload:只有当页面中的HTML结构、图片、文字等所有资源都加载完成才会执行对应的操作 (在一个页面中只能使用一次,使用多次后面会把前面的覆盖掉->因为它是DOM0级事件绑定,如果改为DOM2事件绑定也是可以使用多次的) window.addEventListener("load",function(){},false);
//$(document).ready():只要页面中的HTML结构将加载完成就会执行对应的操作(一个页面可以使用多次)
//document.addEventListener("DOMContentLoaded",function(){},false);
//事件的传播分为两个阶段:
//捕获阶段、冒泡阶段 ->捕获在前,冒泡在后
//捕获阶段:从外向内执行
//冒泡阶段:从内向外执行
oDiv.addEventListener("click", function (e) {
console.log("ok");
}, false);
function fn12() {
console.log(12);
console.log(this);
}
oDiv.attachEvent("onclick", fn1);
function fn12() {
console.log(12);
console.log(this);
}
oDiv.attachEvent("onclick", fn1);
//DOM2兼容问题:
//在标准的浏览器中采用addEventListener/removeEventListener,在IE6~8中不支持这个,需要使用attachEvent/detachEvent;
//oDiv.addEventListener("click",fn1,false);//三个参数,行为不需加on
//oDiv.attachEvent("onclick",fn1);//两个参数,行为需要加on,第三个参数没有说明我们的这个只能在冒泡阶段发生
//1)顺序问题->标准浏览器中绑定多个方法,方法的执行顺序和绑定的顺序保持一致,而在IE6~8中顺序是混乱的
//2)重复问题->标准浏览器中是对于给一个元素的同一个行为绑定多次一样的方法,浏览器会自己把重复的过滤掉,而在IE6~8中是不进行过滤的,绑定重复了也会执行多次
//3)this问题->标准浏览器中绑定的方法中的this是当前的元素,而IE6~8中是window
/移除:在DOM2移除的时候,我们需要保证三个参数高度的一致才能移除
// function fn(e) {
// console.log("ok");
// oDiv.removeEventListener("click", fn, false);
// }
// oDiv.addEventListener("click", fn, false);