利用 Firefox 的默认/内置事件侦听器



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

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

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


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

我也和Dagger聊天,他说:

…内置项的状态不是由事件处理程序设置的,而是由从nsContextMenu的构造函数中设置,没有挂钩到它的机制

看来,这是不可能的

不,没有相同的方法来避免事件侦听器,这种方法可以比另一个事件侦听器执行得更好,并且与在会话中卸载附加组件兼容。

挂接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=。是啊,这可能行得通……除了其他附加组件可能有相同的想法,所以欢迎来到兼容性地狱。这也涉及到把东西推到窗口,这会导致跨隔间的包装,这使得事情再次容易出错。

这是一个解决方案吗?也许吧,但不是一个相同的

还有什么?

没什么,真的。

这绝对是可能的。mozillazine的Morat给出了一个很好的解决方案: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

相关内容

  • 没有找到相关文章

最新更新