在 FireFox 扩展中动态插入新菜单
Insert new menu dynamically in a FireFox extension
我正在尝试使用我的扩展在主菜单栏上插入一个新菜单。我知道如何使用XUL覆盖来做到这一点,但它需要通过JavaScript插入。此代码应创建一个名为"新建"的新菜单,其中包含单个"新选项卡"选项。 alert(doc);
显示[object XMLDocument]
,但我的新菜单不会显示。
var xmlString = '<menu id="new-menu" label="New" accesskey="N">'+
'<menupopup id="menu_NewPopup">'+
'<menuitem id="menu_newNavigatorTab" label="New Tab" command="cmd_newNavigatorTab" key="key_newNavigatorTab" accesskey="T"/>'+
'</menupopup>'+
'</menu>';
var parser = new DOMParser();
var doc = parser.parseFromString(xmlString, "text/xml");
document.getElementById('main-menubar').appendChild(doc);
使用常规的 DOM API。
首先,找出正确的父节点。在browser.xul
,这通常是以下之一:
-
#mainPopupSet
- 全新菜单 -
#menu_ToolsPopup
- "工具"菜单 -
#contentAreaContextMenu
- 内容的主上下文菜单
对于其他菜单,请自己跟踪 id(例如,使用 DOM 检查器,或读取 chrome://browser/content/browser.xul 源)。在你自己的窗户里,反正你自己最了解。
然后你可以动态地构建你的菜单内容,比如
var parent = document.getElementById("<parent from step 1>");
var menu = document.createElement("menu"); // in a XUL window, the XUL namespace is already implied.
menu.setAttribute("id", "my-extension-menu"); // Use sane names that are unlikely to clash with other ids in the window.
menu.setAttribute("label", "My Item");
var item = document.createElement("menuitem");
item.setAttribute("label", "My Item");
item.addEventListener("command", function item_click(e) {
alert("clicked");
}, false);
menu.appendChild(item);
parent.appendChild(menu); // Or insertBefore()
在XUL覆盖中,对popupshowing
事件做出反应通常很常见,只根据需要构建/更新菜单。还有一个popuphidden
活动。
document.getElementById("contentAreaContextMenu")
.addEventListener("popupshowing", function construct_or_update(e) {
// Construct menu, if first time, else update as necessary
}, true);
这通常与存根覆盖结合使用:
<!-- ... xml preamble, doctype, etc. -->
<overlay id="my-extension-overlay">
<popup id="contentAreaContextMenu">
<menu id="my-extension-menu">
<menupopup id="my-extension-menupopup"/>
</menu>
</popup>
</overlay>
然后有这样的东西:
document.getElementById("my-extension-menu")
.addEventListener("popupshowing", function construct_or_update(e) {
var mp = document.getElementById("my-extension-menupopup");
// Remove cruft from last time.
while (mp.lastChild) {
mp.removeChild(mp.lastChild);
}
// Create new menu items
}, true);
如果您只有一组静态菜单项,并且想要根据上下文或其他内容显示或隐藏您的项,只需设置元素上的.hidden
属性即可。这比一次又一次地构建整个子 DOM 要高效得多。
document.getElementById("contentAreaContextMenu")
.addEventListener("popupshowing", function update_menuitems(e) {
var item = document.getElementById("my-extension-item");
item.hidden = someCondition;
}, true);
PS:请勿使用DOMParser
。如果你真的觉得你必须做这样的事情,把它放在一个文件中,XMLHttpRequest.responseXML
文档。然后,您可以根据需要.importNode()
和.appendChild()
/.insertBefore()
。但是,如果您可以使用叠加层,则不建议这样做。但是,对于无法使用覆盖的引导(无需重启)扩展,它可能可行。
永远不要从字符串构造 DOM 片段,特别是不要从动态连接在一起的字符串构造片段。
- 下拉菜单在菜单按钮的边缘闪闪发光
- react:菜单+子菜单+内容
- HTML5上下文菜单-当菜单项被点击时,访问最初被点击的元素
- WordPress切换菜单 - 使菜单在当前页面上保持打开状态
- 如何创建响应菜单(汉堡菜单)
- 如果我使用 JQuery $(window).click(function() 关闭菜单,菜单的墨水不起作用
- 有没有办法在 css 中设计一个看起来完全是 html 下拉菜单的菜单
- 子菜单 100% 菜单宽度
- 在 FireFox 扩展中动态插入新菜单
- Kendo UI网格单元格中的工具栏菜单,菜单是从哪个行单击的
- 将鼠标悬停在父菜单或菜单上时,保持弹出菜单处于打开状态
- JS菜单保持菜单状态
- 手风琴菜单扩展-菜单更改
- 滑动切换垂直菜单:子菜单不起作用
- 如何:居中水平菜单&子菜单
- Android菜单/子菜单-菜单'Title"不需要执行任何活动…当前刷新webview
- css上的子菜单悬停菜单问题
- 新手菜单/子菜单问题
- 基于用户隐藏/显示新菜单'的选择
- 在打开新菜单之前关闭页面上的其他菜单