0

我有一个上下文菜单项,如果右键单击图像,它就会被激活,与激活的方式完全相同'context-copyimage'

是否可以将该菜单项绑定/配对,'context-copyimage'从而消除添加额外(重复)事件侦听器和显示/隐藏处理程序的需要??!!
(添加观察者会'context-copyimage'破坏目的)

如果没有,是否可以使用使用的事件侦听'context-copyimage'器?

更新:
我正在尝试减少听众。目前,脚本有一个popupshowing听众。On popupshowing,它检查是否为gContextMenu.onImag真,如果为真,则显示菜单项。Firefox 的context-copyimage做法完全相同。我想知道是否有可能将这两个绑定以删除/减少脚本内事件侦听器。

我也在和Dagger聊天,他说:

...内置项目的状态不是从事件处理程序中设置的,而是从 nsContextMenu 的构造函数中设置的,并且没有任何机制可以挂钩

看来,这是不可能的

4

2 回答 2

3

不,没有明智的方法可以避免事件侦听器的性能优于另一个事件侦听器,并且与在会话中卸载加载项兼容。

挂钩nsContextMenu

正如您已经被告知的,状态是通过初始化的gContextMenu = new nsContextMenu(...)。所以你需要钩住这些东西,这实际上很容易。

var newProto = Object.create(nsContextMenu.prototype);
newProto.initMenuOriginal = nsContextMenu.prototype.initMenu;
newProto.initMenu = function() {
    let rv = this.initMenuOriginal.apply(this, arguments);
    console.log("ctx", this.onImage, this); // Or whatever code you'd like to run.
    return rv;
};
nsContextMenu.prototype = newProto;

现在,第一个问题是:它实际上表现更好吗?毕竟这只是在原型链中引入了另一个链接。当然,可以避免Object.create并直接覆盖nsContextMenu.prototype.initMenu

但真正的问题是:如何再次移除钩子?回答:你真的不能,因为其他插件可能在你之后钩住了同样的东西,而解钩也会解钩其他插件。但是您需要摆脱引用,否则加载项在禁用/卸载时会泄漏内存。好吧,您可以使用Components.utils.makeObjectPropsNormal,但这对封闭变量并没有真正的帮助。所以让我们避免闭包...嗯...您需要某种消息传递,例如事件侦听器或观察器...我们回到第一个问题。

另外

document.getElementById("contentAreaContextMenu").addEventListener(...)

我将其称为“为没有可衡量的利益而过度杀戮”。

覆盖onpopupshowing=

可以覆盖<menupopup onpopupshowing=. 是的,这可能会飞......除了其他附加组件可能有相同的想法,所以欢迎来到兼容性地狱。此外,这再次涉及将东西推入窗口,这会导致跨隔间包装,这会使事情再次容易出错。

这是一个解决方案吗?也许,但不是一个理智的人。

还有什么?

不多,真的。

于 2014-07-11T09:57:09.433 回答
1

是的,这是绝对可能的。mozillazine 的莫拉特在这里给出了一个很好的解决方案:http://forums.mozillazine.org/viewtopic.php?p=13307339&sid=0700480c573017c00f6e99b74854b0b2# p13307339

function handleClick(event) {
  window.removeEventListener("click", handleClick, true);
  event.preventDefault();
  event.stopPropagation();
  var node = document.popupNode;
  document.popupNode = event.originalTarget;
  var menuPopup = document.getElementById("contentAreaContextMenu");
  var shiftKey = false;
  gContextMenu = new nsContextMenu(menuPopup, shiftKey);
  if (gContextMenu.onImage) {
    var imgurl = gContextMenu.mediaURL || gContextMenu.imageURL;
  }
  else if (gContextMenu.hasBGImage && !gContextMenu.isTextSelected) {
    var imgurl = gContextMenu.bgImageURL;
  }
  console.log('imgurl = ', imgurl)
  document.popupNode = node;
  gContextMenu = null;
}
window.addEventListener("click", handleClick, true);

这使您可以访问gContextMenu具有各种属性的属性,例如您是否通过链接,或者您是否右键单击图像,以及是否gContextMenu.imageURL保留了它的价值。很酷的东西

此处的代码控制台日志imgurl,如果您没有通过图像,它将记录undefined

于 2014-07-11T09:33:05.887 回答