向後相容的DOM事件綁定

來源:互聯網
上載者:User

主要內容:
addEventListener綁定方式的問題:
document.body.addEventListener( 'click',
    function() {
        alert('body clicked');
    },false);

以及第二個參數為object的優勢:
document.body.addEventListener('click',
    {
        handleEvent: function() {
            alert('body clicked');
        }
    },
    false);

原文廢話太多,我只翻譯了主要部分。
具體細節,請自行查看
本文
先簡短的看一下各個瀏覽器提供的DOM元素事件綁定介面:
//IE使用element.attachEvent:
document.body.attachEvent(
    'onclick',
    function() {
        alert('body clicked');
    });
//其他瀏覽器使用element.addEventListener:
document.body.addEventListener(
    'click',
    function() {
        alert('body clicked');
    },
    false);

一般來說上面的第二個參數都是傳入一個函數控制代碼,但是大多數javascript程式員並不知道第二個參數可以傳入一對象obj【DOM2介面http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener】,如此一來,當event執行的時候,會隱式的調用obj的handleEvent方法。
document.body.addEventListener(
    'click',
    {
        handleEvent: function() {
            alert('body clicked');
        }
    },
    false);

這麼做的一個重要方面是obj的handleEvent只有在執行的時候才需要去訪問【有點類似延遲綁定的效果】。同時,如果在兩次event事件間隔中,handleEvent發生了改變,那麼產生的效果會跟著改變。這樣一個好處就是不用remove事件而直接切換事件。
看下面的例子:
document.body.addEventListener('click', obj, false);
// click body will error in some browsers because
// 現在還沒有事件
obj.handleEvent = function() {alert('alpha');};

// 單擊彈出alpha
obj.handleEvent = function() {alert('beta');};

// 單擊彈出"beta"
document.body.removeEventListener('click', obj, false);
//單擊什麼都沒有了

【注意,這個用法存在一定的相容性問題。不過我現在只面向手機瀏覽器,所以請自行測試】
跨瀏覽器的事件綁定
對於事件綁定,各種庫都會處理相容問題,統一API,大都類似:
LIB_addEventListener(
    document.body,
    'click',
    function() {
        alert('body clicked');
    });

個人實現的一個:
//一個封裝
    function LIB_addEventListener(el,type,fn){
        el.addEventListener(type,fn,false);
    }
    function ViewObject() {
        this.data = 'alpha';
        LIB_addEventListener(document.body,'click',this.handleClick);
    }
    ViewObject.prototype.handleClick = function() {
        console.log(this.data);
    };
    var test = new ViewObject();//單擊彈出undefined

我們期望彈出‘alpha’,但是this指向window,彈出的是undefined;
解決方式,有的庫添加了第四個參數,用來制定上下文:
    function LIB_addEventListener(el,type,fn,obj){
        el.addEventListener(type,fn.bind(obj),false);
    }
    function ViewObject() {
        this.data = 'alpha';
        LIB_addEventListener(document.body,'click',this.handleClick,this);
    }
    ViewObject.prototype.handleClick = function() {
        console.log(this.data);
    };
    var test = new ViewObject();

此時我們彈出來‘alpha’
這種方式的問題:listener在綁定的時候就已經固定了,於是問題就又來了。
    function LIB_addEventListener(el,type,fn,obj){
        el.addEventListener(type,fn.bind(obj),false);
    }
    function ViewObject() {
        this.data = 'alpha';
        LIB_addEventListener(document.body,'click',this.handleClick,this);
    }
    ViewObject.prototype.handleClick = function() {
        console.log(this.data);
    };
    var test = new ViewObject();
    test.handleClick = function(){
        console.log('new fn');//單擊彈出的依舊是alpha。我們希望的是new fn
    }

採用obj的綁定形式:
    function LIB_addEventListener(el,type,obj){
        el.addEventListener(type,obj,false);
    }
    function ViewObject() {
        this.data = 'alpha';
        LIB_addEventListener(document.body, 'click', this);
        LIB_addEventListener(document.body, 'mousemove', this);
    }
    ViewObject.prototype.handleEvent = function(e) {
            if('click' == e.type){
                console.log(this.data)
            }else{
                console.log('not click')
            }
        };

    var test = new ViewObject();

上面的例子我改了一下,但是可以說明問題。這樣的靈活性也高一些。

 

摘自  西山

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.