【问题标题】:Link add-on SDK panel to toolbar button将附加 SDK 面板链接到工具栏按钮
【发布时间】:2014-03-05 08:32:34
【问题描述】:

插件 SDK 将面板附加到小部件,如 here 所示。我想用工具栏按钮使用附加 SDK 来实现相同的效果。

我使用的工具栏按钮是type menu-button,这意味着左侧是一个图标并且有一个oncommand 监听器。右侧是一个下拉箭头,单击时显示其内容。以下是使用附加 SDK 创建此类按钮的代码:

const doc = require('sdk/window/utils').getMostRecentBrowserWindow().document;

var navBar = doc.getElementById('nav-bar')
var btn = doc.createElement('toolbarbutton');
btn.setAttribute('id', 'hylytit');
btn.setAttribute('type', 'menu-button');
btn.setAttribute('class', 'toolbarbutton-1');
btn.setAttribute('image', data.url('resources/hylyt_off.png'));
btn.setAttribute('orient', 'horizontal');
btn.setAttribute('label', 'Hylyt.it');
btn.addEventListener('command', function(event) {
  if (event.button===0) btnClick();
  console.log(TAG+'button clicked');
}, false);
var panel = doc.createElement('panel');
panel.setAttribute('id', 'search-panel');
panel.addEventListener('command', function(event) {
    console.log(TAG+'dropdown clicked');
}, false);
var label = doc.createElement('label');
label.setAttribute('control', 'name');
label.setAttribute('value', 'Article List');
var textbox = doc.createElement('textbox');
textbox.setAttribute('id', 'name');
panel.appendChild(label);
panel.appendChild(textbox);
btn.appendChild(panel);
navBar.appendChild(btn);

上面的panel 不是一个附加的SDK 面板,它是一个XUL panel 并且受到严重限制,因为它不能用CSS 设置样式。最重要的是,尽管btnonCommand 按预期触发,但面板的onCommand 侦听器永远不会触发。 XUL 面板会在我单击下拉按钮时显示(只要它有子按钮),但由于我无法访问其单击处理程序,因此我不能仅在单击时创建附加 SDK 面板。

所以我的问题是这样的。有没有办法访问工具栏按钮的菜单部分的点击处理程序,或者有没有办法将附加 SDK 面板附加为工具栏按钮的子项?

【问题讨论】:

    标签: javascript firefox-addon firefox-addon-sdk


    【解决方案1】:

    感谢您为我指明箭头面板的方向。有没有办法将 HTML 文件放在一个文件中,而不必动态创建 XUL 元素?我试图达到的效果类似于 Pocket 扩展,它在单击按钮部分时做一件事,在单击箭头时做另一件事。 – willlma 7 小时前

    你有 900 多个代表,你应该知道得更好。创建另一个问题主题而不是在评论中询问如何做不同的事情是常识,尤其是在解决方案接受之后。

    尽管如此,这就是完成 Pocket 工具栏按钮效果的方法。基于上述贡献者提供的代码。 再问一个问题,我会把它移到那里,你可以在那里接受我的解决方案。

    var doc = document;
    
    var navBar = doc.getElementById('nav-bar')
    var btn = doc.createElement('toolbarbutton');
    btn.setAttribute('id', 'hylytit');
    btn.setAttribute('type', 'menu-button');
    btn.setAttribute('class', 'toolbarbutton-1');
    btn.setAttribute('image', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowMjgwMTE3NDA3MjA2ODExODcxRjlGMzUzNEZGQkNGQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxRUM5MTQ0MkJFNkUxMUUxOUM3NzgwMzc3MDc2Rjk1MCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxRUM5MTQ0MUJFNkUxMUUxOUM3NzgwMzc3MDc2Rjk1MCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDI4MDExNzQwNzIwNjgxMTg3MUZFQTk0QUU4RTMwMEYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDI4MDExNzQwNzIwNjgxMTg3MUY5RjM1MzRGRkJDRkIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5kJv/fAAAByUlEQVR42qRTPWvCYBC+mKiolFYURVSwfoCLkw4iGDM5WoO460/o4tKuHToV+gd0t5Ku4mQWJ8Fd/NhEpy6K3+ldakKsi+ALb3hzd89zd8+9L6MoCtyyOPpkMpl3m81WM5lMV4GOxyOsVqu3Xq/3qhIEg8Ga1+sFs9l8FcFut4P5fP6Cxz8CAvt8PmBZ9iqCw+Ggn9WaKTOB9/s9FAoF4Hn+LIjOZCMfxVGrWrWcFkRiWiwWiMfjIv6GOI77kGUZ1us15PN5SKVSz2ifttvtL2yBPRNRI1gsFiCK4pMkSVUE/GBrn5vN5i4ajVYxpFEsFuuRSIR1u91wQcAwDOAkwOl0VjBjCIFit9sdoOshl8sNsLp6IBCoOBwOME5LJSABqU8i8Pv91Kcwm83kdDrNk9/lcslYTYLi7HY7aBidIJvNTjqdziNpQBmIBDVIoFDT05TuPR6PCqbs2+0WBEGYqJWfbmKx2WxKo9FIDSAbtgDL5VLNQqRWq1Vtky4R6gDlcpnE/mYMV7nearUqw+FQJzEuDRyLxaBUKjXQVDVWoJNgFZV+vw/j8VgXi4DhcBiSySRl18H6+P5tAbekXC7p5DuLZ259jb8CDAAxmdyX9iaHkQAAAABJRU5ErkJggg==');
    btn.setAttribute('orient', 'horizontal');
    btn.setAttribute('label', 'Hylyt.it');
    ////
    var toolbarbuttonPanel = doc.createElement('panel');
    toolbarbuttonPanel.setAttribute('id', 'toolbarbutton-panel');
    toolbarbuttonPanel.setAttribute('type', 'arrow');
    var toolbarbuttonLabel = doc.createElement('label');
    toolbarbuttonLabel.setAttribute('value', 'toolbarbutton panel');
    toolbarbuttonPanel.appendChild(toolbarbuttonLabel);
    ////
    ////
    var dropmarkerPanel = doc.createElement('panel');
    dropmarkerPanel.setAttribute('id', 'dropmarker-panel');
    dropmarkerPanel.setAttribute('type', 'arrow');
    var dropmarkerLabel = doc.createElement('label');
    dropmarkerLabel.setAttribute('value', 'dropmarker panel');
    dropmarkerPanel.appendChild(dropmarkerLabel);
    ////
    
    navBar.appendChild(btn);
    
    var mainPopupSet = document.querySelector('#mainPopupSet');
    mainPopupSet.appendChild(dropmarkerPanel);
    mainPopupSet.appendChild(toolbarbuttonPanel);
    
    btn.addEventListener('click',function(event) {
        console.log('event.originalTarget',event.originalTarget);
        if (event.originalTarget.nodeName == 'toolbarbutton') {
            dropmarkerPanel.openPopup(btn);
        } else if (event.originalTarget.nodeName == 'xul:toolbarbutton') {
            toolbarbuttonPanel.openPopup(btn);
        }
    }, false);
    

    【讨论】:

    • 在他对 iframe 发表评论后,我将答案标记为正确,这与附加 SDK 面板非常相似,我认为它是原始问题的解决方案。如果我将 iframe 设为面板的子级,则尽管无法访问单击侦听器,但它会在单击时显示。也就是说,您的解决方案更好,因为现在我有两个单独的点击事件,当它们发生时我可以做任何我想做的事情。我将在这里接受这个答案,因为apparently it isn't frowned upon。非常感谢。
    • 附加 iframe 是您问题的解决方案吗?不,“附加 iframe”显然没有回答您的问题……改变答案不是,而是撒谎。您的问题中没有提到您想要一个双面板工具栏按钮。我的解决方案是在您的评论中回答您的问题……您接受了评论中提出的问题的答案……这非常令人不悦。从中学习一些常见的 SO 礼仪。
    • 当然可以。如果我在单击菜单按钮时想要一个附加的 sdk 面板(类似于可以加载 HTML 文件的 XUL 面板),那么 add an iframe as a child to panel 是一个不错的选择回答。他把panel.openPopup(btn) 放在事件侦听器中搞砸了,但是如果您删除该行并向面板添加一个 iframe,那么您将获得所需的行为:两次单独单击,其中一次显示带有 HTML 附加到工具栏的面板-按钮。
    • 至于您的编辑,我不想要两个面板,但谁在乎呢?您向我和将来访问此页面的每个人展示了一种在单击按钮时做一件事,在单击菜单时做另一件事的方法。这解决了我的问题。我现在将使用if (event.originalTarget.nodeName == 'toolbarbutton') 执行与面板无关的特定功能,并使用else if (event.originalTarget.nodeName == 'xul:toolbarbutton') 显示附加SDK 面板。您的回答帮助我毫无困难地解决了我原来的问题,所以我不明白为什么这是违反礼仪的。所以去感谢你自己吧。
    • 大声笑,你需要冷静,你会接受你的错误。不明白怎么回事别说别人乱了,看看openPopups在哪里。很高兴看到 Firefox 插件开发。也很高兴看到新用户给老用户上了一堂礼仪课。布拉格的道具绝对值得我再次投赞成票。我已经编辑了这个主题,以便将来人们可以通过“双/双功能工具栏按钮”来引用它
    【解决方案2】:

    面板没有 onCommand 方法见MDN - Panels Article

    你可以让你的面板风格化,给它输入像panel.setAttribute('type', 'arrow')这样的箭头,然后附加到你的按钮上。我没有在下面给它键入箭头。

    这是工作代码。复制粘贴到暂存器并设置环境>浏览器然后运行它。

    var doc = document; //to put this back in sdk do const doc = require('sdk/window/utils').getMostRecentBrowserWindow().document;
    
    var navBar = doc.getElementById('nav-bar')
    var btn = doc.createElement('toolbarbutton');
    btn.setAttribute('id', 'hylytit');
    btn.setAttribute('type', 'menu-button');
    btn.setAttribute('class', 'toolbarbutton-1');
    btn.setAttribute('image', ''); //i made this image blank because i dont have the image and im running from scratchpad
    btn.setAttribute('orient', 'horizontal');
    btn.setAttribute('label', 'Hylyt.it');
    
    var panel = doc.createElement('panel');
    
    btn.addEventListener('command', function(event) { //moved this below var panel = doc.createElement because panel needs to be crated before we write this function
      //if (event.button===0) btnClick();
      //console.log(TAG+'button clicked'); //what is TAG? its undefeined for me
        panel.openPopup(btn);
    }, false);
    
    panel.setAttribute('id', 'search-panel');
    /*
    panel.addEventListener('command', function(event) {
        console.log(TAG+'dropdown clicked'); //what is TAG? its undefeined for me
    }, false);
    */
    var label = doc.createElement('label');
    label.setAttribute('control', 'name');
    label.setAttribute('value', 'Article List');
    var textbox = doc.createElement('textbox');
    textbox.setAttribute('id', 'name');
    panel.appendChild(label);
    panel.appendChild(textbox);
    btn.appendChild(panel);
    navBar.appendChild(btn);
    

    【讨论】:

    • 感谢您向我指出箭头面板的方向。有没有办法将 HTML 文件放在一个文件中,而不必动态创建 XUL 元素?我想要达到的效果类似于Pocket扩展,当点击按钮部分时做一件事,当点击箭头时做另一件事。
    • 是的,将 iframe 附加到面板并设置 iframe src
    • 谢谢,这有效(有一些修改),但我更喜欢@Blargh 的回答,因为当我单击工具栏按钮的菜单部分时,它允许我附加一个附加的 sdk 面板而不是 iframe . Sorry for unaccepting.
    • 我同意 blargh,他的解决方案是针对您的评论而不是针对您的主题问题。你需要注意那些东西会被抓住的东西
    【解决方案3】:

    您可以使用插件 SDK 和一些 Jetpack 模块创建工具栏按钮和面板。试试 Rob--W 的 toolbarwidget-jplibbrowser-action-jplib

    您可以轻松地向工具栏添加一个按钮,并使用 css / html 为面板设置任何样式:

    var badge = require('browserAction').BrowserAction({
        default_icon: 'images/icon19.png', // optional
        default_title: 'Badge title',      // optional; shown in tooltip
        default_popup: 'popup.html'        // optional
    });
    

    【讨论】:

    • 谢谢。不幸的是,两者都没有提供一种方法来创建具有两种不同操作的双面菜单按钮,具体取决于单击哪一侧。
    猜你喜欢
    • 2021-04-25
    • 2023-01-15
    • 1970-01-01
    • 2023-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 2023-03-07
    相关资源
    最近更新 更多