当我们在浏览器点击一下的时候,为什么就可以执行指定的代码,用户点击这下,浏览器背后发生了怎样动人的故事,接下来就来一起寻找浏览器事件背后的故事
我们如果想用户点击某个节点事执行某段代码,我们可以这样做:
1. <div οnclick=hello()></div> //直接在html中调用方法,这个是浏览器暴露的接口之一,HTML事件处理程序(也可以叫事件侦听器),就是侦听这个dom节点的click动作,hello方法就是这个侦听器的回调函数,这是hello的执行上下文是window
2. dom0级事件处理
document.getElementsByTagName('div')[0].onclick(function(){
console.log(this);//this指向当前元素
});
dom0事件处理程序中的回调函数是被认为是元素的方法执行的,所以this的指向是当前元素而不是window,也就是说onclick在这里相当于是
当前元素的属性,既然是属性,那自然就可以被覆盖了,所以如果多个dom0相同的时间处理程序,最后一个会覆盖前面一个。既然是属性,那就可以这样注销了
document.getElementsByTagName('div')[0].οnclick=null;
3.dom2级事件处理程序
三个参数,事件名,回调函数,在捕获阶段执行还是冒泡阶段执行,t默认false-》冒泡阶段执行
document.getElementsByTagName('div')[0].addEventListener("click",function(){
console.log(this);//这个时候this指向的是dom节点,可以得知回调方法的执行上下文依然还是dom节点,但是却不是当成dom节点的方法使用
},false);
这种事件处理程序可以添加多个相同的事件在同一个元素上而不会被覆盖,所以说明回调函数不是dom节点的属性或者方法,dom节点只是函数的执行上下文。
注销函数,removeEventListener(),dom2处理规范要求,addEventListener和removeEventListener传入的事件处理函数必须相同,也就是函数的引用相同
所以上面这种直接用匿名函数作为事件处理程序的方法定义的程序是没法注销的,
var test=function();
document.getElementsByTagName('div')[0].addEventListener("click",test);//添加test方法为事件处理程序
document.getElementsByTagName('div')[0].removeEventListener("click",test);//移除事件处理程序
但是曾经让前端程序员蛋疼但是却有给了程序员收入的ie依旧保持自己的风格,使用另外两个接口来事件addEventListener和removeEventLisner
attachEvent("onclick",test);//添加事件处理程序
detachEvent("onclick",test);//移除事件处理程序
帅的人可能已经发现了,怎么少了一个参数,没错,ie的时间处理程序都是在冒泡阶段触发的,所以也就没有第三个参数了
讲了那么多,还没有讲那背后动人的故事
简单的讲就是浏览器提供了一系列接口给js调用(不同浏览器厂商接口可能会有不同,例如ie),这也是为什么js称之为前端语言,因为浏览器统一都给它提供了接口和运行环境,为什么nodejs是后台语言,因为node实现了系统提供的接口,可以直接和系统交互。因为浏览器厂商众多难以统一,这也是js称霸客户端的原因之一,而系统就比较简单多了,所以后端语言多元化。
扯淡扯远了,简单来讲就是浏览器提供了接口和用户动作进行交互,上面讲到的捕获阶段和冒泡阶段又是什么呢?
简单粗暴的讲解:
捕获阶段就是从document作为根节点往下寻找,知道找到对应元素:document--->html---->body-------->dom节点
冒泡阶段就是从dom节点作为根节点开始冒泡,一直到window最高级别:dom节点------>body---------->html--------->window
jq案例,如果要给一个用js添加的dom节点添加事件监听,两种方法:
//这种方法就相当于用dom0事件驱动实现,所以如果div是用js添加的元素,会导致事件无法驱动,因为这是冒泡处理
$("div").click(function(){
})
//这中方法就相当于用dom2实现的,这个时候如果div是未来元素,那也可以驱动,因为它是从document往下寻找,事件捕获的方式,所以只要document不是未来元素就可以
$("document").on("click","div",function(){
})
本人作为初级前端,技术有限,欢迎各位大婶指点,如果你和我一样也是初学者,也欢迎进行技术交流