1.編寫一個通用的事件監聽函數
function bindEvent(elem,type,selector,fn){
if(fn==null){
fn = selecotr;
selector = null;
}
elem.addEventListener(type,function(e){
var target;
if(selector){
target = e.target;
if(targer.matcher(selector)){
fn.call(target,e);
}
}else{
fn(e);
}
});
}
2.描述事件冒泡流程
1.Dom 樹形結構
2.事件冒泡 (一個一個往上冒,一層層觸發事件)
3.阻止冒泡(e.stopPropatation();)
4.冒泡的應用(使用代理)
3.對于一個無限下拉加載圖片的頁面,如何給每一個圖片綁定事件
1.使用代理
2.代理的兩個優點:
--代碼比較簡潔,綁定一次就可以了
--對瀏覽器的壓力比較小
(在頁面上執行了一堆js和在頁面上執行了一兩行js,內存和渲染的
壓力都會比較小一些,效率會高一些)
1.通用事件綁定
var btn = document.getElementById('btn1');
btn.addEventListener('click',function(event){
console.log('clicked');
});
function bindEvent(elem, type, fn){
elem.addEventListener(type,fn);
}
var a = document.getElementById('link1');
bindEvent(a,'click',function(e){
e.preventDefault(); //阻止默認行為
alert('clicked');
});
1.1關于IE低版本的兼容性
IE低版本使用 attachEvent 綁定事件,和W3C標準不一樣;
IE低版本使用量已經非常少,很多網站都早已不支持了;
建議對IE低版本的兼容性:了解即可,無需深究;
如果遇到對IE版本要求苛刻的面試,果斷放棄;
2.事件冒泡(冒泡的特點就是往上)
//需求:點擊激活彈出激活,點擊取消彈出取消
//body里面綁定click事件,點擊激活,首先要觸發綁定在它身上的事件
然后再去觸發綁定在它父節點(div1)上的事件,然后再去觸發綁定在
它父節點的父節點(body)上的事件,如果還有父節點還會往上冒;順著
DOM的一個樹形結構底層葉的節點的一個點擊事件會一層一層根據樹形結構
往它的父元素觸發。
<body>
<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>
</body>
function bindEvent(elem, type, fn){
elem.addEventListener(type,fn);
}
var p1= document.getElementById('p1');
var oBody = document.body;
bindEvent('p1','click',function(e){
e.stopPropatation(); //阻止冒泡
alert('激活') ;
});
bindEvent(body,'click',function(e){
alert('取消');
});
3.代理(事件冒泡的具體應用)
//代理的原理:
1.通過事件冒泡的機制
2.我們在上層的一個綁定可以通過target屬性拿到它真實觸發的元素
//需求:給所有的a標簽弄個click事件
<div id="div1">
<a href="#">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<!-會隨時新增更多了 a 標簽->
</div>
var oDiv = document.getElementById('div1'):
oDiv.addEventListener('click',function(e){
e.preventDefault();
var target = e.target; //target點擊是從哪觸發的
if(target.nodeName== 'A'){
alert(target.innerHTML);
}
});
4.完善通用綁定事件的函數
代理的好處:
1.代碼簡潔
2.減少瀏覽器內存占用
function bindEvent(elem,type,selector,fn){
if(fn == null){
//如果第三個參數沒有
fn = selector;
selector = null;
}
elem.addEventListener(type,function(e){
var target;
if(selector){
//代理
target = e.target;
//matches是不是符合目標的代理元素;
/*如果target是觸發事件的目標,dom節點是不是和
selector選擇器匹配的*/
if(target.matches(selector)){
//target----this
fn.call(target,e);
}
}else{
//不是代理
fn(e);
}
});
}
//使用代理
var div1 = document.getElementById('div1');
bindEvent(div1,'click','a',function(e){
e.preventDefault();
console.log(this.innerHTML);
});
//不使用代理
var a = document.getElementById('a1');
bindEvent(div1,'click',function(e){
console.log(a.innerHTML);
});