事件
Jonnzer Lv4

介绍下事件流:
三个阶段:捕获、目标、冒泡
事件流

冒泡,字面上理解,就是从下往上冒泡,咕噜咕噜~可以理解成从具体节点到不具体节点的事件流(addEventListener默认监听选项)

捕获,与冒泡相反,就是从大节点一直往下获取事件流,直到具体节点

事件委托(事件委托 是 别名)

如果你想要在大量子元素中单击任何一个都可以运行一段代码,您可以将事件监听器设置在其父节点上,并让子节点上发生的事件冒泡到父节点上,而不是每个子节点单独设置事件监听器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// jq
$('.top_wrapper a').each(function (index,item) {
let aLink = $(item).attr('href');
if (!aLink.includes('?')) {
aLink += '?';
}
if (coupon) {
aLink +=`&coupon=${coupon}`;
$(item).attr('href',aLink );
}
if (qd) {
aLink +=`&qd=${qd}`;
$(item).attr('href',aLink );
}
$(item).attr('href', aLink);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
 // 原生
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
var list = document.querySelector('#list')
list.addEventListener('click',function (e){
if(e.target.tagName === 'LI'){
console.log('当前元素事件触发成功')
}
})

事件监听

addEventListener(eventName,function,bool) // eventName事件名 function是触发的函数 bool为true时是捕获 默认是false冒泡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<ul id="list">
<li>
<div>div</div>
</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var list = document.querySelector('#list')
list.addEventListener('click', function (e) {
// elem.closest(selector) 方法返回与 selector 匹配的最近的祖先。'
// 在我们的例子中,我们从源元素开始向上寻找 <li>。
// 限定不超出ul#list的范围
let li = e.target.closest('li');
if (!li) return;
if(!list.contains(li)) return;
console.log(li)
})
</script>

事件绑定

(1) 内联 (优先级最高)

1
<input type="button" value="按钮" onclick="alert(1);">

(2) 对象.事件

1
2
3
4
5
6
7
<input type="button" value="按钮">

var bt = document.getElementsBytagname("input")[0]
bt.onclick = function(){
alert(2)
}

以上两种方式只能绑定一个事件

(3) addEventListener

1
2
3
4
5
6
7
8
<input type="button" value="按钮">

var bt = document.getElementsBytagname("input")[0]

bt.addEventListener('click',function(){

})

event.stopPropagation: 阻止捕获和冒泡阶段中当前事件的进一步传播。
event.preventDefault: 阻止默认行为,调用了后就会取消事件的执行。

知识点:

事件绑定
事件冒泡
事件代理

QA:

编写一个通用的事件监听函数

有时候在事件处理函数内部,您可能会看到一个固定指定名称的参数,例如 event,evt 或简单的 e。
这被称为事件对象,它被自动传递给事件处理函数,以提供额外的功能和信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function bindEvent(elem, type, selector, fn) {
if (fn == null) {
fn = selector
selector = null
}
elem.addEventListener(type, e => {
const target = e.target
if (selector) {
if(target.matches(selector)) { // https://developer.mozilla.org/zh-CN/docs/Web/API/Element/matches 匹配css选择器 返回 布尔
fn.call(target, event)
} else {
fn.call(target, event)
}
}
})
}
const btn1 = document.getElementById('btn1')
btnEvent(btn1, 'click', 'button', event => {
event.preventDefault()
alert('clicked')
})
描述事件冒泡的流程

基于DOM 树形结构, DOM 树的深层级 往 浅层级 的事件响应,就是 事件冒泡
事件代理 的机制也是 事件冒泡

1
2
3
4
5
6
7
8
9
10
// 阻止事件冒泡
const p1 = document.querySelector('#p1')
const body = document.body
bindEvent(p1, 'click', (e) => {
e.stopPropagation()
alert('子')
})
bindEvent(body, 'click', (e) => {
alert('父')
})
无限下拉的图片列表,如何监听每个图片的点击?

参考:
segment
javascript.info
event.stopPropogation
事件 MDN

  • 本文标题:事件
  • 本文作者:Jonnzer
  • 创建时间:2018-07-27 06:18:00
  • 本文链接:https://jonnzer.github.io/2018/07/27/JS/事件/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论