delegate

Module

Methods

event.delegate()
void delegate ( selector , eventType , filter , fn [ , scope ] )
为符合匹配的 dom 节点的相应事件添加事件处理器, 并在该节点的子孙节点中匹配 filter 的节点上触发事件时调用.
Parameters:
  • selector (string|HTMLCollection|Array<HTMLElement>) – 字符串表示 css3 选择器
  • eventType (string) – 包含一个或多个事件名称的字符串, 多个事件名以空格分开
  • filter (string) – 可参见 dom.filter() 的 filter 参数
  • fn (function(eventObject)) – 当事件触发时的回调函数
  • scope (object) – 回调函数的 this 值. 如果不指定默认为绑定事件的当前元素

该方法是 on 方法的增强. 当 on 方法被调用时, 符合选择器的元素被绑定事件处理器, 而后面添加的元素则没有, 即他们需要另外一次绑定, 例如

<body>
  <div class="clickme">
    Click here
  </div>
</body>

绑定一个 click 事件的事件触发器:

Event.on('.clickme','click', function() {
  // Bound handler called.
});

当该元素被点击时, 调用对应的事件处理器. 但是如果新加入一个元素:

KISSY.Node.all('body').append('<div class="clickme">Another target</div>');

新元素匹配选择器 clickme ,但是他如果不再次 on , 则在他上面的点击不会有任何效果.

delegate 方法提供了解决方法, 如果这样调用:

Event.delegate(document,'click','.clickme',function(){
   // Bound handler called.
});

这样的话如果今后又添加了一个元素

KISSY.Node.all('body').append('<div class="clickme">Another target</div>');

在新元素上点击仍然会调用之前的事件处理器.

可以使用 undelegate 来移除之前的绑定:

function d(){
}

Event.delegate(document,'click','.clickme',d);

Event.undelegate(document,'click','.clickme',d);

Note

不能在 object , embed , applet 元素上注册事件. 事件处理器回调函数中 this 指向 scope (没指定指向绑定事件的元素), 传入的参数为 event , event.target 指向事件触发源, event.currentTarget 指向当前事件处理器调用所在的匹配 filter 的元素. 可以使用 stopPropagation() 来停止事件的向上冒泡, 这样就不会在同样符合 filter 条件的祖先节点上调用事件处理器.

Note

因为 delegate 是在事件冒泡到代理元素后才开始处理的,那么通过 on 注册到代理元素的子节点的事件处理器已经被触发, 而无法被 delegate 绑定的事件处理器阻止 ( stopPropagation ),但 delegate 事件处理器可以阻止绑定到同一元素但是匹配元素在当前事件处理器之上的 delegate 事件处理器.

Note

同样可以对 mouseenter , mouseleave 进行委托.

Demo

委托实现点击通知

<!DOCTYPE html>
<html>
<head>
    <style>

        button {
            margin: 10px;
        }

        div {
            color: blue;
            font-weight: bold;
        }

        span {
            color: red;
        }
    </style>

    <script src="//g.alicdn.com/kissy/k/1.4.7/seed.js" data-config="{combine:true}"></script>
</head>
<body>
<div class='out' id='i4'>
    <div class='inner' id='i3'>
        <div class='inner' id='i1'>
            <button id='click_button'>click me</button>
        </div>
    </div>
</div>
<div id='log'></div>
<script>
    KISSY.use('core', function (S) {
        var $ = KISSY.Node.all;

        $('#i4').delegate('click', '.inner', function (e) {
            var target = e.target, currentTarget = e.currentTarget;
            $('#log').prepend("<div style='margin:5px;'>invoked : <br/> this.id=" + this.id + "<br/>event.target.id=" +
                    target.id + "<br>event.currentTarget.id=" + currentTarget.id + "</div>");
        });
    });
</script>

</body>
</html>

也可以阻止事件向上冒泡

<!DOCTYPE html>
<html>
<head>
    <style>

        button {
            margin: 10px;
        }

        div {
            color: blue;
            font-weight: bold;
        }

        span {
            color: red;
        }
    </style>

    <script src="//g.alicdn.com/kissy/k/1.4.7/seed.js" data-config="{combine:true}"></script>
</head>
<body>
<div class='out' id='i4'>
    <div class='inner' id='i3'>
        <div class='inner' id='i1'>
            <button id='click_button'>click me</button>
        </div>
    </div>
</div>
<div id='log'></div>
<script>
    KISSY.use('core', function (S) {
        var $ = KISSY.Node.all;

        $('#i4').delegate('click', '.inner', function (e) {
            var target = e.target, currentTarget = e.currentTarget;
            $('#log').prepend("<div style='margin:5px;'>invoked : <br/> this.id=" + this.id + "<br/>event.target.id=" +
                    target.id + "<br>event.currentTarget.id=" + currentTarget.id + "</div>");
            e.stopPropagation();
        });
    });
</script>

</body>
</html>

委托 mouseenter/mouseleave

<!DOCTYPE html>
<html>
<head>
    <style>

        button {
            margin: 10px;
        }

        div {
            color: blue;
            font-weight: bold;
        }

        span {
            color: red;
        }
    </style>

    <script src="//g.alicdn.com/kissy/k/1.4.7/seed.js" data-config="{combine:true}"></script>
</head>
<body>
<div class='out' id='i4' style='width:300px;height:300px;border:1px solid green;'>
    i4
    <div class='inner' id='i3' style='width:200px;height:200px;border:1px solid red;margin:50px;'>
        #i3.inner
        <div class='inner' id='i1' style='width:100px;height:100px;border:1px solid black;margin:50px;'>
            #i1.inner : try mouse
        </div>
    </div>
</div>
<hr/>
<div id='log'></div>
<script>
    KISSY.use('core', function (S) {
        var $ = KISSY.Node.all;
        $('#i4').delegate('mouseenter mouseleave click', '.inner', function (e) {
            $('#log').prepend(e.type + " : " + e.currentTarget.id + "<br/>");
        });
    });
</script>

</body>
</html>