事件捕获与冒泡
#很常见的,页面的交互效果大部分都是通过“事件”来进行处理的。
浏览器的事件流:事件捕获阶段 -> 事件处理阶段 -> 事件冒泡阶段
知识点:
- 事件捕获
- 事件冒泡
一、事件捕获
在DOM元素触发事件时,其浏览器执行事件的流程阶段中,捕获是从最外层的DOM(body)到实际触发元素这样的一个至上而下的事件触发过程。
1.由JS动态生成插入的dom元素无法触发事件?
HTML:
<ul class="list-item"> <!-- 先循环给原有的li绑定click事件 --> <li class="item">快点点我啊!</li> <li class="item">拜托点我啊!</li> <li class="item">麻烦点我啊!</li> <li class="item">跪求点我啊!</li> <li class="item">求求你点我!</li> <!-- 此处绑定添加新元素 --> <li class="item add_item">点我添加+</li> </ul>
Javascript:
window.onload = function() { var list_box = document.querySelector('.list-item'); var list_Array = list_box.querySelectorAll('.list-item > li'); var add_item = list_box.querySelector('.add_item'); // 原循环dom并绑定click事件 for(var i=0; i<list_Array.length; i++) { list_Array[i].onclick = function(event){ console.log(event); } } // 添加新元素事件 add_item.onclick = function(event){ var new_li = document.createElement("li"); var val_ = document.createTextNode("我是新来的"); new_li.setAttribute('class', 'item new'); new_li.appendChild(val_); list_box.appendChild(new_li); } }
## 这里实现为li元素绑定click事件并打印信息,且li.add_item 添加事件动态生成 li.item.new
这时,你会发现由 js动态新增的li元素并没有绑定成功click事件!
为什么会这样子呢?
个人理解: JS执行for遍历循环的是DOM树结构中原先存在的 li 元素,而对于动态新增的 li.item.new元素是之后生成的,所以并不能为其绑定click事件,除非再进行一次 querySelectorAll('li') 查询。(显然是不明智的 -_ - !!!)
尝试解决办法:
// 续.. // 事件委托 list_box.onclick = function(event){ var target = event.target; var class_name = [target.className].toString(); if (class_name.indexOf('item') === 0) { console.log(target); // ok解决 target就是触发点击事件源元素! } }
原理:利用了事件的捕获,点击子元素li元素,触发了父元素ul的click事件,关键在于通过 event.tartget 获取的源点击元素。。。