面试题201412——client 事件

作者:zccst


如何在ie下模拟DOMContentLoad 事件
(看过的, 又忘了, 看来没掌握好) 不知道................... 应该用 创建一个指向空的 src=http://void(0); defer, ie支持这个用defer, 浏览器再DOM加载完才触发, 所以在 script 的 readstate == "complete" 的时候说明DOM已经加载完成了
另一种方法看了一下是用定时器, 当 try{ (document.documentElemnt || document.body).doscroll("left") } 也说明加载完了

参考:[Event]事件(高程版)(一)事件类型[url]http://zccst.iteye.com/blog/2081868[/url]


[b][size=large]-------------------------基础知识分界线-----------------[/size][/b]

client有关的所有东西,可参考:
[url]http://zccst.iteye.com/admin/categories/204843[/url]


[b]事件代理[/b]
优点:
1,document对象很快就可以访问,可以在任何时间点为它添加事件处理程序,无需等待DOMContentLoaded或load事件。
2,用时更少,因为所需DOM引用更少
3,占用内存空间更少,能提升整体性能

适合:click, mousedown, mouseup, keydown, keyup和keypress。
但不适合mouseover和mouseout。


[b]【浏览器差异】[/b]
target -> srcElement
preventDefault() cancelable -> returnValue 布尔,默认false
stopPropagation() bubbles -> cancelBubble 布尔,默认true


blur, focus不冒泡(但focusin, focusout冒泡)
mouseenter, mouseleave不冒泡


IE中attachEvent()与DOM0级方法主要区别是作用域不同,
DOM0,作用域是所属元素
attachEvent(),作用域是全局作用域window

btn1.attachEvent("onclick",function(){
alert(this === window);//true
});



兼容写法

var EventUtil = {
addEvent: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;
}
}
addHandler:function(element,type,handler){
//...
},
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;
}
},
removeHandler::function(element,type,handler){
}
};



[b]多次绑定[/b]
1,对于IE浏览器

btn1.attachEvent("onclick",function(){
alert("clicked");
});
btn1.attachEvent("onclick",function(){
alert("hello");
});

在IE9下,按顺序弹出clicked, hello,但是在IE8顺序是相反的先hello,再clicked。

2,对于标准浏览器
addEventListener都在(,,false)情况:

btn1.addEventListener("click",function(e){
alert(this.id);
},false);
btn1.addEventListener("click",function(e){
alert('hello');
},false);


addEventListener一个是(,,false),另一个是(,,true)情况:

btn1.addEventListener("click",function(e){
alert(this.id);
},false);
btn1.addEventListener("click",function(e){
alert('hello');
},true);

//运行效果,跟false和true没关系。原因是时间绑定他们自己身上,无法体现捕获和冒泡的过程。如果在body上添加addEventListener,差别就体现出来了。


//如果换成document.body,则先hello,然后空白
document.body.addEventListener("click",function(e){
alert(this.id);
},false);
document.body.addEventListener("click",function(e){
alert('hello');
},true);



涉及到知识点:

事件冒泡 我们给一个dom同时绑定两个点击事件,一个用捕获,一个用冒泡,你来说下会执行几次事件,然后会先执行冒泡还是捕获!!!

addEventListener一个demo的oncick进行多次绑定,只会执行一次,貌似犀牛书讲得很清楚,而attachEvent才会执行多次吧。


[b]【标准事件】冒泡的过程[/b]
给父元素添加onclick事件,给父元素添加addEventListener(,,true),给子元素添加onclick事件

btn1.onclick = function(e){
alert('2'+e.eventPhase);
//e.stopPropagation();//如果添加该行,则不再冒泡到父元素,父元素onclick不再被触发
}
document.body.addEventListener("click",function(e){
alert('1'+e.eventPhase);
console.log(e.target === e.currentTarget, e.currentTarget === this);//false, true
},true);
document.body.onclick = function(e){alert('3'+e.eventPhase);}

//对于addEventListener(,,false)与onclick,按绑定顺序触发


点击btn1时,父元素先在捕获阶段捕获,然后目标元素触发,再次冒泡到父元素(父元素onclick被触发)

涉及到知识点:
1,事件的三个阶段 eventPhase 1捕获 2目标 3冒泡
addEventListener(,,true)与addEventListener(,,false)区别?捕获阶段,冒泡阶段
attachEvent只在冒泡阶段

2,addEventListener时,this,target与currentTarget区别?
如果是当前对象addEventListener(),则三者一样
如果是当前对象的父元素addEventListener(),则this === currentTarget,target与他们不同。

3,同时绑定onclick与addEventListener(,,false),执行顺序是什么?
执行顺序与书写先后顺序有关
测试

btn1.onclick = function(e){
console.log("onclick");
}
btn1.addEventListener("click",function(e){
console.log("addEventListener");
},false);


批注:onclick虽然eventPhase等于2,但是仍发生在冒泡阶段(摘自《高级程序设计》)。

4,e.stopPropagation()是阻止冒泡
如果先onclick,再addEventListener(,,false),并且在onclick总阻止了冒泡
则,addEventListener(,,false)不再被触发
且,事件不再冒泡到父元素,父元素onclick不再被触发
批注:对addEventListener(,,true)没有影响,因为发生在捕获阶段。


如果您觉得本文的内容对您的学习有所帮助,您可以微信:
[img]http://dl2.iteye.com/upload/attachment/0109/0668/fb266dfa-95ca-3d09-b41e-5f04a19ba9a1.png[/img]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值