使用常规的 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 片段,特别是不要从动态连接在一起的字符串构造片段。