簡體   English   中英

(javascript)為什么我需要為事件處理程序使用wrap函數?

[英](javascript) why do i need to use a wrap function for event handlers?

我試圖理解為什么在下面的代碼中我需要Dragger.prototype.wrap以及為什么我不能直接使用事件處理方法:

function Dragger(id) {
    this.isMouseDown = false;
    this.element = document.getElementById(id);
    this.element.onmousedown = this.wrap(this, "mouseDown");
}

Dragger.prototype.wrap = function(obj, method) {
    return function(event) {
        obj[method](event);
    }
}

Dragger.prototype.mouseDown = function(event) {
    this.oldMoveHandler = document.body.onmousemove;
    document.onmousemove = this.wrap(this, "mouseMove");
    this.oldUpHandler = document.body.onmousemove;
    document.onmouseup = this.wrap(this, "mouseUp");
    this.oldX = event.clientX;
    this.oldY = event.clientY;
    this.isMouseDown = true;
}

Dragger.prototype.mouseMove = function(event) {
    if (!this.isMouseDown) {
        return;
    }
    this.element.style.left = (this.element.offsetLeft
            + (event.clientX - this.oldX)) + "px";
    this.element.style.top = (this.element.offsetTop
            + (event.clientY - this.oldY)) + "px";
    this.oldX = event.clientX;
    this.oldY = event.clientY;
}

Dragger.prototype.mouseUp = function(event) {
    this.isMouseDown = false;
    document.onmousemove = this.oldMoveHandler;
    document.onmouseup = this.oldUpHandler;
}

有人告訴我,那是因為this改變沒有它,但我不明白為什么this變化,為什么包裝功能阻止它改變,什么this將改變以沒有包裝的功能。

你需要包裝它們,因為當一個函數被用作事件處理程序時, this關鍵字引用觸發事件的DOM元素,如果你不包裝它,你就無法訪問你的實例成員Dragger對象,如this.isMouseDown

例如:

假設您有一個按鈕:

<input type="button" id="buttonId" value="Click me" />

你有以下對象:

var obj = {
  value: 'I am an object member',
  method: function () {
    alert(this.value);
  }
}

如果你打電話:

obj.method();

您將看到一個警報,其中包含obj對象的value成員中包含的文本( '我是對象成員' )。

如果使用obj.method函數作為事件處理程序:

document.getElementById('buttonId').onclick = obj.method;

當用戶點擊按鈕時,它會提示“點擊我”

為什么? 因為當觸發click事件時,將使用指向DOM元素的this關鍵字執行obj.method ,並且它將提示“Click me”,因為該按鈕包含value成員。

您可以檢查上面的片斷跑這里


對於上下文實施,我總是保持關閉綁定功能:

// The .bind method from Prototype.js
if (!Function.prototype.bind) {
  Function.prototype.bind = function(){
    var fn = this, args = Array.prototype.slice.call(arguments),
             object = args.shift();
    return function(){
      return fn.apply(object,
        args.concat(Array.prototype.slice.call(arguments)));
    };
  };
}

它允許您包裝任何函數,強制執行上下文。 作為第一個參數,它接收將用作this對象的對象,其余的可選參數是將在此處調用包裝的函數中心代碼的對象。

在按鈕示例中,我們可以將其用作:

document.getElementById('buttonId').onclick = obj.method.bind(obj);

它在很多情況下都非常有用,它將作為ECMAScript 5的一部分引入。

CMS給了一個很好的答案有關的值this在不同的語境。 但是作為旁注,這里有一個方便的函數,你可以使用它來概括Dragger.wrap (類似於dojo.hitch )的效果,如果你沒有使用庫或者使用沒有這樣的庫的庫工具:

var lockContext = function(context, callback) {
    return function() {
        callback.apply(context, arguments);
    }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM