面试题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]事件(高程版)(一)事件类型http://zccst.iteye.com/blog/2081868

-------------------------基础知识分界线-----------------

client有关的所有东西,可参考:

http://zccst.iteye.com/admin/categories/204843

事件代理

优点:

1,document对象很快就可以访问,可以在任何时间点为它添加事件处理程序,无需等待DOMContentLoaded或load事件。

2,用时更少,因为所需DOM引用更少

3,占用内存空间更少,能提升整体性能

适合:click,mousedown,mouseup,keydown,keyup和keypress。

但不适合mouseover和mouseout。

【浏览器差异】

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){
	}
};

多次绑定

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才会执行多次吧。

【标准事件】冒泡的过程

给父元素添加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,事件的三个阶段eventPhase1捕获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)没有影响,因为发生在捕获阶段。

如果您觉得本文的内容对您的学习有所帮助,您可以微信:

相关推荐