zoukankan      html  css  js  c++  java
  • javascript之事件委托(转)

    事件委托

    转:http://www.html-js.com/article/1824

    在JavaScript里,通常要做的一件事是绑定事件,比如用户在页面的点击、滚动等,然后执行注册的回调函数,这样就响应了用户的某种行为。简单的例子如下:

    $('button').on('click', function() {
        alert('hello');
    });
    

    在用户每次点击页面上的按钮时,弹出一个对话框显示‘hello’。 在有些情况下,我们期望页面上的一些元素响应用户同样的动作,举个例子。在用户点击列表的每一项时,将其内容显示在div#data-show里。

    <ul id="data-list">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        …
        <li>100</li>
    </ul>
    <div id="data-show"></div>
    

      

    可以这么做:

    $('#data-list li').on('click', function() {
        $('#data-show').html($(this).html());
    });
    

      

    其实是给列表的每一项(100个)分别绑定了点击事件。这样做的弊端在于,增加了内存,因为$(’#data-list li’)里有100个li对象。同时降低了代码性能,因为$(’#data-list li’)会搜索ul#data-list下所有的li元素。

    在满足需求的情况下,怎么做更好呢?

    答案是使用事件委托!

    $('#data-list').on('click', 'li', function() {
        $('#data-show').html($(this).html());
    });
    

      

    将li元素的点击事件委托给其父元素ul。这么做之所以行得通,是因为事件具有冒泡的特点,当内层元素的某个事件被触发,事件会一级一级冒泡到更外层元素。当外层元素被绑定事件且被触发时,判断事件的来源即event.target是否是目标元素li,如果是就执行回调。上面的代码等价于:

    function showText(text) {
        $('#data-show').html(text);
    }
    
    $('#data-list').on('click', function(event) {
        var $target = $(event.target);
        if ($target.is('li')) {
            showText($target.html());
        }
    });
    

      

    除了提高性能和节省内存的好处外,事件委托的另一个好处在于,页面动态变化后,不需要重新检索元素和绑定事件。上例中,如果通过AJAX向列表增加新项,新添加项仍能响应用户点击。

    利用事件委托实现事件在HTML页面中的可配置

    可能存在这样的需求,页面上的多个元素(不同的),会响应同样的用户行为,比如一个按钮和一个链接,均须响应同样的行为。这种case还有可能存在页面之间。举个例子。

    Page 1:

    <button class="primary">See more</button>
    <a class="secondary">See details</link>
    Page 2:
    
    <input type="button" class="third" value="Check more"/>
    

      

    JS代码势必会这样:

    $('.primary').add('.secondary').add('.third').on('click', callback);
    

      

    如果又有其他元素也要响应同样的行为,需要修改以上JS代码,而使其变得更长。是否有更好的方式?看下面这个例子。

    JS code:

    var events = (function() {
        var list = {};
    
        return {
            on: function(actionName, fn) {
                if (!(typeof actionName === 'string' && typeof fn === 'function')) {
                    throw new Error('Invalid args');
                }
    
                list[actionName] = fn;
            },
    
            trigger: function(actionName, data) {
                var callback = list[actionName];
                callback && callback.call(null, data);
            }
        };
    }());
    
    $(document).on('click', '.delegated-action', function(event) {
        var $el = $(this), actionName = $el.data('actionName');
        if (!actionName) {
            return;
        }
    
        var evt = {
            $event: event,
            $self: $el,
            data: $el.data('actionData')
        };
        events.trigger(actionName, evt);
    });
    
    function showIndex(event) {
        alert(event.data.index);
    }
    
    events.on('see-more', showIndex);
    

      

    这个例子中,将所有含有样式类delegated-action的元素上的点击事件委托给了document。对象events存储用户通过events.on定义的所有动作和回调。在页面中,只要给元素加上属性class=”delegated-action”和data-action-name=”see-more”,该元素就能响应用户的点击动作了。若需要给回调传入数据,可以将数据以JSON的形式绑定在data-action-data属性上,而不需要修改JS代码。

    HTML code:

    <a class="delegated-action" href="javascript:" data-action-name="see-more" data-action-data='{"index": 1}'>See more</a>
    
    <button class="delegated-action" data-action-name="see-more" data-action-data='{"index": 2}'>See more</button>
    
    <input class="delegated-action" type="button" data-action-name="see-more" data-action-data='{"index": 3}' value="See more"/>
    

      

    这种方式很适合页面上通用组件或行为,而不用关心元素的类型、ID、命名等,只需要在HTML里添加指定的样式类,定义data-action-name和data-action-data属性即可。文章只拿click事件来描述例子,读者有兴趣可以扩展到代码以适合其他事件。

    清风徐来,水波不兴
  • 相关阅读:
    Spring Boot下的一种导入Excel文件的代码框架
    Spring Boot下的一种导出CSV文件的代码框架
    Spring Boot下的一种导出Excel文件的代码框架
    使用系统参数表,提升系统的灵活性
    折纸效果! Cocos Creator 3.0
    弹性跟随相机!3D入门教程!
    dotnet OpenXML 读取 PPT 主序列进入退出强调动画
    dotnet C# 调用委托的 GetInvocationList 的对象分配
    WPF 下拉框选项做鼠标 Hover 预览效果
    WPF 后台代码做 TranslateTransform 的动画
  • 原文地址:https://www.cnblogs.com/it-xiaojun/p/6086806.html
Copyright © 2011-2022 走看看