亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 1566 | 回復(fù): 0
打印 上一主題 下一主題

綁定DOM事件到對(duì)象 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2011-12-19 14:02 |只看該作者 |倒序?yàn)g覽
在上一篇Blog 《舍去jQuery,面向M編程,而不是面向V編程》中,在面向?qū)ο缶幊痰睦又行枰壎ㄊ录綄?duì)象的方法上,而不是綁定到全局方法上。在這一篇里,我們可以繼續(xù)延續(xù)這個(gè)話題,以完善事件綁定機(jī)制。
  我們想要達(dá)到的目標(biāo)是,一個(gè)對(duì)象已經(jīng)封裝了事件處理的邏輯,而我們知道對(duì)象本身是不能捕獲事件的,只有DOM元素可以捕獲事件,如何動(dòng)態(tài)地綁定DOM事件的處理句柄到對(duì)象實(shí)例上。看下面的代碼:

var Button = function(id){
    this.div = document.createElement("div");
    this.div.id = id;

    this.onClick = function(){
        alert(this.div.id); // 這里的this是div,而不是我們想要的Button實(shí)例

    };

    this.div.onclick = this.onClick;

};


代碼的意圖很明顯,div上的onclick由Button對(duì)象的onClick方法來(lái)處理,但我們會(huì)發(fā)現(xiàn),其實(shí)這樣工作是有問(wèn)題的,this.onClick方法里的this其實(shí)在事件處理階段是指向div的,而不是我們想當(dāng)然的Button實(shí)例。如何讓this指向Button實(shí)例呢?我們提到一個(gè)技巧, 擴(kuò)展JavaScript的Function原型:

Function.prototype.bind = function(context){
    var _method = this;
    return function(e) {
        var array = [e || window.event];
        return _method.apply(context, array);
    };
};


為一個(gè)方法綁定執(zhí)行的上下文,這樣就為將this指定到Button實(shí)例提供了可能,上面Button的例子可以改為:

Function.prototype.bind = function(context){
    var _method = this;
    return function(e) {
        var array = [e || window.event];
        return _method.apply(context, array);
    };
};

var Button = function(id){
    this.div = document.createElement("div");
    this.div.id = id;

    this.onClick = function(e){
        alert(this.div.id); // 這時(shí)this是指向Button實(shí)例的

    };

    this.div.onclick = this.onClick.bind(this);
};


這樣雖然可以工作了,但還不完美,如果我們需要在處理事件時(shí)有多個(gè)處理句柄,并且還能隨時(shí)移除事件句柄,那上面的方法還需要改進(jìn),就是加入attachEvent和detachEvent了。

Function.prototype.bind = function(context){
    var _method = this;
    return function(e) {
        var array = [e || window.event];
        return _method.apply(context, array);
    };
};
/**
 * Attach event listener to a DOM object
 *
 * @param domObj
 * @param evType, for example "click", "load" etc
 * @param thi$, the context of handler
 * @param handler, event handler
 */

$attachEvent = function(domObj, evType, thi$, handler){
    var _handler = handler.bind(thi$);

    if(domObj.addEventListener){
        domObj.addEventListener(evType, _handler, false);
    }else{
        domObj.attachEvent("on"+evType, _handler);
    }

    return _handler;
};

/**
 * Detach event listener from a DOM object
 *
 * @see J$VM.attachEvent(domObj, evType, thi$, handler)
 */

$detachEvent = function(domObj, evType, thi$, handler){
    if(domObj.removeEventListener){
        domObj.removeEventListener(evType, handler, false);
    }else{
        domObj.detachEvent("on"+evType, handler);
    }
};
var Button = function(id){
    this.div = document.createElement("div");
    this.div.id = id;

    this.onClick = function(e){
        alert(this.div.id); // 這時(shí)this是指向Button實(shí)例的


        // 假設(shè)在這個(gè)邏輯中我們需要移除事件句柄,但其實(shí)這一句也是不如我們預(yù)期的。

       $detachEvent(this.div, "click", this, this.onClick);
    };

    $attachEvent(this.div, "click", this, this.onClick);
};


引入這兩個(gè)方法后,再看Button的例子,好像完美了,但實(shí)際上,detachEvent(this.div, "click", this, this.onClick)這一句并不如我們預(yù)期的那樣工作,因?yàn),在attachEvent內(nèi)部,我們attach的實(shí)際上是bind方法返回的方法,而不是this.onClick,所以detachEvent時(shí),并不能找到這個(gè)this.onClick。我們還需要繼續(xù)改造bind方法和detachEvent方法。

Function.prototype.bind = function(context){
    var _method = this;
    _method.__handler__ = function(e) {
        // 在_method里暗藏一個(gè)真實(shí)的綁定句柄

        var array = [e || window.event];
        return _method.apply(context, array);
    };
    return _method.__handler__;
};

$detachEvent = function(domObj, evType, thi$, handler){
    var _handler = handler.__handler__ || handler; // 取出__handler__


    if(domObj.removeEventListener){
        domObj.removeEventListener(evType, _handler, false);
    }else{
        domObj.detachEvent("on"+evType, _handler);
    }
};


到這里,我們的事件綁定機(jī)制基本上完美了,最后附上一段完整的代碼:

(function(){
window.J$VM = {};

Function.prototype.bind = function(context){
    var _method = this;
    _method.__handler__ = function(e) {
        var array = [e || window.event];
        return _method.apply(context, array);
    };
    return _method.__handler__;
};

/**
 * Attach event listener to a DOM object
 *
 * @param domObj
 * @param evType, for example "click", "load" etc
 * @param thi$, the context of handler
 * @param handler, event handler
 */

J$VM.attachEvent = function(domObj, evType, thi$, handler){
    var _handler = handler.bind(thisObj);

    if(domObj.addEventListener){
        domObj.addEventListener(evType, _handler, false);
    }else{
        domObj.attachEvent("on"+evType, _handler);
    }

    return _handler;
};

/**
 * Detach event listener from a DOM object
 *
 * @see J$VM.attachEvent(domObj, evType, thi$, handler)
 */

J$VM.detachEvent = function(domObj, evType, thi$, handler){
    var _handler = handler.__handler__ || handler;

    if(domObj.removeEventListener){
        domObj.removeEventListener(evType, _handler, false);
    }else{
        domObj.detachEvent("on"+evType, _handler);
    }
};

/**
 * Cancel event bubble
 */

J$VM.cancelBubble = function(e){
    if(e.stopPropagation){
        e.stopPropagation();
    }else{
        window.event.cancelBubble = true;
    }
};

})();


您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP