7

我创建了一个 Chrome 扩展,它使用热键 [Alt]+[0...9] 只是为了发现 facebook 使用相同的热键。有什么办法可以让我的扩展程序禁用 facebook 的热键,以便我单独开火?我相当确定我已经确定了 facebook 用来实现他们的 [Alt]+[0...9] 热键的代码:

document.documentElement.onkeydown=function(a){a=a||window.event;var b=a.target||a.srcElement;var c=a.keyCode==13&&!a.altKey&&!a.ctrlKey&&!a.metaKey&&!a.shiftKey&&CSS.hasClass...

这是在从根文档的头部调用的脚本中。我尝试了以下方法来禁用它们:

//contents script:
$().ready( function() {
  document.documentElement.onkeydown = '';
});

乃至

$().ready( function() {
  document.documentElement.onkeydown = function(e){};
});

我进一步猜测,这些尝试都不起作用的原因是,尽管 Chrome 扩展内容脚本与它们运行的​​任何网页共享一个 DOM,但也许它们不共享编码环境?任何见解将不胜感激!

4

3 回答 3

13

Chrome 的内容脚本在沙盒环境中执行[来源]。没有与全局 ( ) 对象进行通信的直接方法。 window

另一个常见的陷阱是开发人员忘记了脚本是如何/何时注入的。

  • 默认情况下,脚本在名为“ document_idle ”的位置注入。此时,文档不忙(DOMContentLoaded已触发,window.onload可能已触发,也可能未触发)。
  • 因此,脚本中的函数可能会在声明后立即被覆盖。

要注入一个小脚本,我建议将代码直接添加到内容脚本中:

var actualCode = '/* Code here (see below for inspiration) */';

var script = document.createElement('script');
script.appendChild(document.createTextNode(actualCode));
(document.head || document.documentElement).appendChild(script);
script.parentNode.removeChild(script);

如果您想确保该方法不会被覆盖,您可以使用Object.defineProperty, 来定义一个不可变属性:

Object.defineProperty(document.documentElement, 'onkeydown', {
    value: function() {},
    writable: false,     /* Cannot be overwritten, default false */
    configurable: false, /* Cannot be deleted, or modified */
    enumerable: true     /* Does not really matter. If true, it's visible in
                             a for-loop. If false, it's not*/
});

Firefox 4+ 和至少 Chrome 5+ 支持前面提到的方法。如果您还想支持 Firefox 2+ 和 Chrome 1+,可以使用__defineSetter__, 来防止onkeydown被定义:

document.documentElement.__defineSetter__('onkeydown', function(){});
于 2012-01-24T21:29:35.690 回答
6

您的直觉是正确的,作为 Chrome 扩展程序的一部分从内容脚本运行的 JavaScript 在沙箱中运行,该沙箱无法访问在包含页面中执行的 JavaScript。

根据内容脚本上的 Chrome 文档

However, content scripts have some limitations. They cannot:
*  Use chrome.* APIs (except for parts of chrome.extension)
*  Use variables or functions defined by their extension's pages
*  Use variables or functions defined by web pages or by other content scripts

首先,我建议您考虑不同的快捷键。为您自己的扩展程序覆盖现有快捷键的功能可能会为期待 Facebook 快捷键的人提供不和谐的用户体验。想象一下,如果一个扩展覆盖了作为复制和粘贴桌面操作系统一部分的 ctrl-c 和 ctrl-p 快捷方式——我想你会有一些不高兴的用户可能会删除改变他们之前学到的行为的东西。

但是,如果您坚持,那么这里是加载将在包含页面的上下文中执行的 JavaScript 的解决方法:

编辑:更新每条评论以引用插件中的 JS 文件,而不是托管在网络上的文件

首先,您需要在 chrome 插件中创建一个 JavaScript 文件:override-fb-hotkeys.js.

首先,您需要在 Web 上的某个位置托管一个 JavaScript 文件,其中包含您要在页面中执行的脚本,假设您将它托管在:http://example.com/override-fb-hotkeys.js.

然后,从您的内容脚本中,您可以将一个脚本标签插入到引用您的 JavaScript 文件的 DOM 中,如下所示:

    var script = document.createElement('script');
    script.setAttribute("type", "text/javascript");
    script.setAttribute("async", true);
    script.setAttribute("src", chrome.extension.getURL("override-fb-hotkeys.js")); //Assuming your host supports both http and https
    var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
    head.insertBefore(script, head.firstChild)

然后将在包含页面的上下文中获取并执行 JavaScript,而不是来自 Chrome 插件的沙盒代码。

于 2012-01-24T07:13:19.973 回答
1

这就是使用 jQuery 的方法

删除任何网页的所有快捷方式:

$('[accessKey]').attr('accessKey','')
于 2013-06-16T19:04:59.167 回答