js事件监听:addEventListener() 与 移除事件:removeEventListener()

    xiaoxiao2022-07-05  180

    说事件绑定得先说事件流

    事件流 冒泡型事件流:事件的传播是从最特定的事件目标到最不特定的事件目标。即从DOM树的叶子到根。【推荐】

    捕获型事件流:事件的传播是从最不特定的事件目标到最特定的事件目标。即从DOM树的根到叶子。

    DOM标准采用捕获+冒泡。两种事件流都会触发DOM的所有对象,从document对象开始,也在document对象结束。

    来个例子看一下吧!

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <div id="myDiv">Click me!</div> </body> </html>

    当点击了div时事件流走向,

    在冒泡型事件流中click事件传播顺序为:<div> =》<body> =》<html> =》document

    在捕获型事件流中click事件传播顺序为:document =》<html> =》<body> =》<div>

    这里之所以说冒泡,并不是视图上的冒泡,而是结构上的冒泡。这里要弄清楚了,就算在视图上div是独立的,但他的在html结构

    结构上依旧是被body所包裹。而冒泡是由内而外向上冒泡。

    懂了冒泡之后,捕获就好理解了,就是反向的事件流。由外而内。

      事件处理 以上明白了事件流,现在说说怎样处理事件。

        HTML事件处理:

     直接在标签内绑定事件,例如:<button οnclick="something()"></button>

    这里直接将js内something函数绑定到button上。

    缺点:

    1.一个方法需要多次引用,而且不符合 行为、结构、样式 相分离的原则。

    2.当js的函数名更改,html标签内的方法也需要更改。

         DOM 0级事件处理:

    在<script>中获取dom元素绑定事件,例如:btn.onclick = function () {}

    0级事件处理的较HTML事件处理的有点很明显,他完全写在<script>内,符合 行为、结构、样式 相分离的原则。还可以选出DOM元素集合通过for循环统一操作。

    缺点:每个DOM元素只能绑定一个同类事件。例如绑定onclick,当你想在绑定onclick会发现他被覆盖了。

         DOM 2级事件处理(事件监听)

    addEventListener("事件名" , "事件处理函数" , "布尔值");

    false 事件冒泡           true   事件捕获    

    优点相比前两个就多了。可以选择是事件流。可绑定多个同类事件。事件名可以组成字符串。

     

    到今天的主题了~~

    addEventListener() 和 removeEventListener()

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>addEventListener</title> <script type="text/javascript" src="js/jquery-3.0.0.js"></script> <style type="text/css"> #content{ width: 100px; height: 100px; background: #f9f; } </style> </head> <body> <div id="content"></div> <script type="text/javascript"> //addEventListener 用于向指定元素添加事件句柄 //可以向一个元素添加多次点击事件,后一个点击事件不会覆盖前一个点击事件 var content = document.getElementById("content"); content.addEventListener("click",function(){ console.log("11"); },false) content.addEventListener("click",function(){ console.log("22"); },false) content.addEventListener("mouseenter",add,false); function add(){ console.log("成哥没我帅"); } //由于成哥并不这么认为,一再用自身的权势让我更改这个事实,所以下面我需要再移出这个事件 content.removeEventListener("mouseenter",add,false); </script> </body> </html>

    注意:removeEventListener() 不能移除匿名函数,像上面add()这种是可以的。removeEventListener需要知道你需要移出的是哪个事件处理函数。匿名函数丢弃了自身函数名,所以移出不了。

    document.body.addEventListener('touchmove', function (event) { event.preventDefault(); },false);

    阻止事件冒泡stopPropagation()

    解释:只点击了button,但是包含button的div也执行了,这属于事件冒泡,事件逐级向上传递,传给了div,有时并不需要事件冒泡,可以通过stopPropagation()  

    <div id="div"> <button id="btn">按钮</button> </div> <script> document.getElementById("btn").addEventListener("click",showType); document.getElementById("div").addEventListener("click",showDiv); function showType(event){ alert(event.type); event.stopPropagation(); } function showDiv(){ alert("div"); } </script>

    事件代理

    这里归类可能没归好,也看看吧

    传统的事件处理中,需要为每个元素添加事件处理器。js事件代理则是一种简单有效的技巧,通过它可以把事件处理器添加到一个父级元素上,从而避免把事件处理器添加到多个子级元素上。

    事件代理的原理用到的就是事件冒泡和目标元素,把事件处理器添加到父元素,等待子元素事件冒泡,并且父元素能够通过target(IE为srcElement)判断是哪个子元素,从而做相应处理

     传统事件处理,为每个元素添加事件处理器,代码如下:  

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> </head> <body> <ul id="color-list"> <li>red</li> <li>orange</li> <li>yellow</li> <li>green</li> <li>blue</li> <li>indigo</li> <li>purple</li> </ul> <script> (function(){ var colorList=document.getElementById("color-list"); var colors=colorList.getElementsByTagName("li"); for(var i=0;i<colors.length;i++) { colors[i].addEventListener('click',showColor,false); }; function showColor(e) { e=e||window.event; var targetElement=e.target||e.srcElement; alert(targetElement.innerHTML); } })(); </script> </body> </html>

    事件代理的处理方式,代码如下:

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> </head> <body> <ul id="color-list"> <li>red</li> <li>orange</li> <li>yellow</li> <li>green</li> <li>blue</li> <li>indigo</li> <li>purple</li> </ul> <script> (function(){ var colorList=document.getElementById("color-list"); colorList.addEventListener('click',showColor,false); function showColor (e) { e=e||window.event; var targetElement=e.target||e.srcElement; if(targetElement.nodeName.toLowerCase()==="li"){ alert(targetElement.innerHTML); } } })(); </script> </body> </html>

    事件代理的好处

     总结一下事件代理的好处:

            将多个事件处理器减少到一个,因为事件处理器要驻留内存,这样就提高了性能。想象如果有一个100行的表格,对比传统的为每个单元格绑定事件处理器的方式和事件代理(即table上添加一个事件处理器),不难得出结论,事件代理确实避免了一些潜在的风险,提高了性能。         DOM更新无需重新绑定事件处理器,因为事件代理对不同子元素可采用不同处理方法。如果新增其他子元素(a,span,div等),直接修改事件代理的事件处理函数即可,不需要重新绑定处理器,不需要再次循环遍历。  而代理事件需要注意的是事件冒泡, 例如:Li里有span,这时我只想操作Li那我就要用到阻止冒泡了。

    转载地址:https://blog.csdn.net/weixin_40122996/article/details/82533223

    最新回复(0)