为什么每次点击我的工具栏按钮时我的javascript都会变得不确定?

时间:2013-01-04 18:05:04

标签: javascript javascript-events firefox-addon

我正在尝试创建一个简单的扩展,每次单击一个按钮时都会提醒鼠标单击(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对象都会重置?

1 个答案:

答案 0 :(得分:4)

  

为什么每次点击扩展程序的按钮时,我的mouseClick对象都会重置?

未重置,从未设置


问题

在事件处理程序中,this引用window,而不引用mouseClick。处理程序不在对象的上下文中调用,因为您直接将其绑定到window

意思是,在函数内部,this._x = x;window._x = x;相同。 myClick._x永远不会改变 稍后当您致电mouseClick.display()时,该功能内的this会引用mouseClick并提醒初始值。

一个函数就像任何其他值一样。将其分配给对象的属性并不会将其神奇地绑定到该对象。 this引用的内容是在函数调用时确定的,而不是在创建函数时确定的。

MDN explains this very wellquirksmode.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);