委托模式:合作愉快

前言

委托模式就是把本该自己要做的事叫别人替你做,对于你自己来说是好事(至少不用自己去做),但对于别人来说很有可能是一件坏事(别人也有自己的事要忙),委托模式在  JavaScript 程序中就有点不一样,即使原理跟前面解析是一样的,便效果却是皆大欢喜。为什么这么说,我们不妨往下看。

委托模式之旅

委托模式在我们平时的开发中也很实用,比如我们有一个菜单,假设菜单的数量很多,点击每个菜单都会跳转到对应的页面,如果在源生 JavaScript 中我们通常都是遍历所有的菜单元素,逐一给每个菜单元素绑定一个点击事件。有多少个菜单就得添加多少个点击事件,可以想象这是一事多少糟糕的事件。不管是从代码的美观上还是从性能上分析都有足够的理由让我们对它进行必要的优化。我们不妨看看下面这样简单的示例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>委托模式</title>
</head>

<body>
    <ul id="menu">
        <li>首页</li>
        <li>HTML5</li>
        <li>CSS3</li>
        <li>JavaScript</li>
        <li>Node.js</li>
        <li>Linux</li>
        <li>jQuery</li>
        <li>数据库</li>
    </ul>
    <script>
(function(){
    var oldTarget = null;
    var menuBox = document.getElementById("menu");
    menuBox.onclick = function (e) {
        if(oldTarget){ // 上次点击元素存在,则先清空其背景
            oldTarget.style.background = "none";
        } 
        // IE浏览器 e.srcElement;
        // 其它主流浏览器 e.target
        var target = e.target || e.srcElement;
        target.style.background = "#ccc";
        oldTarget = target;
    }
})();
    </script>
</body>

</html>

上面这个示例就是一个简单版的多菜单场景,示例中菜单只是为了说明问题,所以我们也没必要添加那么多菜单,能够把问题说明白就好。

心细你的可能已经发现了上面的代码已经是优化过的代码。我们直接把点击事件添加到 ul 上,li 上一个点击事件都不用加。

如果你运行上面的代码就会得到预期的效果。

为什么我们可以这么做呢?

其实我们可以这么做得益于 JavaScript 中的事件冒泡行为,简单说下,所谓的事件冒泡就是当你点击了一个元素后,父元素上的同类型事件也会被触发(如果有的话)。

而如果我们需要传参的话,就可以通过 event 事件中目标元素上的属性获取到。当然,我们需要为每一个 li 添加一些独有的属性来实现传参。

这样我们实现后,我们就收获了至少一个好处:不用遍历元素,逐一绑定事件,节省了系统资源,提高了程序的性能。