(javascript)为什么我需要为事件处理程序使用wrap函数?
我试图理解为什么在下面的代码中我需要Dragger.prototype.wrap,以及为什么我不能直接使用事件处理方法:(javascript)为什么我需要为事件处理程序使用wrap函数?,javascript,closures,event-handling,wrap-function,Javascript,Closures,Event Handling,Wrap Function,我试图理解为什么在下面的代码中我需要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 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;
}
有人告诉我这是因为
这个
没有它会改变,但我不明白为什么这个
会改变,为什么wrap函数会阻止它改变,以及没有wrap函数这个会变成什么。你需要包装它们,因为当函数被用作事件处理程序时,this
关键字引用触发事件的DOM元素,如果不包装它,则无法访问Dragger
对象的实例成员,如this.isMouseDown
例如:
假设您有一个按钮:
<input type="button" id="buttonId" value="Click me" />
如果你打电话:
obj.method();
您将看到一个警报,其文本包含在obj
对象(“我是对象成员”)的value
成员中
如果将obj.method
函数用作事件处理程序:
document.getElementById('buttonId').onclick = obj.method;
当用户单击该按钮时,它将提示“单击我”
为什么??
因为当触发click事件时,obj.method
将在this
关键字指向DOM元素的情况下执行,并且它将发出“click me”警报,因为该按钮包含一个值
成员
您可以检查上面运行的代码段
对于上下文强制,我总是关闭一个函数:
// 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
的对象,其余可选参数是包装函数enter code在此调用的参数
在按钮示例中,我们可以将其用作:
document.getElementById('buttonId').onclick = obj.method.bind(obj);
它在很多情况下都非常有用,它将作为ECMAScript 5的一部分介绍。关于此
在不同上下文中的值。但作为旁注,如果您不使用库或使用没有此类工具的库,您可以使用以下一个方便的函数来概括Dragger.wrap
(类似于dojo.hitch
)的效果:
var lockContext = function(context, callback) {
return function() {
callback.apply(context, arguments);
}
};
对不起,你能详细说明一下吗?我不明白。啊,所以区别在于“this”将引用DOM对象本身,而不是处理程序(因此我无法访问类似的内容。isMouseDown,因为a没有isMouseDown,但我的类Dragger有?@hatorade:没错,你明白了。正是因为闭包,对象中声明的方法才得到了对象“this”,因为它保留了生成它的环境?我认为看到对象文字而不是实例化对象可能会让人困惑。你的标题暗示了一个与问题内容不同的问题。您想知道关于事件处理程序、给定范围内的
this
的值,还是prototype
的类定义?
var lockContext = function(context, callback) {
return function() {
callback.apply(context, arguments);
}
};