問題
編寫一個通用的事件監聽函數
描述事件冒泡的過程
對于一個無限下拉加載圖片的頁面,如何給每個圖片綁定事件
知識點
- 通用事件綁定
<input type="button" id="btn1" value="按鈕1">
<a id="aLink">簡書</a>
//標準方法
var btn = document.getElementById('btn1');
btn.addEventListener('click', function(e) {
console.log('checked')
})
//封裝事件綁定
function blindEvent(elem, type, fn) {
elem.addEventListener(type, fn)
}
var a = document.getElementById('aLink')
blindEvent(a, 'click', function(e) {
e.preventDefault() //阻止默認行為
alert('checked')
})
IE 低版本瀏覽器
IE 低版本使用 attachEvent 綁定事件,和 W3C 標準不一樣
IE 低版本使用量已經非常少了,很多網站都已經不支持了
建議對 IE 低版本的兼容性了解即可,無需深究
如果遇到對 IE 低版本要求苛刻的面試, 果斷放棄
- 事件冒泡
功能需求: 點擊下面的每個 P 標簽,彈出里面相應的內容
<div id="div1">
<p id="p1">激活</p>
<p id="p2">取消</p>
<p id="p3">取消</p>
<p id="p4">取消</p>
</div>
<div id="div2">
<p id="p5">取消</p>
<p id="p6">取消</p>
</div>
//封裝的綁定事件
function blindEvent(elem, type, fn) {
elem.addEventListener(type, fn)
}
//開始
var p1 = document.getElementById('p1');
blindEvent(p1, 'click', function(e) {
e.stopPropagation(); //阻止冒泡到上層;如果不阻止的話,會先彈出'激活',再彈出'取消',因為在body上也綁定了事件
alert('激活')
})
var body = document.body;
blindEvent(body, 'click', function(e) {
alert('取消')
})
- 事件代理(事件冒泡的具體應用)
使用場景:
多個元素上綁定相同的事件
原理:
利用冒泡機制
操作:
把事件綁定在要綁定元素的父元素上面
<div id="div1">
<a href="#">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<!-- 會隨時新增更多的 a 標簽 -->
</div>
var div1 = document.getElementById('div1');
div1.addEventListener('click', function(e) {
var target = e.target;
// e.target能告訴你點擊(事件)是從哪兒觸發的
//例如在div1 上綁定了一個點擊事件,在 a1 上點擊,這個時候 target 是a1,而不是 div1
if (target.nodeName === 'A') {
alert(target.innerHTML)
}
})
解題
1: 編寫一個通用的事件監聽函數
//elem:要綁定元素的父元素; type:事件類型; selector:本來要綁定的元素
function bindEvent(elem,type,selector,fn) {
//如果第四個參數沒有,那么第三個參數應該是一個函數,fn 就賦值成 selector
if(fn == null){
fn = selector
selector = null
}
elem.addEventListener(type,function(e) {
var target
if(selector) {
// 代理
target = e.target
if(target.matches(selector)) { //判斷目標節點是否和選擇器匹配
fn.call(target,e)
}
}else{
// 不使用代理
fn(e)
}
})
}
//使用代理
var div1 = document.getElementById('div1')
bindEvent(div1,'click','a',function(e) {
e.preventDefault()
console.log(this.href);
})
//不使用代理
var btn1 = document.getElementById('btn1')
bindEvent(btn1,'click',function(e) {
console.log(btn1.innerHTML);
})
2:描述事件冒泡流程
- DOM樹形結構
- 事件冒泡
- 阻止冒泡
事件從最深的節點開始,然后一層一層逐步向上傳播開來
3:對于一個無限下拉加載圖片的頁面,如何給每個圖片綁定事件
使用代理
把事件綁定在要綁定元素的父元素上面