JavaScript 基础(001_Event Delegation)

Event Delegation(事件委托):简而言之,依赖于事件冒泡机制,当我们对 DOM 中的某个元素添加事件的时候,我们可以将事件添加到它的父节点上,即将事件委托给父节点,由父节点来处理事件的响应。

示例代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Event Delegation</title>
    </head>
    <body>
        <div id="container">
            <ul id="list">
                <li><a href="#">Item #1</a></li>
                <li><a href="#">Item #2</a></li>
                <li><a href="#">Item #3</a></li>
                <li><a href="#">Item #4</a></li>
            </ul>
        </div>
        <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                // 对列表中的<a>元素添加事件
                $("#list a").on("click", function(event) {
                    console.log($(this).text());
                });
            });
        </script>
    </body>
</html>

事件委托

如图所示,当我们单击列表中的每一项(<li>元素)时,都会触发点击事件并在 console 中打印出相应信息。现在,我们新增一项(<li>元素)到列表中,测试新增元素的事件是否能够正常触发:

$("#list").append( "<li><a href='#'>Item #5</a></li>" );

事件委托

可以看到,新增元素的事件没有被正常触发,这是因为新增<li>元素的代码晚于事件注册的代码执行。在某些情况下,我们可能会对列表中的<li>元素进行频繁的新增、删除操作,那么以上示例代码中对<a>元素的事件注册方式就显得不合理。现在,我们修改以上示例代码,如下所示:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Event Delegation</title>
        </head>
    <body>
        <div id="container">
            <ul id="list">
                <li><a href="#">Item #1</a></li>
                <li><a href="#">Item #2</a></li>
                <li><a href="#">Item #3</a></li>
                <li><a href="#">Item #4</a></li>
            </ul>
        </div>
        <script src="js/jQuery/jquery-3.1.0.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                // 创建委托事件,即我们将事件注册在父元素<ul>上,将事件目标设置为<a>元素               
                $("#list").on("click", "a", function(event) {
                    console.log($(this).text());
                });
                // 新增<li>元素         
                $("#list").append("<li><a href='#'>Item #5</a></li>");
            });
        </script>
    </body>
</html>

事件委托
经过测试,列表中的每一项(<li>元素)的事件都被正常触发并显示相应信息。在单击列表中的每一项(<li>元素)时,正真的事件源是<a>元素,依赖于事件冒泡机制,单击事件会被上传到每一层父节点,事件传播顺序如下所示:

<a>
<li>
<ul #list>
<div #container>
<body>
<html>
document root

以上示例代码引入了 jQuery 代码库,现在贴出原汁原味版:

<!-- 缺陷代码 -->
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Event Delegation</title>
    </head>
    <body>
        <div id="container">
            <ul id="list">
                <li><a href="#">Item #1</a></li>
                <li><a href="#">Item #2</a></li>
                <li><a href="#">Item #3</a></li>
                <li><a href="#">Item #4</a></li>
            </ul>
        </div>
        <script type="text/javascript">
            window.onload = function() {
                var ul = document.getElementById("list");
                var arr = ul.getElementsByTagName("a");
                for (var i = 0, l = arr.length; i < l; i++) {
                    arr[i].onclick = function eventHandler() {
                        console.log(this.textContent);
                    };
                }
            }
        </script>
    </body>
</html>
<!-- 改进代码 -->
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Event Delegation</title>
    </head>
    <body>
        <div id="container">
            <ul id="list">
                <li><a href="#">Item #1</a></li>
                <li><a href="#">Item #2</a></li>
                <li><a href="#">Item #3</a></li>
                <li><a href="#">Item #4</a></li>
            </ul>
        </div>
        <script type="text/javascript">
            window.onload = function() {
                // 事件委托,即我们将click事件添加在<ul>元素上,再通过相应判断获得事件源
                document.getElementById("list").addEventListener("click", function(e) {
                     if(e.target && e.target.nodeName.toLowerCase() == "a") {
                        console.log(e.target.text);
                     }
                });
            }
        </script>
    </body>
</html>

参考网址:
http://learn.jquery.com/events/event-delegation/
https://www.w3.org/TR/DOM-Level-2-Events/events.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值