JavaScript事件基础、事件原理、事件区别与兼容

it2023-10-03  70

JavaScript事件基础、事件原理、事件区别与兼容

事件基础 //侦听事件(侦听的类型,事件回调函数) 侦听类型必须字符串 document.addEventListener(“abc”,abcHandler); //创建事件 var evt=new Event(“abc”); //把事件向document抛发 document.dispatchEvent(evt); //抛发的对象必须和侦听对象是同一个对象 //所有继承了EventTarget的对象都可以进行事件侦听和抛发

function abcHandler(e){ // 当侦听收到事件后会执行回调函数,函数中有且仅有一个参数 // 这个参数就是创建的事件对象 console.log(e); }

//先侦听后抛发

解耦

var obj={ a:1, init:function(){ document.addEventListener("obj1Event",this.b); }, b:function(e){ console.log(e.c); var evt=new Event("objEvent"); evt.a=1; document.dispatchEvent(evt); } } var obj1={ c:2, init:function(){ document.addEventListener("objEvent",this.d); var evt=new Event("obj1Event"); evt.c=2; document.dispatchEvent(evt); }, d:function(e){ console.log(e.a); } } obj.init(); obj1.init();

事件原理 事件侦听对象.addEventListener(事件类型,事件触发回调函数,是否捕获时触发事件=false) true为捕获阶段触发 事件侦听对象.addEventListener(事件类型,事件触发回调函数,{once:true})//once是true表示该事件仅执行一次,就被销毁

e.type事件侦听的类型 e.bubbles事件是否冒泡 e.stopPropagation();阻止冒泡

默认状态下事件触发是冒泡阶段

捕获 目标 冒泡 外 达到目标 内 | | 内 外

默认创建的事件不会自动冒泡 创建事件的第一个参数是事件的type 第二个参数是事件初始化对象,对象中属性bublles是否冒泡,true冒泡,默认是false var evt=new Event(“abc”,{bubbles:true}); div1.dispatchEvent(evt);

事件委托:把子元素的事件委托给父元素侦听,事件委托 事件委托案例:列表点击

<ul> <li>北京 <ul class="ul1"> <li>昌平 <ul class="ul1"> <li>老牛湾</li> <li>沙河</li> <li>回龙观</li> <li>霍营</li> </ul> </li> <li>海淀</li> <li>朝阳</li> <li>东城</li> <li>西城</li> </ul> </li> <li>陕西 <ul class="ul1"> <li>西安</li> <li>咸阳 <ul class="ul1"> <li>淳化</li> <li>三原</li> <li>旬邑</li> <li>泾阳</li> </ul> </li> <li>宝鸡</li> <li>延安</li> </ul> </li> <li>河北</li> <li>河南</li> <li>山西</li> </ul> var ul=document.querySelector("ul"); ul.addEventListener("click",clickHandler); // 把子元素的事件委托给父元素侦听,事件委托 function clickHandler(e){ // console.log(this); this就是事件侦听的对象 // console.log(e.target,e.srcElement);//点击事件的目标元素,这两个是相同的 // console.log(e.currentTarget===this)//e.currentTarget就是this也就是事件侦听对象 // 这里不需要取消冒泡 if(e.target.constructor!==HTMLLIElement)return; // if(e.target.nodeName!=="LI") return; e.target.bool=!e.target.bool; if(e.target.firstElementChild && e.target.firstElementChild.constructor===HTMLUListElement){ if(e.target.bool){ e.target.firstElementChild.className="ul1 ul2"; }else{ e.target.firstElementChild.className="ul1"; } }

事件的区别和兼容 onclick事件 1、使用onclick时具有覆盖性 2、行内的onclick如果没有后续的onclick则会执行,否则会被覆盖 3、行内的onclick(需要在函数名后加括号)执行的函数不是回调函数,而是直接使用函数执行 4、如果是IE6以下,没有e这个参数,所以无法获取这个事件对象5、行内事件中,因为不传递e这个参数,因此也无法获取事件对象6、当无法获取e对象时可以通过e=e||window.event获取,(事件兼容方式)用于onclick写法

on事件和addEvevtListener区别: 1、on事件支持任何浏览器兼容,addEventListener只支持IE8及以上浏览器 2、on事件,实际上是针对DOM对象有一个固定的属性。例如onclick,一般会赋值给这个属性一个匿名函数,当再次赋值时会覆盖上次的函数。addEventListener事件会使用回调函数添加,可以设置多个事件对象函数,不会覆盖 3、on事件多用匿名函数,开发时很容易产生回调地狱,但是使用addEventListener多使用命名函数有效控制回调地狱的产生 4、on事件不支持捕获阶段事件,addEventListener支持捕获阶段事件,还支持once冒泡(IE8以上阻止冒泡e.stopPropagation;e.concelBubble取消冒泡兼容写法) 5、删除事件方式不同:addEventListener使用removeEventListener,on事件用div.οnclick=null删除事件 6、因为on事件都是系统自动为DOM对象添加的事件类型,因此固定,addEventListener支持自定义事件,可以自己抛发事件接收

回调地狱案例: 实现按顺序点击才能打印: on产生回调地狱

var div0=document.querySelector(".div0"); var div1=document.querySelector(".div1"); var div2=document.querySelector(".div2"); var div3=document.querySelector(".div3"); var div4=document.querySelector(".div4"); div1.onclick=function(){ div2.onclick=function(){ div3.onclick=function(){ div4.onclick=function(){ console.log("aaa"); } } } }

addEventListener方法控制:

div1.addEventListener("click",clickHandler); function clickHandler(e){ switch(this){ case div1: div2.addEventListener("click",clickHandler); break; case div2: div3.addEventListener("click",clickHandler); break; case div3: div4.addEventListener("click",clickHandler); break; case div4: console.log("aaaa"); } }

attachEvent和addEvevtListener: element.attachEvent(‘on开头的事件名’,事件函数名)添加事件,只支持IE11以下浏览器,其他浏览器不支持,不支持捕获冒泡 element.detachEvent(‘on开头的事件名’,事件函数名)移除事件,不支持事件抛发

attachEvent和addEvevtListener兼容写法

function addEvent(elem, type, calLback, bool){ if(bool==undefined) bool=false; if(elem. addEventListener){ elem. addEventListener(type, callback, bool); }elset elem. attachEvent("on"+type, calLback); }
最新回复(0)