不管新手老手,在前端開發中,常常要爲DOM元素綁定事件,以實現某些功能。
如何經過一些JS技巧,達到減小事件綁定,優化頁面性能的目的呢?
接下來介紹一下我我的對優化事件綁定的實踐。css
我儘可能寫得通俗易懂一些,但願能爲剛入門前端的人們帶來幫助。
也歡迎你們踊躍評論和指正,一塊兒分享建議和想法哦。html
哈哈,放心,我不會強行地科普一堆瀏覽器事件機制晦澀的理論,前端
事件傳播機制在各類瀏覽器或版本上可能會有差別,在差別中尋找平衡點,冒泡機制是個突破口。jquery
這裏直接給出最佳實踐:利用事件冒泡機制來爲DOM元素綁定事件。瀏覽器
理由一:早期IE只有冒泡機制,統一使用冒泡機制來綁定事件,就解決了最棘手的IE瀏覽器兼容性問題了。函數
理由二:事件傳播的冒泡階段,最接近頁面UI上看到的實際狀況,由子元素逐級向父元素傳播,更加直觀而且容易理解。性能
理由三:對於動態添加的DOM元素,要直接爲其綁定事件,只能推到元素建立後進行。但若是利用事件冒泡機制,不須要再爲這個時間點所糾結。優化
話很少說,直接上實例(下面的示例都不造輪子,直接用jquery了哈)。網站
假如如今有一個無序列表,須要在點擊具體列表項時,於控制檯打印該項的HTML內容。
思路是:想辦法爲DOM元素綁定事件 -> 獲取元素HTML -> 輸出到控制檯。this
<ul class="list"> <li class="list-item">1</li> <li class="list-item">2</li> ... </ul>
<ul class="list"> <li class="list-item" onclick="handler(this)"></li> <li class="list-item" onclick="handler(this)"></li> ... </ul>
function handler(e) { console.log($(e).html()); }
一不留神懶惰先生跑了出來:OK搞定,完成任務!就這樣吧,能實現功能就能夠了。
思考:
這是種最古老的事件綁定方式,沒有作到JS和HTML的分離,很是不利於維護,是隨着潮流要被淘汰的糟糕作法。
但是不由感嘆,現在仍是會在某些中小型網站、教材、還有大學課堂上看到它們的身影。而後新手們紛紛模仿,從起點開始就走了很多彎路,我也是過來人(捂臉)。
$('.list-item').on('click', function() { // 獲取元素集合並綁定事件 console.log($(this).html()); };
此次作到了JS和HTML的分離,先獲取元素集合,再利用jquery
的事件綁定方法on()
,解決瀏覽器事件API的差別問題。
思考:
若是有100個列表項的話,jquery
就會遍歷100次,爲匹配的元素集合都綁定一個click
事件。
光這100次遍歷和綁定操做,就是件很是消耗資源的事情。
再加上因爲建立太多的事件監聽,也會對頁面性能有影響。
$('.list').on('click', 'li', function(event) { // 綁定事件到父節點 console.log($(event.target).html()); // 注意操做對象是event.target仍是this,下面會有詳細說明哦 });
優化後,將監聽函數放到了父元素上,經過只監聽父元素的一個事件,掌控了千千萬萬的列表項。
藉助冒泡機制,事件綁定由100優化到1,就是這麼愉快,哈哈哈。
使用on()
方法的篩選器
這裏用到了on()
方法的第二個參數,這個參數是個篩選器,例如li
,>li
,.list-item
,li.list-item
等。
當檢測到點擊事件是由這個篩選器匹配的元素傳來的,就觸發這個父節點的click事件回調函數。
篩選器沒有用.list-item
而是li
由於若是把css類做爲篩選器的話,jquery
在執行時要把每一個event.target
的class
屬性去查一查,而後拆分後看看是否是有叫list-item
。判斷步奏多了不少。
本示例中,只使用li
來篩選就已經知足咱們的需求了,優化要從細節開始哦。
注意回調函數中操做的是this
仍是event.target
由於當前是在父元素中綁定的事件,因此this
默認指向的是父元素,並非咱們的列表項。
可是這裏要強調一點:若是使用on()
方法中的篩選器自動篩選的話,jquery
也會自動幫咱們把this
指向改爲event.target
,這時候this
和event.target
都一樣指向的是列表項了,兩個均可以用哦。
建議使用event.target
,避免混淆,也可讓代碼更加清晰啦。
若是不使用jquery
在on()
方法中提供的篩選器的話,也能夠本身去判斷冒泡過來的是否是li:
$('.list').on('click', function(event) { if (event.target.tagName === 'LI') { // 判斷標籤是否是li,注意tagName屬性返回的是大寫 console.log($(event.target).html()); } });
這樣子不管是用on()
方法的自動篩選,仍是直接本身寫代碼判斷,均可以統一使用event.target
來獲取冒泡階段傳播到此的具體列表項,咱們就能夠開心的去操做它啦。
這裏介紹的只是幾個小點,在前端開發中能優化的地方還有不少不少。
重要的是精神層面上的東西,必須不知足於現狀、多思考、多注重細節,才能逼着本身一點點向前爬過去。
謝謝你看到了最後,你們一塊兒加油!