javascript和jq的事件委托

今天在公司,有个需求是,通过ajax动态查询数据,回来,再添加到一个ul的li元素中,例如(点击生成 li 模拟,加载数据生成相应的数据, 事件: 点击):

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
    <button>create</button>
    <ul id="parent">
        <li class="son-1">Item 1</li>
        <li class="son-2">Item 2</li>
    </ul>
    <script>
        $(function () {
            $('button').on('click', function (e) {
                $('#parent').append('<li>add</li>')
            });
        });
    </script>
</body>
</html>

平时自己的添加事件:

$('#parent li').on('click', function (e) {
    alert('这是第' + $(this).index() + 'li');
});

这样子可以为,dom元素中已经经过渲染的li元素绑定事件,如果点击 craete按钮新生成的li元素,由于,事件绑定的js已经执行完毕,所以无法对新生成的li进行事件的绑定。一开始,在没有用jq的事件委托,自己简单的粗暴的对新生的元素,再一次动态绑定:

//在生成新生元素后, 再次执行这段 函数 ,绑定需要的事件。
$('#parent li').on('click', function (e) {
    alert('这是第' + $(this).index() + 'li');
});

明显是很挫的做法,不仅不易维护,而且性能也大打折扣,因为这样虽然会为新的元素绑定到事件,但是已经存在的元素也会再次绑。

jq提供的事件委托,可以很有效的解决这种问题。delegate 和 on 都提供了相应的方法

$('#parent').delegate('li', 'click', function(event) {
    console.log($(this))
});
$('#parent').on('click', 'li', function (e) {
    console.log($(this))
});

这两个函数均可提供相应的效果,个人更倾向于使用 on :

下面是从jq的api copy过来的使用文档:

on(events,[selector],[data],fn)

概述

在选择元素上绑定一个或多个事件的事件处理函数。

on()方法绑定事件处理程序到当前选定的jQuery对象中的元素。在jQuery 1.7中,.on()方法 提供绑定事件处理程序所需的所有功能。帮助从旧的jQuery事件方法转换,see .bind(), .delegate(), 和 .live(). 要删除的.on()绑定的事件,请参阅.off()。要附加一个事件,只运行一次,然后删除自己, 请参阅.one()

参数

events,[selector],[data],fnV1.7

events:一个或多个用空格分隔的事件类型和可选的命名空间,如"click"或"keydown.myPlugin" 。

selector:一个选择器字符串用于过滤器的触发事件的选择器元素的后代。如果选择的< null或省略,当它到达选定的元素,事件总是触发。

data:当一个事件被触发时要传递event.data给事件处理函数。

fn:该事件被触发时执行的函数。 false 值也可以做一个函数的简写,返回false。

events-map,[selector],[data]V1.7

events-map:个用字符串表示的,一个或多个空格分隔的事件类型和可选的命名空间,值表示事件绑定的处理函数。

selector:一个选择器字符串过滤选定的元素,该选择器的后裔元素将调用处理程序。如果选择是空或被忽略,当它到达选定的元素,事件总是触发。

data:当一个事件被触发时要传递event.data给事件处理函数。


javascript也有原生的事件委托

DEMO:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <input type="button" id="btn" />
    <ul id="ul">
      <li>aaaaaaaa</li>
      <li>bbbbbbbb</li>
      <li>cccccccc</li>
    </ul>
    <script>
        window.onload = function(){
          var oUl = document.getElementById("ul");
          var aLi = oUl.getElementsByTagName("li");
          var oBtn = document.getElementById("btn");
          var iNow = 4;

          oUl.onmouseover = function(ev){
            var ev = ev || window.event;
            var target = ev.target || ev.srcElement;
            if(target.nodeName.toLowerCase() == "li"){
                alert('触发了')
            }
          }
          oUl.onmouseout = function(ev){
            var ev = ev || window.event;
            var target = ev.target || ev.srcElement;
            if(target.nodeName.toLowerCase() == "li"){
               alert('触发了')
            }
          }
          oBtn.onclick = function(){
            iNow ++;
            var oLi = document.createElement("li");
            oLi.innerHTML = iNow;
            oUl.appendChild(oLi);
          }
        }
    </script>
</body>
</html>

从原生的js中可以看出:事件委托是通过,事件的冒泡。实现的。通过子元素的点击事件,冒泡到父元素,父元素再通过event的内容判断 为该元素触发相应的事件, 在demo中的,获取对应的 tagName 判断子元素 是不是 li。是的话触发对应的事件,从而 达到事件的委托。

你可能感兴趣的:(js事件委托)