我已经制作了一个JS对象,有一些原型函数,并且在构造函数中调用它们很好,使用它。[function]
但是在后来的事件处理函数中,这是指元素,而不是对象,我不知道如何解决这个问题:
通过AddListener很好,鼠标按下事件触发,导致enable / disableDragging正常工作。但是在该函数中,“this”是元素,而不是dragger对象,因此我无法调用WindowCenter,DraggingBool或Add / RemoveListener事件。
从阅读起,看起来我可能需要实现prototype.bind?但不确定如何重新安排我现有的代码来执行此操作。或者我是否更改其中一个函数以返回函数?
是的,我知道我可以在jQuery中执行此操作,多次完成,只是试着看看我是否可以使用POJS:)
Dragger = function(element, draggingElement) {
this.Element = element;
this.DraggingElement = element;
this.WindowCenter;
this.DraggingBool = false;
this.AddListener(this.DraggingElement, "mousedown", this.enableDragging);
this.AddListener(this.DraggingElement, "mouseup", this.disableDragging);
}
Dragger.prototype.AddListener = function (element, eventType, listener, bubble) {
if (typeof (element) != "object" || typeof (listener) != "function")
return;
if (typeof (bubble) == "undefined")
var bubble = false;
eventType = eventType.toLowerCase();
if (eventType.substr(0, 2) == "on")
eventType = eventType.substr(2);
if (window.addEventListener) { // Mozilla, Netscape, Firefox
element.addEventListener(eventType, listener, bubble);
} else if (window.attachEvent) { // IE
element.attachEvent("on" + eventType, listener);
}
}
Dragger.prototype.RemoveListener = function (element, eventType, listener) {
eventType = eventType.toLowerCase();
if (eventType.substr(0, 2) == "on")
eventType = eventType.substr(2);
if (window.addEventListener) { // Mozilla, Netscape, Firefox
element.removeEventListener(eventType, listener, false);
} else if (window.attachEvent) { // IE
element.detachEvent("on" + eventType, listener);
}
}
Dragger.prototype.enableDragging = function (e) {
if (!e) var e = window.event;
//dont move for right click
if (e.which && e.which == 3)
return;
else if (e.button && e.button == 2)
return;
this.DraggingBool = true;
this.WindowCenter = new Point(e.pageX, e.pageY);
this.AddListener(document.body, "mouseover", this.mouseMoveListener);
}
Dragger.prototype.disableDragging = function () {
this.DraggingBool = false;
this.RemoveListener(document.body, "mouseover", this.mouseMoveListener);
}
Dragger.prototype.mouseMoveListener = function (e) {
if (!this.DraggingBool)
return;
if (!e) var e = window.event;
e.preventDefault();
var newLoc = new Point(e.pageX, e.pageY);
var xDif = windowCenter.X - newLoc.X;
var yDif = windowCenter.Y - newLoc.Y;
this.Element.style.left = (this.Element.offsetLeft + xDif) + "px";
this.Element.style.top = (this.Element.offsetTop + yDif) + "px";
this.WindowCenter = newLoc;
}
答案 0 :(得分:2)
这是因为在使用addEventListener
时,执行范围设置为节点,就像您使用了node.onclick = foo
一样。在IE中使用attachEvent
时,执行范围将成为全局执行范围,即窗口。
解决此问题的一种方法是使用Function.call或Function.apply来指定您喜欢的执行范围。许多库将声明一个绑定函数来帮助解决这个问题,例如:
function bind(fn, context) {
return function() {
return fn.apply(context, arguments);
};
}
this.AddListener(this.DraggingElement, "mousedown",
bind(this.enableDragging, this));
您还可以向AddListener函数添加上下文参数,并在那里进行绑定。
Ecmascript 5有一个内置绑定方法。
答案 1 :(得分:0)
Function.prototype.bind = function () {
if (arguments.length < 2 && arguments[0] === undefined) {
return this;
}
var thisObj = this,
args = Array.prototype.slice.call(arguments),
obj = args.shift();
return function () {
return thisObj.apply(obj, args.concat(Array.prototype.slice.call(arguments)));
};
};
Function.bind = function() {
var args = Array.prototype.slice.call(arguments);
return Function.prototype.bind.apply(args.shift(), args);
}
Dragger = function(element, draggingElement) {
this.Element = element;
this.DraggingElement = element;
this.WindowCenter;
this.DraggingBool = false;
this.AddListener(this.DraggingElement, "mousedown", this.enableDragging,this);
this.AddListener(this.DraggingElement, "mouseup", this.disableDragging,this);
}
Dragger.prototype.AddListener = function (element, eventType, listener, bubble,dragger_obj) {
if (typeof (element) != "object" || typeof (listener) != "function")
return;
if (typeof (bubble) == "undefined")
var bubble = false;
eventType = eventType.toLowerCase();
if (eventType.substr(0, 2) == "on")
eventType = eventType.substr(2);
if (window.addEventListener) { // Mozilla, Netscape, Firefox
element.addEventListener(eventType, listener.bind(dragger_obj), bubble);
} else if (window.attachEvent) { // IE
element.attachEvent("on" + eventType, listener.bind(dragger_obj));
}
}
Dragger.prototype.RemoveListener = function (element, eventType, listener,dragger_obj) {
eventType = eventType.toLowerCase();
if (eventType.substr(0, 2) == "on")
eventType = eventType.substr(2);
if (window.addEventListener) { // Mozilla, Netscape, Firefox
element.removeEventListener(eventType, listener.bind(dragger_obj), false);
} else if (window.attachEvent) { // IE
element.detachEvent("on" + eventType, listener.bind(dragger_obj));
}
}
Dragger.prototype.enableDragging = function (e) {
if (!e) var e = window.event;
//dont move for right click
if (e.which && e.which == 3)
return;
else if (e.button && e.button == 2)
return;
this.DraggingBool = true;
this.WindowCenter = new Point(e.pageX, e.pageY);
this.AddListener(document.body, "mouseover", this.mouseMoveListener,this);
}
Dragger.prototype.disableDragging = function () {
this.DraggingBool = false;
this.RemoveListener(document.body, "mouseover", this.mouseMoveListener,this);
}
Dragger.prototype.mouseMoveListener = function (e) {
if (!this.DraggingBool)
return;
if (!e) var e = window.event;
e.preventDefault();
var newLoc = new Point(e.pageX, e.pageY);
var xDif = windowCenter.X - newLoc.X;
var yDif = windowCenter.Y - newLoc.Y;
this.Element.style.left = (this.Element.offsetLeft + xDif) + "px";
this.Element.style.top = (this.Element.offsetTop + yDif) + "px";
this.WindowCenter = newLoc;
}