我正在尝试在没有jquery的情况下重写jquery插件,我无法弄清楚为什么当我使用.bind()时事件不会在函数中更新参数。我已将问题简化为以下内容:
function IMdraw(div) {
this.div = div
this.div.addEventListener('mousedown', this.mousedown.bind(this));
}
IMdraw.prototype = {
onMouseMove: function (fn) {
this.moveHandler = fn;
this.div.addEventListener('mousemove', this.moveHandler, false);
},
move1: function(e, arg) {
console.log('move1')
console.log(e.offsetX);
console.log(e.offsetY);
},
move2: function(e) {
console.log('move2')
console.log(e.offsetX);
console.log(e.offsetY);
},
mousedown: function(e) {
var arg = 3;
this.onMouseMove(this.move1.bind(this));
this.onMouseMove(this.move2.bind(this, e, arg));
},
}
var obj = new IMdraw(document.querySelector('div'));

<div style="width:500px; height:500px; background: blue;">
</div>
&#13;
正如您在单击蓝色div并在div中移动光标时所看到的那样,在move2函数中,offsetX和offsetY不会更新,但会在move1函数中更新。
有没有解释为什么它会这样?我相信我正在使用.bind()。
答案 0 :(得分:0)
问题是您的bind
调用干扰了事件对象到事件回调函数的自动传递。
move1
,您没有传递任何内容,因此e
正确指向
自动传递给事件的mousemove
事件
回调函数。 arg
未通过arg
,因此move1
(undefined
}内部将为move2
。e
,您通过传递自己的参数来干扰事件对象的自动传递。您是mousedown
参数
传递是来自mousemove
事件的事件对象,而不是arg
事件
在move2
发生时更新,因此您始终可以看到点击鼠标时的偏移量。您确实已将arg
传递给fun.bind(thisArg[, arg1[, arg2[, ...]]])
,并且可以使用。解决方案是根本不传递事件对象,让它像往常一样自动传递,只传递你需要的任何额外数据(在你的情况下为addEventListener
),但是参数您通过的将是该案件在此案件中收到的第一批案件,该事件将是最后一天(与通常情况相反)。
FROM MDN :
语法:
onmousemove
<强>参数强>
<强> thisArg 强>
作为this参数传递给目标函数的值 当调用绑定函数时。如果绑定,则忽略该值 函数是使用new运算符构造的。
arg1,arg2,...
prepend 的参数提供给绑定函数的参数 在调用目标函数时。
这是一个有效的解决方案。我做了一些小的调整,以便您使用function IMdraw(div) {
this.div = div;
this.div.addEventListener('mousedown', this.mousedown.bind(this));
}
IMdraw.prototype = {
onMouseMove: function (fn) {
this.div.addEventListener('mousemove', fn);
},
move1: function(arg, e) {
console.log('move1');
console.log(e.offsetX, "Passed argument: " + arg);
console.log(e.offsetY, "Passed argument: " + arg);
},
move2: function(arg, e) {
console.log('move2');
console.log(e.offsetX, "Passed argument: " + arg);
console.log(e.offsetY, "Passed argument: " + arg);
},
mousedown: function(e) {
console.log(this.div);
var arg = 3;
// The e argument represents the mousedown event that was fired. It only happens
// once, when you click the mouse. It won't happen again when you move the mouse
// so the values associated with it don't change on move1 and move2.
// Instead, don't pass the event object at all (let that happen organically as it
// normally does) and pass just the extra data you want to pass. This extra argument
// will be the FIRST argument recieved by the bound function and the event will be
// the SECOND.
this.div.addEventListener("mousemove", this.move1.bind(this, arg));
this.div.addEventListener("mousemove", this.move2.bind(this, arg));
}
}
var obj = new IMdraw(document.querySelector('div'));
而不是<div style="width:500px; height:500px; background: blue;">
</div>
,这是更现代和基于标准的。
let mainMenu() = ["1. list item one",itemOne
"2. list item two",itemTwo
"3. list item three",itemThree
"4. list item four",itemFour
"0. Exit",exitApplication]
|> Map.ofList
mainMenu()
|> Seq.iter(fun keyValuePair ->
Console.WriteLine (sprintf "%s" (keyValuePair.Key |> string)))