前端性能提升+內(nèi)存管理+事件委托

標(biāo)簽(空格分隔): 事件委托 冒泡 性能優(yōu)化


序:

開(kāi)啟本文前巢墅,首先有幾點(diǎn)要說(shuō)明一下侦铜。
問(wèn)題
1:添加到文檔上的事件處理程序越多院塞,頁(yè)面整體運(yùn)行性能越低。
2:每個(gè)函數(shù)都是對(duì)象戏溺,都要占內(nèi)存渣蜗,內(nèi)存中的對(duì)象越多,性能越差于购,跑不動(dòng)
3:頁(yè)面一加載上來(lái)要事先指定DOM的事件處理程序袍睡,導(dǎo)致訪問(wèn)DOM的次數(shù),進(jìn)而延遲了整個(gè)文檔的交互就緒時(shí)間肋僧。
所以:從以上的角度考慮:
解決
1》避免向頁(yè)面中DOM添加大量的事件處理程序斑胜,限制了DOM和js建立連接的數(shù)量。利用委托嫌吠,只是給某個(gè)祖級(jí)指定一個(gè)事件處理程序止潘,來(lái)管理某一類(lèi)的所有事件。例如:管理所有的點(diǎn)擊辫诅。
2》對(duì)于即將移除的DOM凭戴,要手動(dòng)移除其身上的事件處理程序。有些瀏覽器不會(huì)做只能處理釋放掉炕矮,比如:通過(guò)innerHTML方式替換掉的元素么夫。

方案一:利用委托

論證上邊寫(xiě)的很清楚了者冤,下面就是針對(duì)每個(gè)方案上一段代碼吧。
HTML:

<div class="con">
    <button id="btn1">點(diǎn)擊我變色</button>
    <p id="btn2">點(diǎn)擊出彈窗</p>
    <h6 id="btn3">點(diǎn)擊做跳轉(zhuǎn)</h6>
</div>

CSS:

 .con {
            background: rgba(0, 0, 0, .2);
            border: 1px solid #ff9;
        }

.btn1, .btn2, .btn3 {
            width: 300px;
            height: 50px;
            border: 1px solid #000;
            text-align: center;
            line-height: 50px;
            cursor: pointer;
}

目標(biāo):
點(diǎn)擊3個(gè)元素走不同的事件處理程序档痪。

分析:
3個(gè)元素共同的祖級(jí)是類(lèi)名叫.con的元素涉枫。所以把事件執(zhí)行程序與他建立聯(lián)系即可。而不是傳統(tǒng)的給每個(gè)元素綁定一次事件處理代碼腐螟。

實(shí)現(xiàn):
JS:

  window.onload = function () {
//1:獲取DOM
        var btn1 = document.querySelector('#btn1');
        var btn2 = document.querySelector('#btn2');
        var btn3 = document.querySelector('#btn3');
        var con = document.querySelector('.con');

//2:事件委托
        con.addEventListener('click', function (e) {
            var e = e || event;

            if (e.target.id == 'btn1') {
                //換背景色
                con.style.background = '#80B3FF';
            }
            if (e.target.id == 'btn2') {
                //彈出目標(biāo)的id
                alert(e.target.id);
            }
            if (e.target.id == 'btn3') {
                //做跳轉(zhuǎn)
                window.location.;
            }

        }, true)
    }

===================================================
tip:
這里是通過(guò)事件對(duì)象的里的target對(duì)象里的id屬性愿汰,當(dāng)然這種在實(shí)際開(kāi)發(fā)事使用較少,畢竟要給每個(gè)元素一個(gè)id乐纸,id甚是寶貴衬廷,不能亂來(lái),所以汽绢,再看看通過(guò)其他方式選中你要操作的元素吗跋。普通元素還可以通過(guò)節(jié)點(diǎn)名(標(biāo)簽名),標(biāo)簽內(nèi)容庶喜。表單元素還可以通過(guò)name屬性小腊,例如這里的button按鈕救鲤。標(biāo)簽身上設(shè)置下name屬性久窟。js里根據(jù)這個(gè)屬性去拿到對(duì)應(yīng)DOM。

===================================================

通過(guò)其他方式拿到對(duì)應(yīng)的DOM

1.標(biāo)簽名:

HTML:

<div class="con">
    <button>點(diǎn)擊我變色</button>
    <p>點(diǎn)擊出彈窗</p>
    <h6>點(diǎn)擊做跳轉(zhuǎn)</h6>
</div>

這里省略樣式本缠,和上邊一致的斥扛。.con里的子只有標(biāo)簽名字。

JS:

   window.onload = function () {
   
        var btn1 = document.querySelector('button');
        var btn2 = document.querySelector('p');
        var btn3 = document.querySelector('h6');

        var con = document.querySelector('.con');


        con.addEventListener('click', function (e) {
            var e = e || event;
     
            if (e.target.nodeName.toLowerCase() == 'button') {
                //換背景色
                con.style.background = '#80B3FF';
            }
            if (e.target.nodeName.toLowerCase() == 'p') {
                //彈出目標(biāo)的id
                alert(e.target.nodeName);
                //二者是一致的
                alert(e.srcElement.nodeName);
            }
            if (e.target.nodeName.toLowerCase() == 'h6') {
                //做跳轉(zhuǎn)
                window.location.;
            }

        }, true)
    }

e.target.nodeName拿到的是大寫(xiě)的標(biāo)簽名字丹锹,所以需要轉(zhuǎn)換成小寫(xiě)好處理些稀颁。toLowerCase()一下就OK了。

2.標(biāo)簽內(nèi)容:

HTML:

<div class="con">
    <button>點(diǎn)擊我變色</button>
    <p>點(diǎn)擊出彈窗</p>
    <h6>點(diǎn)擊做跳轉(zhuǎn)</h6>
</div>

JS:

   window.onload = function () {

        var con = document.querySelector('.con');

        con.addEventListener('click', function (e) {
            var e = e || event;
            if (e.target.innerHTML == '點(diǎn)擊我變色') {
                //換背景色
                con.style.background = '#80B3FF';
            }
            if (e.target.innerHTML == '點(diǎn)擊出彈窗') {
                //彈出目標(biāo)的id
                alert(e.target.nodeName);
                //二者是一致的
                alert(e.srcElement.nodeName);
            }
            if (e.target.innerHTML == '點(diǎn)擊做跳轉(zhuǎn)') {
                //做跳轉(zhuǎn)
                window.location.;
            }

        }, true)
    }

利用 e.target.innerHTML或者是e.target.innerText都可以楣黍。

3.表單標(biāo)簽的name屬性:

如果是表單元素匾灶,還可以在表單元素上把name屬性設(shè)置下。

HTML:

<div class="con">
    <button name="fromDomBtn">點(diǎn)擊我變色</button>
    <p>點(diǎn)擊出彈窗</p>
    <h6>點(diǎn)擊做跳轉(zhuǎn)</h6>
</div>

JS:這里只是寫(xiě)按鈕部分了租漂。

con.addEventListener('click', function (e) {
            var e = e || event;
            
            if (e.target.name == 'fromDomBtn') {
                //換背景色
                con.style.background = '#80B3FF';
            }
    }

利用表單身上的屬性name;即e.target.name

常規(guī)處理方式就是以上幾種阶女,可以根據(jù)你的代碼選擇合適的方案。

方案二:手動(dòng)移除事件處理程序

如果心里清楚哩治,哪些帶有事件處理程序的元素將要被移除秃踩,那么最好手動(dòng)置空他的事件處理程序,即切斷了DOM和js之間的引用關(guān)系业筏。如果直接對(duì)DOM進(jìn)行增刪改查中的“刪”憔杨,即:removeChild()/replaceChild()等,是不需要咱們手動(dòng)再置空他們身上原來(lái)的事件引用蒜胖。因?yàn)榍岸说拇a一般不需要我們進(jìn)行內(nèi)存管理消别、垃圾回收等操作抛蚤,瀏覽器會(huì)幫我們做好。這里說(shuō)的將要被移除是指通過(guò)innerHTML的方式替換達(dá)到刪除的結(jié)果寻狂,此時(shí)就需要我們做點(diǎn)事了霉颠,因?yàn)橐恍g覽器不會(huì)很好的處理這一塊,例如(IE)荆虱;下邊用代碼演示下具體怎么實(shí)現(xiàn):

HTML:

<div class="con">
    <button>點(diǎn)擊我發(fā)生con的內(nèi)容替換</button>
</div>

JS:

  window.onload = function () {
        var con = document.querySelector('.con');
        var btn = document.querySelector('button');
        
        const txt = ` <h1>Lorem ipsum dolor.</h1>
    <p> Error esse est illo impedit libero molestias, perspiciatis ratione repudiandae voluptate voluptatem!</p>`;



        btn.onclick = function () {
            btn.onclick = null;//點(diǎn)擊進(jìn)來(lái)后手動(dòng)釋放自身和事件處理程序的引用關(guān)系蒿偎;用過(guò)一次就釋放掉了
            con.innerHTML = txt;
        }
    }

把這段代碼,復(fù)制到你的編譯器試試吧怀读,點(diǎn)擊事件肯定只會(huì)執(zhí)行一次诉位。

js庫(kù)實(shí)現(xiàn)委托

如果你不是使用原生js,使用jQuery或是zepto等怎么做呢菜枷?更簡(jiǎn)單苍糠。直接上代碼。

HTML片段截绕√堋:

    ![](/gameInfo/images/ban.jpg)
    <a href="###" class="loadBtn hrefTo"></a>
    <b class="clickDetail hrefTo">(點(diǎn)擊了解詳情)</b>

由于jQuery/zepto里自帶的事件注冊(cè)on方法只能接受3個(gè)參數(shù)岳瞭,所以對(duì)于第二個(gè)參數(shù)DOM;要好好利用下了蚊锹,把需要的做同一件事的dom都附屬一個(gè)類(lèi)名叫:hrefTo的瞳筏。OK。

    //1:引入庫(kù)
    <script src="/common/js/zepto.min.js"></script>
    //2:點(diǎn)擊banner/了解詳情/下載按鈕三處實(shí)現(xiàn)跳轉(zhuǎn)
    
    $('body').on('click','.hrefTo',function () {
        window.location.;
    });

----------------------------------------------------喜歡就動(dòng)動(dòng)小手哈牡昆。------------------------------------------------------

--------------------------------------你的支持是灑家-麥殼-macrolam前進(jìn)的動(dòng)力--------------------------------------

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末姚炕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子丢烘,更是在濱河造成了極大的恐慌柱宦,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件播瞳,死亡現(xiàn)場(chǎng)離奇詭異掸刊,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)赢乓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)忧侧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人骏全,你說(shuō)我怎么就攤上這事苍柏。” “怎么了姜贡?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵试吁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)熄捍,這世上最難降的妖魔是什么烛恤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮余耽,結(jié)果婚禮上缚柏,老公的妹妹穿的比我還像新娘。我一直安慰自己碟贾,他們只是感情好币喧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著袱耽,像睡著了一般杀餐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上朱巨,一...
    開(kāi)封第一講書(shū)人閱讀 51,521評(píng)論 1 304
  • 那天史翘,我揣著相機(jī)與錄音,去河邊找鬼冀续。 笑死琼讽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的洪唐。 我是一名探鬼主播钻蹬,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼桐罕!你這毒婦竟也來(lái)了脉让?” 一聲冷哼從身側(cè)響起桂敛,我...
    開(kāi)封第一講書(shū)人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤功炮,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后术唬,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體薪伏,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年粗仓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嫁怀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡借浊,死狀恐怖塘淑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蚂斤,我是刑警寧澤存捺,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響捌治,放射性物質(zhì)發(fā)生泄漏岗钩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一肖油、第九天 我趴在偏房一處隱蔽的房頂上張望兼吓。 院中可真熱鬧,春花似錦森枪、人聲如沸视搏。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)凶朗。三九已至,卻和暖如春显拳,著一層夾襖步出監(jiān)牢的瞬間棚愤,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工杂数, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宛畦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓揍移,卻偏偏與公主長(zhǎng)得像次和,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子那伐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理踏施,服務(wù)發(fā)現(xiàn),斷路器罕邀,智...
    卡卡羅2017閱讀 134,656評(píng)論 18 139
  • 前端開(kāi)發(fā)面試知識(shí)點(diǎn)大綱: HTML&CSS: 對(duì)Web標(biāo)準(zhǔn)的理解畅形、瀏覽器內(nèi)核差異、兼容性诉探、hack日熬、CSS基本功:...
    秀才JaneBook閱讀 2,366評(píng)論 0 25
  • 每一次相愛(ài)都是那么簡(jiǎn)單, 而分手卻是痛心的無(wú)奈肾胯。 好像每一次都是夢(mèng)境的過(guò)往竖席, ...
    微詩(shī)人閱讀 316評(píng)論 0 1
  • 對(duì)“淋漓”這個(gè)詞有感大約是看了《按自己的意愿過(guò)一生》毕荐,這種將自己有限的生命撐大到淋漓盡致的狀態(tài)讓人羨慕,同樣也...
    羽然說(shuō)閱讀 729評(píng)論 0 1
  • 何處古琴暗飛聲艳馒,散入秋風(fēng)滿(mǎn)城南憎亚。 八月十六,空氣中飄著些許雨絲和淡淡的桂花香,我的心情如同這飄飄漾漾的花香...
    多肉多智閱讀 689評(píng)論 0 2