html代码
<html>
<head>
<style>
div {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.055);
}
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<div id="out">
<div id="mid">
<div id="inz">
</div>
</div>
</div>
<script>
//…………
</script>
</body>
</html>
一、事件发生顺序
事件发生顺序图(图片来源:https://www.cnblogs.com/Chen-XiaoJun/p/6210987.html)
其中最里层的冒泡和捕获(即上图5和6)在同一时间节点,前后顺序根据代码顺序而定。
<script>
var out = document.getElementById("out")
var mid = document.querySelector("#mid")
var inz = document.querySelector("#inz")
out.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
mid.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
inz.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
out.addEventListener('click', function () {
console.log('捕获:' + this.id)
}, true)
mid.addEventListener('click', function () {
console.log('捕获:' + this.id)
}, true)
inz.addEventListener('click', function () {
console.log('捕获:' + this.id)
}, true)
</script>
<script>
var out = document.getElementById("out")
var mid = document.querySelector("#mid")
var inz = document.querySelector("#inz")
out.addEventListener('click', function () {
console.log('捕获:' + this.id)
}, true)
mid.addEventListener('click', function () {
console.log('捕获:' + this.id)
}, true)
inz.addEventListener('click', function () {
console.log('捕获:' + this.id)
}, true)
out.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
mid.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
inz.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
</script>
事件冒泡、事件捕获和事件委托详细内容可参考该网页:https://www.cnblogs.com/Chen-XiaoJun/p/6210987.html
二、jquery绑定事件
jquery常用绑定事件方法有.on()
.bind()
.one()
.one()
使用one绑定的事件只会触发一次。
.bind()
截至jQuery 3.0,.bind()已被弃用。它被.on()自jQuery 1.7以来将事件处理程序附加到文档的方法所取代,因此不鼓励使用它。
.on()
可以通过第二个参数绑定子控件实现事件委托,如
$("#mid").on('click',"#inz",function () {
console.log("jquery on:" + this.id)
})
on()
.bind()
.one()
都是可以通过事件名称绑定事件。
事件名包括click
绑定单击、dblclick
绑定双击、mousemove
绑定鼠标移动等。
jquery还有.click(f)
、.dblclick(f)
、.mousemove(f)
等方法,相当于.on('click',f)
、.on('dblclick',f)
、.on('mousemove',f)
的简写
jQuery 事件方法:http://www.runoob.com/jquery/jquery-ref-events.html
jquery的on()
bind()
click()
one()
等方法绑定的事件,都是在事件冒泡阶段触发。
<script>
var out = document.getElementById("out")
var mid = document.querySelector("#mid")
var inz = document.querySelector("#inz")
$("#mid").on('click',function(){
console.log('on:' + this.id)
})
$("#mid").bind('click',function(){
console.log('bind:' + this.id)
})
$("#mid").one('click',function(){
console.log('one:' + this.id)
})
$("#mid").click(function(){
console.log('click:' + this.id)
})
mid.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
inz.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
</script>
三、jquery事件委托
用on()的参数绑定选择器虽然可以给子控件绑定事件,但是事件还是在冒泡到的父控件时才执行(即将绑定到子控件的事件委托给父控件执行);同时,该事件先于该父控件用jquery绑定的其他事件
1.当inz的冒泡事件阻止事件传输后,通过事件委托绑定到inz上的事件未触发。这是因为用$("#mid").on(‘click’,’#inz’,f)虽然把事件绑定到了inz上,但是事件的执行却被委托给了父控件mid
<script>
var out = document.getElementById("out")
var mid = document.querySelector("#mid")
var inz = document.querySelector("#inz")
$("#mid").on('click',function(){
console.log('on:' + this.id)
})
$("#mid").on('click','#inz',function(){
console.log('on:' + this.id)
})
mid.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
inz.addEventListener('click', function (e) {
console.log('冒泡:' + this.id)
e.stopPropagation()
}, false)
</script>
2.委托事件先于自身绑定事件(通过jquery绑定的)。
<script>
var out = document.getElementById("out")
var mid = document.querySelector("#mid")
var inz = document.querySelector("#inz")
$("#mid").on('click',function(){
console.log('on:' + this.id)
})
$("#mid").on('click','#inz',function(){
console.log('on:' + this.id)
})
mid.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
inz.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
</script>
<script>
var out = document.getElementById("out")
var mid = document.querySelector("#mid")
var inz = document.querySelector("#inz")
mid.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
inz.addEventListener('click', function () {
console.log('冒泡:' + this.id)
}, false)
$("#mid").on('click',function(){
console.log('on:' + this.id)
})
$("#mid").on('click','#inz',function(){
console.log('on:' + this.id)
})
</script>
jquery委托事件中的 this.id
,先于jquery绑定事件中的this.id
输出,但是通过addEventListener
绑定的事件还是由编写顺序觉定
四、在绑定事件中调用函数
1.this指向
2.call、apply参数区别
给DOM绑定事件时,事件函数的this是指向该DOM的,但是在事件函数中再调用其他函数,这时其他函数的this是指向window的。要想其他函数的this也指向DOM,可以使用call()
、apply()
我顺便用这个例子记一下call()
、apply()
参数的区别
<script>
var out = document.getElementById("out")
var mid = document.querySelector("#mid")
var inz = document.querySelector("#inz")
mid.addEventListener('click', function () {
ttt.call(this, '冒', '泡')
ttt.apply(this, ['冒', '泡'])
ttt('冒', '泡')
}, false)
function ttt(x, y) {
console.log(x + y + ':' + this)
}
</script>