我正在尝试创建一个简单的扩展,每次单击一个按钮时都会提醒鼠标单击(mouseup)坐标。 (学习尝试)
扩展工作正常,设置正确,除了一个小故障。
我的XUL文件:
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin/" ?>
<?xml-stylesheet type="text/css"
href="chrome://mouseclick/skin/mouseclick.css" ?>
<!DOCTYPE overlay SYSTEM
"chrome://mouseclick/locale/mouseclick.dtd">
<overlay id = "overlay-id" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript"
src="chrome://mouseclick/content/mouseclick.js" />
<toolbarpalette id="BrowserToolbarPalette">
<toolbarbutton id="mouseclick-button" class="mouseclick-class"
label="&button.label;" tooltiptext="&tooltip.text;"
oncommand = "mouseClick.display();"/>
</toolbarpalette>
<toolbar id="nav-bar">
<toolbarbutton id="mouseclick-button" class="mouseclick-class"
label="&button.label;" tooltiptext="&tooltip.text;"
oncommand = "mouseClick.display();"/>
</toolbar>
</overlay>
我的JS文件:
if(mouseClick === undefined) {
var mouseClick = {
_x : "not yet clicked" ,
_y : "not yet clicked"
};
}
mouseClick.handler = function(e) {
var x = e.pageX !== undefined ? e.pageX : e.clientX;
var y = e.pageY !== undefined ? e.pageY : e.clientY;
/*A TEST ALERT
alert("(" + x + ", " + y + ")"); // a dummy command for testing
*/
this._x = x;
this._y = y;
};
mouseClick.display = function() {
alert("(" + this._x + ", " + this._y + ")");
};
window.addEventListener("mouseup", mouseClick.handler, false);
问题是,当我单击文档中的任何位置或窗口中除扩展按钮之外的任何位置时, TEST警告命令会提醒正确的坐标。
然而,当我点击我的按钮时,(再次触发警报命令), 第一个 TEST警告返回正确的坐标。
但主要提醒,提醒(not yet clicked, not yet clicked)
。
为什么每次点击我的扩展程序按钮时,我的mouseClick
对象都会重置?
答案 0 :(得分:4)
为什么每次点击扩展程序的按钮时,我的mouseClick对象都会重置?
未重置,从未设置。
问题
在事件处理程序中,this
引用window
,而不引用mouseClick
。处理程序不在对象的上下文中调用,因为您直接将其绑定到window
。
意思是,在函数内部,this._x = x;
与window._x = x;
相同。 myClick._x
永远不会改变
稍后当您致电mouseClick.display()
时,该功能内的this
会引用mouseClick
并提醒初始值。
一个函数就像任何其他值一样。将其分配给对象的属性并不会将其神奇地绑定到该对象。 this
引用的内容是在函数调用时确定的,而不是在创建函数时确定的。
MDN explains this
very well和quirksmode.org explains it in the light of event handlers。
解决方案
您可以使用.bind
[MDN]
mouseClick
window.addEventListener("mouseup", mouseClick.handler.bind(mouseClick), false);
或者传递一个函数,该函数又调用mouseClick.handler
:
window.addEventListener("mouseup", function(event) {
mouseClick.handler(event);
}, false);