可想實現一個自己的簡單jQuery庫?(九)

二哲發表於2015-11-22

Lesson-8


事件機制

在講事件機制之前呢,我們有一個很重要的東西要先講,那就是如何實現事件委託(代理).

只有必須先明白瞭如何實現一個事件委託,我們才能更好的去實現on和off.在我看來,on和off裡最難實現的就是他的事件委託.

function delegate(agent,type,selector,fn) {
    agent.addEventListener(type,function(e) {

        var target = e.target;
        var ctarget = e.currentTarget;
        var bubble = true;

        while(bubble && target != ctarget) {
            if(filiter(agent,selector,target)) {
                bubble = fn.call(target,e);
            }
            target = target.parentNode;
            return bubble;
        }
    },false);
    function filiter(agent,selector,target) {
        var nodes = agent.querySelectorAll(selector);
        for (var i = 0; i < nodes.length; i++) {
            if (nodes[i] == target) {
                return true;
            }
        }
    }
}

以上是我對整個委託的實現,當然在這隻做了非常簡單的實現,沒有對很多別的情況進行判斷,也沒有多個引數是否捕捉.

我們先拆解下分析.

function filiter(agent,selector,target) {
    var nodes = agent.querySelectorAll(selector);
    for (var i = 0; i < nodes.length; i++) {
        if (nodes[i] == target) {
            return true;
        }
    }
}

先看這個方法,這其實就是一個元素過濾,作用就是為了過濾出我們委託的元素具體是誰.target就是我們具體的委託元素

agent.addEventListener(type,function(e) {

    var target = e.target;
    var ctarget = e.currentTarget;
    var bubble = true; //是否阻止冒泡

    while(bubble && target != ctarget) {
        if(filiter(agent,selector,target)) {
            bubble = fn.call(target,e);
        }
        target = target.parentNode;
        return bubble;
    }
},false);

然後是我們的主要部分.其實這裡就很簡單,while的條件判斷兩個,第一個是是否阻止冒泡,第二個判斷是冒泡是否到頂.

接著我們進行filiter進行過濾,如果返回true,則是我們的委託元素,直接call即可.

如果不做過多的相容處理,實現一個委託還是比較容易的.

PS:如果您還是不太明白,可以來這看更具體的解釋.http://www.meckodo.com/?p=309

您的star是檢驗程式碼的唯一標準!:)

github地址: https://github.com/MeCKodo/forchange/tree/master/lesson-8
可想實現一個自己的簡單jQuery庫?(八):http://segmentfault.com/a/1190000004025152

相關文章