Javascript keydown事件在引导Firefox插件中不起作用

Javascript keydown事件在引导Firefox插件中不起作用,javascript,firefox-addon,key,Javascript,Firefox Addon,Key,我是新的延伸发展。我正试图在我启动的Firefox扩展中触发一个keydown事件,但它似乎不起作用。我错过什么了吗 下面是我的bootstrap.js代码: Cu.import("resource://gre/modules/Services.jsm"); function watchWindows(callback) { function watcher(window) { try { let {documentElement} = window.docum

我是新的延伸发展。我正试图在我启动的Firefox扩展中触发一个
keydown
事件,但它似乎不起作用。我错过什么了吗

下面是我的bootstrap.js代码:

Cu.import("resource://gre/modules/Services.jsm");

function watchWindows(callback) {

    function watcher(window) {
    try {

      let {documentElement} = window.document;
      if (documentElement.getAttribute("windowtype") == "navigator:browser")
        callback(window);
    }
    catch(ex) {}
    }


     function runOnLoad(window) {

    window.addEventListener("load", function runOnce() {
      window.removeEventListener("load", runOnce, false);
      watcher(window);
    }, false);
  }

  // Add functionality to existing windows
  let windows = Services.wm.getEnumerator(null);
  while (windows.hasMoreElements()) {
    // Only run the watcher immediately if the window is completely loaded
    let window = windows.getNext();
    if (window.document.readyState == "complete")
      watcher(window);
    // Wait for the window to load before continuing
    else
      runOnLoad(window);
  }

  // Watch for new browser windows opening then wait for it to load
  function windowWatcher(subject, topic) {
    if (topic == "domwindowopened")
      runOnLoad(subject);
  }
  Services.ww.registerNotification(windowWatcher);

  // Make sure to stop watching for windows if we're unloading
  unload(function() Services.ww.unregisterNotification(windowWatcher));
}

/**
* Save callbacks to run when unloading. Optionally scope the callback to a
* container, e.g., window. Provide a way to run all the callbacks.
*
* @usage unload(): Run all callbacks and release them.
*
* @usage unload(callback): Add a callback to run on unload.
* @param [function] callback: 0-parameter function to call on unload.
* @return [function]: A 0-parameter function that undoes adding the callback.
*
* @usage unload(callback, container) Add a scoped callback to run on unload.
* @param [function] callback: 0-parameter function to call on unload.
* @param [node] container: Remove the callback when this container unloads.
* @return [function]: A 0-parameter function that undoes adding the callback.
*/
function unload(callback, container) {
  // Initialize the array of unloaders on the first usage
  let unloaders = unload.unloaders;
  if (unloaders == null)
    unloaders = unload.unloaders = [];

  // Calling with no arguments runs all the unloader callbacks
  if (callback == null) {
    unloaders.slice().forEach(function(unloader) unloader());
    unloaders.length = 0;
    return;
  }

  // The callback is bound to the lifetime of the container if we have one
  if (container != null) {
    // Remove the unloader when the container unloads
    container.addEventListener("unload", removeUnloader, false);

    // Wrap the callback to additionally remove the unload listener
    let origCallback = callback;
    callback = function() {
      container.removeEventListener("unload", removeUnloader, false);
      origCallback();
    }
  }

  // Wrap the callback in a function that ignores failures
  function unloader() {
    try {
      callback();
    }
    catch(ex) {}
  }
  unloaders.push(unloader);

  // Provide a way to remove the unloader
  function removeUnloader() {
    let index = unloaders.indexOf(unloader);
    if (index != -1)
      unloaders.splice(index, 1);
  }
  return removeUnloader;
}

/* library */

const Utils = (function() {

    const sbService = Cc['@mozilla.org/intl/stringbundle;1']
                         .getService(Ci.nsIStringBundleService);
    const windowMediator = Cc['@mozilla.org/appshell/window-mediator;1']
                              .getService(Ci.nsIWindowMediator);


    let setAttrs = function(widget, attrs) {
        for (let [key, value] in Iterator(attrs)) {
            widget.setAttribute(key, value);
        }
    };

    let getMostRecentWindow = function(winType) {
        return windowMediator.getMostRecentWindow(winType);
    };

    let exports = {
        setAttrs: setAttrs,
        getMostRecentWindow: getMostRecentWindow,
    };
    return exports;
})();



let ResponseManager = (function() {

    const obsService = Cc['@mozilla.org/observer-service;1']
                          .getService(Ci.nsIObserverService);

    const RESPONSE_TOPIC = 'http-on-examine-response';

    let observers = [];

    let addObserver = function(observer) {
        try {
            obsService.addObserver(observer, RESPONSE_TOPIC, false);
        } catch(error) {
            trace(error);
        }
        observers.push(observers);
    };

    let removeObserver = function(observer) {
        try {
            obsService.removeObserver(observer, RESPONSE_TOPIC, false);
        } catch(error) {
            trace(error);
        }
    };

    let destory = function() {
        for (let observer of observers) {
            removeObserver(observer);
        }
        observers = null;
    };

    let exports = {
        addObserver: addObserver,
        removeObserver: removeObserver,
        destory: destory,
    };
    return exports;
})();

/* main */

let ReDisposition = function() {

    let respObserver;

    respObserver = {

        observing: false,

        observe: function(subject, topic, data) {
            try {
                let channel = subject.QueryInterface(Ci.nsIHttpChannel);
                this.override(channel);
            } catch(error) {
                trace(error);
            }
        },

        start: function() {
            if (!this.observing) {
                ResponseManager.addObserver(this);
                this.observing = true;
            }
        },
        stop: function() {
            if (this.observing) {
                ResponseManager.removeObserver(this);
                this.observing = false;
            }
        },
        refresh: function() {
            this.start();
        },

        re: /^\s*attachment/i,

        re2: /^\s*text/i,

        override: function(channel) {

            if(disablePlugin)
            {
               try {
               let contentHeader;
               contentHeader = channel.getResponseHeader('Content-Type');
               if (this.re2.test(contentHeader)) 
               return;
               channel.setResponseHeader('Content-Disposition', "attachment", false);
               return;
               }
                catch(error) {
                return;
                }       
            }

            // check if have header
            let header;
            try {
                header = channel.getResponseHeader('Content-Disposition');
            } catch(error) {
                return;
            }

            // override to inline
            if (this.re.test(header)) {
                channel.setResponseHeader('Content-Disposition', header.replace(this.re, "inline"), false);
                return;
            }

        }
    };



    let initialize = function() {

        respObserver.refresh();
    };
    let destory = function() {

        respObserver.stop();
    };

    let exports = {
        initialize: initialize,
        destory: destory,
    }
    return exports;

};

/* bootstrap entry points */

let reDisposition;
var disablePlugin = false;
let install = function(data, reason) {};
let uninstall = function(data, reason) {};

let startup = function(data, reason) {

    reDisposition = ReDisposition();
    reDisposition.initialize();
    function onwindow(window) {
        function onkeydown(e) {
            if (e.keyCode == 70)
            {
            disablePlugin = true;
            }
            else
            {
            disablePlugin = false;
            }

        }
        function onkeyup(e) {

            disablePlugin = false;

        }
        // Bootstrapped add-ons need to clean up after themselves!
        function onunload() {
            window.removeEventListener("keydown", onkeypress);
            window.removeEventListener("keyup", onkeypress);
        }
        window.addEventListener("keydown", onkeydown);
        window.addEventListener("keyup", onkeyup);
        unload(onunload, window);
    }
    watchWindows(onwindow);


};

let shutdown = function(data, reason) {
    reDisposition.destory();
};

bootstrap.js
范围中没有
窗口
在开发时,您必须枚举现有窗口,并亲自观察新窗口,并根据需要“附加”到它们。例如,请参阅

这里有一个例子。它假定您正在使用
监视窗口
样板文件:

function startup(data, reason) {
    // Callback function called for each browser window (browser.xul)
    function onwindow(window) {
        function onkeydown(e) {
            // XXX: Your code here.
        }
        // Bootstrapped add-ons need to clean up after themselves!
        function onunload() {
            window.removeEventListener("keydown", onkeypress);
        }
        window.addEventListener("keydown", onkeydown);
        unload(onunload, window);
    }

    // Will also fire for existing windows once and upon each new window.
    watchWindows(onwindow);
}

当您刚刚接触Firefox插件、XUL/XPCOM和mozilla平台时,开发自举插件并不是我推荐的。您可能应该查看基于XUL overlay的加载项或加载项SDK。

我强烈推荐加载项SDK,如果它允许实现您需要/想要的内容。与基于XUL的系统相比,您将节省大量的时间addons@nmaler我已经更新了代码,在上面的代码中根本不可能监听键盘事件。看来你只是复制了一些随机代码,并没有真正解决你的问题。。。然后甚至不要尝试使用它。我链接了
watchWindows
,这实际上可以帮助您安装按键处理程序。我将尝试在我的答案中添加一个示例。@非常感谢nmaler,但它仍然不起作用,我已上载了整个源代码,我正在尝试防止在按键时修改标题。请帮我做这个。在“键关闭”时,我想禁用标题修改,并在“键打开”时将其还原。@非常感谢,它正在工作,但“键打开”事件似乎无法正常工作。我已经上传了全部代码,我仍然不能相信我仅仅为了事件处理就必须添加大约150行代码。这是我从watch windows代码中额外添加的任何内容。请不要在事后根本改变您的问题。