前言
通过如下两个实例来理解DOM事件
- 实例1--点击别处关闭浮层
-
onclick与addEventListener的区别
- 实例2--点击后颜色一层一个层出现的漂亮的彩虹圈
1 实例1--点击别处关闭浮层
- 代码效果演示:原生JS 、 jQuery
- HTML代码
<div id="wrapper" class="wrapper"> <button id="clickMe">点我</button> <div id="popover" class="popover"> <input type="checkbox">浮层 </div> </div>
- CSS代码
.wrapper{ display:inline-block; position: relative; } .popover{ display: none; border: 1px orange solid; top: 0px; /*宽度是上级元素的100%*/ left: 130%; padding: 8px; border-radius: 4px; position: absolute; background: white; /*规定段落中的文本不进行换行*/ white-space: nowrap; } /*画浮层左边的小指向箭头*/ .popover::before{ position: absolute; right: 100%; top: 4px; border: 10px solid transparent; border-right-color: orange; content: ''; } .popover::after{ position: absolute; right: 100%; top: 4px; border: 10px solid transparent; border-right-color: white; content: ''; margin-right: -1px; }
- JS代码-原生js
/*点击按钮触发浮层*/ clickMe.addEventListener('click', function(){ popover.style.display = 'block' }) /*阻止默认事件*/ wrapper.addEventListener('click', function(e){ e.stopPropagation() }) /*点击任意处关闭浮层*/ document.addEventListener('click', function(){ popover.style.display = 'none' })
- JS代码-jQuery
$(clickMe).on('click',function(){ $(popover).show() /*如果不加定时器会同步执行show()和hide(),即看起来什么都没有发生*/ setTimeout(function(){ $(document).one('click', function() { $(popover).hide() }) },0) })
2 onclick与addEventListener的区别
- 实例1使用的原生JS,为什么使用addEventListener(),而不使用onclick() --onclick()只能添加一个事件,多个事件时只会输出最后一个,而实例1中存在多个事件,不能用onclick()
- onclick与addEventListener实际上可分为:Inline events与Event Listeners
- Event Listeners (“addEventListener” and “IE's attachEvent”)
- 两者相同点:都是时间监听器。
- 两者不同点:
- addEventListener:很多浏览器支持addEventListener(IE9、IE10、IE11、chrome、firefox、opera、safari支持),使用方式如下:
//addEventListener接受三个参数,最后一个参数默认是false。(false表示事件处理将在冒泡阶段执行,true表示事件处理将在捕获阶段执行) //addEventListener(type,listener,options) var target = document.getElementById("test"); target.addEventListener('click',function test(){ console.log("Hi"); },false)
- addEventListener:很多浏览器支持addEventListener(IE9、IE10、IE11、chrome、firefox、opera、safari支持),使用方式如下:
-
-
- attachEvent:IE中提供的类似addEventListener的事件监听器,使用方式如下:
//qqq var target = document.getElementById("test"); target.attachEvent('onclick',test); function test(){ console.log("Hi"); }
- attachEvent:IE中提供的类似addEventListener的事件监听器,使用方式如下:
-
-
-
- 理论上,Event Listeners (addEventListener and IE's attachEvent)可以无限增加事件监听给某个一元素。实际应用的约束就是客户端内存的限制,这一点因每个浏览器而异
var target = document.getElementById("test"); target.addEventListener('click',function test(){ console.log("Hi"); },false) target.addEventListener('click',function test(){ console.log("Hello"); },false) //Hi //Hello
- 理论上,Event Listeners (addEventListener and IE's attachEvent)可以无限增加事件监听给某个一元素。实际应用的约束就是客户端内存的限制,这一点因每个浏览器而异
-
- Inline events (“HTML onclick="" property” and “element.onclick”)
-
- 使用方式:
-
-
- onclick=""
<a id="test" href="#" onclick="function()">clickMe</a>
- onclick=""
-
-
-
- element.onclick
<a id="test" href="#">clickMe</a> var target = document.getElementById('test') target.onclick = function(){ console.log('Hi'); }
- element.onclick
-
-
-
- Inline events只能添加一个事件,如果同时有多个,只会输出最后一个的结果
var target = document.getElementById('tttt') target.onclick = function(){ console.log('Hi'); } target.onclick = function(){ console.log('Hello'); }
//Hello
- Inline events只能添加一个事件,如果同时有多个,只会输出最后一个的结果
-
- Inline events与Event Listeners的区别:Event Listeners可以添加无数个(理论上)事件,Inline events只能添加1个事件,且下面的会覆盖上面的。
3 实例2--点击后颜色一层一个层出现的漂亮的彩虹圈
- 代码效果:彩虹圈
- HTML代码
<div class="red"> <div class="blue"> <div class="green"> <div class="yellow"> <div class="orange"> <div class="purple"> </div> </div> </div> </div> </div> </div>
- CSS代码
*{margin:0;padding:0;box-sizing:border-box;} //设置背景颜色 .red.active { background: red; } .blue.active { background: blue; } .green.active { background: green; } .yellow.active { background: yellow; } .orange.active { background: orange; } .purple.active { background: purple; } //设置一层一层圆圈以及动画过渡事件 div { border: 1px solid black; padding: 10px; transition: all 0.5s; display: flex; flex:1; border-radius: 50%; background: white; } //设置最外圈的长宽 .red{ 100vw; height: 100vw; }
- JS代码
let divs = $('div').get() let n = 0 for (let i = 0; i < divs.length; i++) { //addEventListener()最后一个参数为true //即执行捕获阶段--从外层到里层,即从爷爷到儿子 divs[i].addEventListener('click', function() { setTimeout(function() { divs[i].classList.add('active') }, n * 500) n += 1 }, true) } for (let i = 0; i < divs.length; i++) { //addEventListener()最后一个参数为false //即执行冒泡阶段--从里层到外层,即从儿子到爷爷 divs[i].addEventListener('click', function() { setTimeout(function() { divs[i].classList.remove('active') }, n * 500) n += 1 }, false) } //⚠️有一个特殊情况:即如果都是自己身上同时捕获(true)和冒泡(false),此时执行顺序和捕获(true)和冒泡(false)无关,谁在前面就先执行哪个