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

说事件绑定得先说事件流

事件流

冒泡型事件流:

事件的传播是从最特定的事件目标到最不特定的事件目标。即从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事件传播顺序为:

=》 =》 =》document

在捕获型事件流中click事件传播顺序为:

document =》 =》 =》

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

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

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

事件处理

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

HTML事件处理:

直接在标签内绑定事件,例如:<button οnclick=“something()”
这里直接将js内something函数绑定到button上。
缺点:
1.一个方法需要多次引用,而且不符合 行为、结构、样式 相分离的原则。
2.当js的函数名更改,html标签内的方法也需要更改。

DOM 0级事件处理:

0级事件处理的较HTML事件处理的有点很明显,他完全写在

缺点:每个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("333");
        }
        content.removeEventListener("mouseenter",add,false);
    </script>
</body>
</html>

注意:removeEventListener()

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

下面再讲一些补充吧。

阻止默认事件preventDefault()

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那我就要用到阻止冒泡了。

好了,就到这里吧。本次分享到这里就结束了,作者自身的技术不是很好,如果有哪里误导了大家,请留言提醒我一下。

如果还有疑问请参考【JavaScript 事件参考手册】

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值