0

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

4

1 回答 1

4

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

它没有被重置,它从未被设置


问题

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

含义,在函数内部,this._x = x;window._x = x;. myClick._x永远不会改变。
稍后当您调用 时mouseClick.display()this该函数内部会引用mouseClick并提醒初始值。

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

MDN 解释this得非常好quirksmode.org 根据事件处理程序进行了解释


解决方案

您可以将处理程序显式绑定到mouseClick使用.bind [MDN]

window.addEventListener("mouseup", mouseClick.handler.bind(mouseClick), false);

或者传递一个函数,该函数依次调用mouseClick.handler

window.addEventListener("mouseup", function(event) {
    mouseClick.handler(event);
}, false);
于 2013-01-04T18:08:29.800 回答