[英]jQuery / JavaScript, why do I need to wrap variables in $() to use them?
[英](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.