我有一个上下文菜单项,如果右击图像,它就会被激活,与'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