6

我创建了一个Chrome扩展,它只使用热键[Alt] + [0 ... 9]来发现Facebook使用相同的热键。有没有可能我的扩展可能禁用Facebook的热键,让我的火单独?我敢肯定我已经确定了代码Facebook的使用来实现自己的[Alt]键+ [0 ... 9]热键:如何通过Chrome扩展禁用Facebook热键?

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

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

Chrome doc on Content Scripts

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

首先,您需要在网页上的某个地方托管一个JavaScript文件,其中包含您要在该页面中执行的脚本,可以说您将其放置在: http://mysite.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插件的沙盒代码。

+0

感谢您的支持。这确实很有见地!我发现没有必要在其他网站上举办的这个作品:'script.setAttribute(“SRC”,chrome.extension.getURL(“覆盖-FB-hotkeys.js”));'但是代码'文件。 documentElement.onkeydown = function(e){};'在注入的文件内不禁用fb快捷键,所以任何更多的帮助将受到欢迎! –

+0

您需要对Facebook页面上的代码进行反向工程,以确定如何捕获和处理关键事件,然后重写该功能。我看了一下,但没有跳出来。我注意到,当我删除I​​D为“blueBarHolder”(整个顶部栏)的元素,然后热键不起作用。 –

+0

嘿,我想问你,因为你似乎知道的东西。你知道是否有一个聪明的解决方法,只需在Chrome上禁用Facebook上的快捷键?我不能忍受L这样的事实(我经常使用ctrl + l来访问导航栏)。就像,即使是简单的一行脚本也会帮助 – Tom

8

Chrome的内容脚本在沙盒环境中执行[source]。没有直接的方式与全球(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+和至少铬5+。如果你也想支持Firefox 2+和Chrome 1+,你可以用__defineSetter__发挥,以防止onkeydown被定义为:

document.documentElement.__defineSetter__('onkeydown', function(){}); 
+0

如果Facebook代码重写Object.defineProperty会怎么样? – Pacerier

+0

@Pacerier如果你用'run_at; “document _start”',那么它不应该是可能的。 –

+0

2 diff扩展名可以执行'document_start'吗? – Pacerier

1

这是您如何使用jQuery

删除所有做任何网页的快捷键:

$('[accessKey]').attr('accessKey','')