火狐扩展:为现有的Chrome XUL元素添加功能

4
为了好玩,我正在尝试编写一个Firefox扩展程序。只是一个非常简单的扩展程序。我已经阅读了一些教程,并且成功创建了基本的“Hello, World”应用程序。
我想要做的事情是,在Firefox应用程序DOM(即选项卡)中的现有元素上添加事件监听器。到目前为止,我能够找到的所有资源都显示如何向应用程序添加新元素,然后使用JavaScript添加操作。我已经尝试过多种方法来添加JavaScript函数(我知道这些函数有效,因为我已经成功地使用该函数添加了元素)到现有元素中。
我最近的尝试结构如下:
<?xml version="1.0"?>
<!-- in myExtension.xul -->

<overlay  id="myExtension"
          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script type="application/x-javascript">
    var tabs = document.getElementsByTagName("tabbrowser-tab")
    var len = tabs.length;
    for (var i = 0; i < len; i++) {
      tabs[i].ondblclick = function() {
        alert('bam!');
      }
    };
  </script>

</overlay>

这些东西都不起作用。就像我说的,我对这些完全是新手,只是在周末项目上得到了一点启发。也许有一种方法可以确保我访问的是Chrome文档而不是页面文档?虽然当我尝试使用这种技术获取页面元素(即“p”)时,也不起作用,所以这可能是个死胡同。 [编辑] 为了澄清一些混淆的事情:
我的意思是“浏览器的DOM”,是指作为Chrome界面一部分的元素,而不是网页元素。我说的是在Firefox应用程序UI中已经存在的元素上放置事件监听器,例如一个选项卡(不是选项卡的内容,而是选项卡本身),或者Home按钮。我想重新定义Firefox应用程序GUI的某些部分的行为。
例如,假设我想在每次单击“新建标签”按钮或“关闭标签”按钮时添加一个警报。或者如果我想重新定义“重新加载”按钮,使其重定向到当前选项卡域的根目录,而不仅仅是重新加载页面。这些都是Firefox的现有部分,我想通过扩展来重新定义它们/覆盖它们,具体是通过向它们添加JavaScript操作。
[/编辑]
[旁注]嵌入式JavaScript在xul中允许吗?还是需要单独的文件?[/旁注]
有人有什么建议吗?

document.getElementsByTagName("tabbrowser-tab") 不会返回一个 NodeList 吗?你尝试获取第一个标签并注册监听器吗?你能把你的扩展程序发布到某个地方吗? - speedball2001
我其实在一段时间前就注意到了这个问题,并且已经修改了我的代码尝试。更新到最新的尝试。 - Josh Kovach
该项目在这里:https://github.com/shekibobo/PinFresh - Josh Kovach
2个回答

4

覆盖层代码中的javascript代码无法正常工作,因为它在gbrowser包含任何选项卡之前运行。

在Firefox(或Thunderbird)扩展程序中,通常在加载事件侦听器中启动扩展程序:

window.addEventListener("load",
                         pinfresh.init,
                         false);

init函数需要为各种选项卡事件注册事件侦听器:

  pub.init = function() {
    var container = gBrowser.tabContainer;

    container.addEventListener("TabOpen", tabOpened, false);
    container.addEventListener("TabClose", tabRemoved, false);
  };

当打开一个新标签页时,我们会注册另一个监听器,当用户双击标签页时触发重新加载标签页的操作:

  tabOpened = function(e) {
    var tab = e.target;
    tab.addEventListener("dblclick", tabDoubleClicked, false);
  }

  tabDoubleClicked = function(e) {
    gBrowser.reloadTab(e.target);
  }

完整代码如下:
<overlay  id="pinfresh"
          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script type="application/x-javascript">
    pinfresh = function() {
      var pub = {};

      tabOpened = function(e) {
        var tab = e.target;
        tab.addEventListener("dblclick", tabDoubleClicked, false);
      }

      tabRemoved = function(e) {
        var tab = e.target;

        tab.removeEventListener("dblclick", tabDoubleClicked, false);
      }

      tabDoubleClicked = function(e) {
        gBrowser.reloadTab(e.target);
      }

      pub.init = function() {
        var container = gBrowser.tabContainer;

        container.addEventListener("TabOpen", tabOpened, false);
        container.addEventListener("TabClose", tabRemoved, false);
      };

      return pub;
    }();

    window.addEventListener("load",
                            pinfresh.init,
                            false);

  </script>
</overlay>

如果要使代码片段与选项卡一起使用,我建议查看Mozilla开发中心的选项卡浏览器页面。

我建议将Javascript代码放在自己的文件中,而不是将其包含在XUL文件中。外部Javascript文件中的错误会显示在Firefox的错误控制台中,这样调试就更容易了。


不希望你觉得我对这个答案置之不理。只是我还没有时间来尝试,而且可能要等到五月份才行。这比我预期的要多很多信息,让我在最后一个学期的压力时刻有很多东西需要学习。 - Josh Kovach
如果您需要,我可以提供修改后的源代码。请问如何联系您? - speedball2001

3
为了获取当前浏览标签页的页面元素,首先需要使用gBrowser.selectedBrowser.contentDocument获取文档本身。
所以基本上,如果您有一个<p id='test'>blah</p>元素并且想要操纵它,您可以执行var p = gBrowser.selectedBrowser.contentDocument.getElementById('test');,然后对其进行任何操作。
关于“向浏览器DOM中的现有元素添加事件侦听器(即选项卡)”,我很抱歉无法理解您想要什么,您是想操纵浏览器GUI(例如在导航栏中添加按钮),还是想操纵选项卡的DOM内容(即查看的网站)? (基本上,“browser”可以意味着很多东西:))。

1
对于浏览器内容解决方案,我给出一个加1的评价。但基本上,我想要为某些浏览器选项卡添加双击操作。正如我上面的代码示例所示,我不想添加元素,我只想使现有元素执行与其默认设置不同的操作。 - Josh Kovach
1
就像你可以使用jQuery为页面元素添加功能一样,你实际上不需要创建新元素,只需在DOM中找到它们并分配一些功能。$(document).ready(function() { $("tabbrowser-tab").dblclick(alert('tab')) }); - Josh Kovach
抱歉,我仍然不明白您所说的“特定浏览器标签”是指什么。您是指浏览器标签本身(您当前单击其中一个标签,浏览器会显示其内容),还是指“标签内容”,即网站HTML?例如,现在我可以看到您的问题和评论在标签内容中,并且还可以看到浏览器中选定的标签具有Stackoverflow的图标(favicon)。 - Nimrod Yonatan Ben-Nes
如果您想要为选项卡内容(例如,显示的网站)的元素添加事件侦听器,请阅读Ajaxian事件侦听器并使用该内容创建任何类型的事件侦听器。在我的扩展中,我使用了他们提供的代码作为独立的JS文件,在我的代码开头调用它,然后每当我想要将事件附加到元素时,我执行以下操作: var lst = El.createEventListener(); img.addEventListener("click", lst, false); lst.addEvent("click", function (e, callback, object) {code..} - Nimrod Yonatan Ben-Nes
编辑了帖子以试图消除混淆。我想“浏览器”这个词让人感到困惑。我说的是改变Firefox应用程序DOM元素的行为。这与组成Firefox的XUL元素有更多关系,而不是HTML DOM的元素。 - Josh Kovach
这是可行的。正如我在上面的评论中所写,你能否将你的扩展上传到某个地方?这样更容易找出为什么它对你不起作用。 - speedball2001

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接