一个案例读懂JS事宜托付

事宜托付(别名事宜代办),就是应用事宜冒泡,只指定一个事宜处置惩罚顺序,就能够治理某一范例的一切事宜。

网上有关于事宜托付的一个“取快递”例子,非常活泼,这里我对它作一些修正和拓展,然后经由过程顺序来申明事宜托付的机制。

某公司有三位员工,他们的快递收件地点为公司,每当有快递送达时,快递员拨打其电话举行关照,他们接到电话后去取件。

员工ID员工称号联系方式
A111111
B222222
C333333

对应到页面,就是每一个员工是一个标记:

<ul id="前台工作人员">
    <li id="A">员工甲</li>
    <li id="B">员工乙</li>
    <li id="C">员工丙</li>
</ul>

每位员工接电话取快递的行动就是一个个事宜,这里我们假定收取快递行动对应着onclick事宜:


A.onclik = function() {
    收取快递;
};
B.onclick = function() {
    收取快递;
};
C.onclick = function() {
    收取快递;
};

以上的完成,一般为经由过程轮回遍历每一个员工,为其增添事宜:

/*顺序1*/
var aUl = document.getElemengtByID("前台工作人员");
var aLi = aUl.getElemengtsByTagName("li");
for (var i = 0; i < aLi.length; i++) {
    aLi[i].onclick = function() {
        收取快递;
    }
}

能够看到,为每一个员工都设置一个事宜,会发生冗余代码,占用内存,同时会举行屡次DOM操纵(与DOM节点举行交互),影响页面运转机能。

“削减DOM操纵是机能优化的重要头脑之一”

因而,我们天经地义地想到:为何不能让前台工作人员帮我们签收快递呢?

<ul id="前台工作人员">
    <li id="A">员工甲</li>
    <li id="B">员工乙</li>
    <li id="C">员工丙</li>
</ul>

/*顺序2*/
var tel = document.getElementById("前台工作人员");
tel.onclick = function() {
    收取快递;
}

假定此时快递员打电话关照员工甲取件(onclick),但员工甲的DOM节点<li>并没有对应事宜(onclick),所以这个事宜会“冒泡”到<li>的父元素<ul>,发明<ul>上有onclick处置惩罚事宜,因而触发该事宜,由前台工作人员收取快递。

能够看到,如许一来,不仅缩减代码量,同时与DOM节点的交互次数也获得了缩减。

另有一个长处:当增添新的DOM节点时,自动照顾父元素的事宜结果。也就是说,当有一个新员工丁来公司后,前台工作人员会直接帮他收取快递,而无需特地为他设置事宜。

比方,当新员工丁来到公司后:

...
<input type="button" id="btn" value="增加新员工">
...

...
/*顺序3*/
var aBtn = document.getElementById("btn");
aBtn.onclick = function() {
    var aLi = document.createElement("li");
    oLi.innerHTML = "员工丁";
    aUl.appendChild(aLi);
}
...

在不运用事宜托付的顺序中,新增的员工丁是没有事宜的,我们须要用一个函数包含住顺序1:

/*顺序4*/
function pro1() {
    var aUl = document.getElemengtByID("前台工作人员");
    var aLi = aUl.getElemengtsByTagName("li");
    for (var i = 0; i < aLi.length; i++) {
        aLi[i].onclick = function() {
            收取快递;
        }
    }
}

然后在新增新员工丁的顺序的末端实行这个函数:

/*顺序5*/
var aBtn = document.getElementById("btn");
aBtn.onclick = function() {
    ...
    pro1();
}

如许做的瑕玷是不言而喻的:DOM节点交互次数成倍增添。
若我们采纳事宜托付机制来完成,就不会存在这个题目,子元素节点的onclick事宜会直接在父元素节点获得实行。

到这里,我们会想到:关于同一种事宜来讲,运用事宜托付将其安排在父元素节点上当然很轻易。但假如关于差别的子元素节点要实行差别的事宜呢,还能运用事宜托付吗?

答案是一定的。

比方上述三位公司员工,老是运用牢固品牌的快递:

  • 员工甲由于廉价,喜好运用申通快递,申通只送到园区大门;
  • 员工乙是京东会员,老是购置京东自营商品,京东快递送到楼下;
  • 员工丙是顺丰VIP,顺丰快递会送到送到地点楼层大厅。

他们三位在接到电话后,前台工作人员须要去差别的处所取件,关于不运用事宜托付的顺序,须要对每一个人设置奇特的处置惩罚事宜:

var A = document.getElementById("A");
var B = document.getElementById("B");
var C = document.getElementById("C");

A.onclick = function() {
    去园区大门取快递;
}
B.onclick = function() {
    去楼下取快递;
}
C.onclick = function() {
    去本层大厅取快递;
}

最少须要三次DOM操纵,而且为每一个对应节点都设置了事宜函数。

而若采纳事宜托付:


var aUl = document.getElementByID("前台工作人员");
aUl.onclick = function (ev) {
    var target = ev.target || ev.srcElement; /*兼容浏览器*/
    if (target.nodeName.toLocaleLowerCase() == "li") {
        switch(target.id) {
            case "A" :
                去园区大门取快递;
                break;
            case "B" :
                去楼下取快递;
                break;
            case "C" :
                去本层大厅取快递;
                break;
        }
    }
}

如许一来,DOM操纵就只有一次,其他的操纵都在JS内举行,能够有用提拔网页机能。

以上就是JS事宜托付的基本头脑。简而言之,就是应用事宜冒泡这一特性,来对事宜举行治理,削减冗余代码,削减不必要的建立,削减交互操纵以勤俭内存和进步机能。

事宜冒泡

事宜冒泡是当触发某个DOM元素节点时,若该节点没有对应事宜,则搜检其父元素是不是有对应事宜,如有,则实行,若没有,继承向上搜检。与其对应的另有事宜捕捉。

关于事宜流的具体分析,将在今后的文章中总结。

    原文作者:bmwz110
    原文地址: https://segmentfault.com/a/1190000018513639
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞