国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
javascript事件委托理解,jQuery .on()方法一步到位實(shí)現(xiàn)事件委托
概述:
什么叫事件委托?他還有一個(gè)名字叫做事件代理,(時(shí)間代理 === 事件委托,現(xiàn)在才知道這兩個(gè)是一個(gè)意思)
高程3上講:事件委托即是利用事件冒泡,只指定一個(gè)事件處理程序,就可以管理某一類(lèi)型的所有事件。
借鑒其他大牛的一個(gè)例子,也為自己更好的理解一下:收快遞例子
有三個(gè)同事預(yù)計(jì)會(huì)在周一收到快遞。為簽收快遞,有兩種辦法:一是三個(gè)人在公司門(mén)口等快遞;二是委托給前臺(tái)MM代為簽收。現(xiàn)實(shí)當(dāng)中,我們大都采用委托的方案(公司也不會(huì)容忍那么多員工站在門(mén)口就為了等快遞)。前臺(tái)MM收到快遞后,她會(huì)判斷收件人是誰(shuí),然后按照收件人的要求簽收,甚至代為付款。這種方案還有一個(gè)優(yōu)勢(shì),那就是即使公司里來(lái)了新員工(不管多少),前臺(tái)MM也會(huì)在收到寄給新員工的快遞后核實(shí)并代為簽收。
兩層意思:
1.現(xiàn)在委托前臺(tái)的同事是可以簽收的,即程序中的現(xiàn)有的dom節(jié)點(diǎn)是有事件的;
2.新員工也是可以被前臺(tái)mm代為簽收的,即程序中新添加的dom節(jié)點(diǎn)也是有事件的;
為什么要用事件委托???事件委托有什么好處???
一般來(lái)說(shuō),dom是需要有事件處理程序的,我們會(huì)直接給他事件處理程序就好了,那么如果是很多dom元素需要添加事件處理呢???
比如 100個(gè)li,每個(gè)li 都有相同的click點(diǎn)擊事件,可能我們會(huì)有for循環(huán)的方法,來(lái)遍歷所有l(wèi)i,然后為每個(gè)li添加綁定事件。
這么做毫無(wú)疑問(wèn)的是對(duì)性能有很大的影響;
在js中,添加到頁(yè)面上的事件處理程序的多少將直接關(guān)系到頁(yè)面運(yùn)行的整體性能,因?yàn)樾枰粩嗟呐cdom節(jié)點(diǎn)進(jìn)行交互,訪問(wèn)dom次數(shù)越多,引起瀏覽器重繪與重排的次數(shù)也就越多,就會(huì)延長(zhǎng)整個(gè)頁(yè)面的交互就緒時(shí)間。
這就是性能優(yōu)化,減少dom操作的原因;
如果采用事件委托,就會(huì)將所有的操作放到j(luò)s程序里面,與dom的操作就只交互一次,這樣減少了dom交互次數(shù),性能就會(huì)提升;
事件委托原理:
事件委托就是利用事件冒泡原理實(shí)現(xiàn)的!
事件冒泡:就是事件從最深節(jié)點(diǎn)開(kāi)始,然后逐步向上傳播事件;
例:頁(yè)面上有一個(gè)節(jié)點(diǎn)樹(shù),div > ul  > li  >  a
比如給最里面的a 加一個(gè)click 事件,那么事件就會(huì)一層一層的往外執(zhí)行,執(zhí)行順序 a > li > ul > div,  有這樣一個(gè)機(jī)制,當(dāng)我們給最外層的div 添加點(diǎn)擊事件,那么里面的ul , li  , a  做點(diǎn)擊事件的時(shí)候,都會(huì)冒泡到最外層的div上,所以都會(huì)觸發(fā),這就是事件委托,委托他們父集代為執(zhí)行事件;
業(yè)務(wù)需求:實(shí)現(xiàn)功能,點(diǎn)擊td ,單元格變色;
html結(jié)構(gòu)
[html] view plain copy
<!-- 事件綁定 -->
<table id="myTable" border="1">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
[javascript] view plain copy
window.onload = function(){
var oTa = document.getElementById("myTable");
var aTd = oTa.getElementsByTagName('td');
for(var i=0;i<aTd.length;i++){
aTd[i].onclick = function(){
aTd[i].style.background = 'red';
}
}
}
上面的辦法是最簡(jiǎn)單的辦法,也是最笨的辦法,我們看看執(zhí)行了多少次dom操作,首先找到table 然后遍歷td ,當(dāng)點(diǎn)擊td的時(shí)候,又要找一次目標(biāo)的li的位置,才能執(zhí)行最后的操作,每次點(diǎn)擊都要找一次td
那我們用事件委托的方式怎么來(lái)寫(xiě)呢,??
[javascript] view plain copy
window.onload = function(){
var oTa= document.getElementById("myTable");
oTa.onclick = function(){         //點(diǎn)擊 table、td均可以alert(123)
alert(123);
}}
[javascript] view plain copy
<pre></pre>
<pre></pre>
這里用父集做事件處理,當(dāng)td被點(diǎn)擊時(shí),由于冒泡原理事件就會(huì)冒泡到table上,因此table上有點(diǎn)擊事件,所以事件就會(huì)被觸發(fā);
當(dāng)然單當(dāng)點(diǎn)擊table本身的時(shí)候也是會(huì)觸發(fā)的;
如果我們只想讓td觸發(fā)而不想讓table觸發(fā),怎么辦呢???
Event對(duì)象提供了一個(gè)屬性叫做target,可以返回事件的目標(biāo)節(jié)點(diǎn),我們稱之為事件源,也就是說(shuō),target就可以表示當(dāng)前事件操作的dom,但可能不是真正操作的dom,
存在兼容性問(wèn)題:標(biāo)準(zhǔn)瀏覽器:event.target,IE瀏覽器:event.srcElement,
此時(shí)只是獲取了當(dāng)前節(jié)點(diǎn)的位置,但并不知道節(jié)點(diǎn)名稱,這里我們用nodeName來(lái)獲取具體是什么標(biāo)簽名,這個(gè)返回值是一個(gè)大寫(xiě)的,判斷時(shí)需要轉(zhuǎn)換為小寫(xiě);[javascript] view plain copy
window.onload = function(){
var oTa = document.getElementById("myTable");
oTa.onclick = function(e){
var e = e || window.event;                    //處理兼容性
var target = e.target || e.srcElement;
target.nodeName.toLowerCase() == 'td' ? alert('我點(diǎn)中了table') :(target.style.background = 'red');  //三元運(yùn)算符進(jìn)行判斷
}
}
這樣改一下,就只有td會(huì)觸發(fā)事件啦,且每次只執(zhí)行一次dom操作,如果td很多的話,將大大減小dom的操作;
上面的例子是說(shuō)td點(diǎn)擊都是產(chǎn)生同樣的效果,要是每個(gè)td被點(diǎn)擊的效果都不一樣,那么事件委托還有用嗎,???
[javascript] view plain copy
<!-- 事件綁定 -->
<table id="myTable" border="1">
<tr>
<td id="add">增加</td>
<td id="delete">刪除</td>
<td id="modfiy">修改</td>
<td id="select">查找</td>
</tr>
</table>
非事件委托寫(xiě)法
[javascript] view plain copy
window.onload = function(){
var Add = document.getElementById("add");
var Delete = document.getElementById("delete");
var Move = document.getElementById("move");
var Select = document.getElementById("select");
Add.onclick = function(){
alert('添加');
};
Remove.onclick = function(){
alert('刪除');
};
Move.onclick = function(){
alert('移動(dòng)');
};
Select.onclick = function(){
alert('選擇');
}
}
4個(gè)按鈕,點(diǎn)擊每一個(gè)做不同的動(dòng)作,,,那么至少需要4次dom操作;
如果用事件委托,能進(jìn)行優(yōu)化嗎?
事件委托寫(xiě)法
[javascript] view plain copy
window.onload = function(){
var myTable = document.getElementById("myTable");
myTable.onclick = function (ev) {
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLocaleLowerCase() == 'table'){
switch(target.id){
case 'add' :
alert('添加');
break;
case 'remove' :
alert('刪除');
break;
case 'move' :
alert('移動(dòng)');
break;
case 'select' :
alert('選擇');
break;
}
}
}
}
用事件委托,只用一次dom操作,就能完成所有的效果,性能肯定比上面的好;
前面講的都是document加載完成后現(xiàn)有的dom節(jié)點(diǎn)的操作;
那么如果是新增的節(jié)點(diǎn),新增的節(jié)點(diǎn)會(huì)有事件嗎???也就是說(shuō),新來(lái)的一個(gè)員工,他能收到快遞嗎????
看一下正常添加節(jié)點(diǎn)的方法:
[javascript] view plain copy
<input type="button" name="" id="btn" value="添加" />
<ul id="ul1">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
用一般的方法,循環(huán)加給li加點(diǎn)擊事件,你會(huì)發(fā)現(xiàn)新增的li沒(méi)有事件?。?!
解決辦法:
一般情況下,我們會(huì)用一個(gè)函數(shù)把那個(gè)for循環(huán)包起來(lái),然后再在點(diǎn)擊事件里調(diào)用這個(gè)函數(shù),這樣也能實(shí)現(xiàn)目的,功能雖然實(shí)現(xiàn)了,但無(wú)疑又增加了dom操作,
用事件委托的方式如何做呢???
[javascript] view plain copy
<script type="text/javascript">
window.onload = function(){
var ul1 = document.getElementById('ul1');
var li = document.getElementsByTagName('li');
var btn = document.getElementById('btn');
var num = 1;
// for(var i=0;i<li.length;i++){
//  li[i].onclick = function(){
//      alert(this.innerHTML);
//  }
//  num++;
// }
ul1.onclick = function(e){
var e = e || window.event;
var target = e.target || event.srcElement;
console.log(target.nodeName);
target.nodeName.toLowerCase() == 'li' ? alert(target.innerHTML) : alert("您點(diǎn)中了ul標(biāo)簽");
}
btn.onclick = function(){
var oLi = document.createElement('li');
oLi.innerHTML = 111*num;
ul1.appendChild(oLi);
}
}
上面是用事件委托的方式,新添加的子元素也是有點(diǎn)擊功能的;
我們可以發(fā)現(xiàn),當(dāng)用事件委托的時(shí)候,根本不需要遍歷元素的子節(jié)點(diǎn),只需要給父級(jí)元素添加事件就好了,
其他的代碼都是在js里面執(zhí)行的,這樣可以大大減少dom操作,
這就是我理解的事件委托的精髓;
jQuery事件委托:
我直接上code了,jquery的操作是如此的簡(jiǎn)單,一個(gè)on全搞定?。?!
[html] view plain copy
<!-- 事件綁定 -->
<table id="myTable" border="1">
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
<td>444</td>
</tr>
</table>
[javascript] view plain copy
<script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$("#myTable td").click(function(){
$(this).html();  //普通寫(xiě)法,如果有100個(gè)td元素,就要綁定100次事件,十分浪費(fèi)性能
})
$("#myTable").click(function(e){    //這種點(diǎn)擊方式怎么排除父元素????
console.log(e.target);
var $clicked = $(e.target);    //e.target 捕捉到觸發(fā)的元素
console.log(e.target.nodeName);  //結(jié)果為大寫(xiě),用toLowerCase()  轉(zhuǎn)換為小寫(xiě)
e.target.nodeName.toLowerCase() == 'table' ? alert('我點(diǎn)中table了')  : $clicked.html();  //排除父元素的點(diǎn)擊效果
})
// jQuery1.7的on綁定方法,替代了以往的bind、live等方法,內(nèi)部自動(dòng)含有事件委托機(jī)制
// $(selector).on(event,childSelector,data,function,map)   on方法的語(yǔ)法
// $(selector).on(event,childSelector,function(){})        on方法語(yǔ)法,綁定在父元素上 事件,子選擇器,回調(diào)函數(shù)
$("#myTable").on('click','td',function(){
$(this).html();
})
})
</script>
總結(jié):
事件委托的優(yōu)點(diǎn):1.在頁(yè)面dom元素較多的情況下,大大減少了dom操作,優(yōu)化了性能;
2.值需要為一個(gè)父元素綁定事件,就可以管理他下面的所有子元素;
3。。。。。。啦啦啦啦,我也不知道啦
適用性:
適合:click 、mousedown、mouseup、keydown 、keyup、keypress
不適合:mouseover和mouseout雖然也有事件冒泡,但是處理他們要特別注意,因?yàn)樾枰?jīng)常計(jì)算他們的位置,處理起來(lái)不太容易,
focus、blur之類(lèi)的本身就沒(méi)有冒泡的特性,自然不能用事件委托;
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
js中的事件委托或是事件代理詳解
jQuery基礎(chǔ)
jQuery性能優(yōu)化
jQuery對(duì)象+選擇器+DOM操作
jQuery性能優(yōu)化指南(2)
jQuery選擇器及jquery案例詳解(必看)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服