如何使用 Chrome 扩展禁用 Facebook 热键?

发布于 2024-12-28 12:20:19 字数 772 浏览 0 评论 0原文

我创建了一个 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,但它们也许不共享编码环境?任何见解将不胜感激!

I have created a Chrome extension that uses the hotkeys [Alt]+[0...9] only to discover facebook uses the same hotkeys. Is there any way possible my extension could disable facebook's hotkeys so that mine fire alone? I'm fairly certain I have identified the code facebook uses to implement their [Alt]+[0...9] hotkeys:

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...

This is in a script called from the head of the root document. I have tried the following to disable them:

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

and even

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

I am guessing further that the reason neither of these attempts work is because although Chrome extension content scripts share a DOM with any webpage on which they run, perhaps they do not share coding environments? Any insight would be appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

懒猫 2025-01-04 12:20:19

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+ 且至少 Chrome 5+。如果您还想支持 Firefox 2+ 和 Chrome 1+,您可以使用 __defineSetter__ 来防止定义 onkeydown

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

Chrome's Content scripts are executed in a Sandboxed environment [source]. There is no direct way to communicate with the global (window) object.

Another common pitfall is that the developer forgets how/when the script is injected.

  • By default, the script is injected at a point called "document_idle". At this point, the document is not busy (DOMContentLoaded has fired, window.onload may or may not have fired).
  • As a result, the functions in the script may be overwritten immediately after declaration.

To inject a small script, I recommend to add the code directly to the Content Script:

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);

If you want to make sure that the method is not going to be overwritten, you can use Object.defineProperty, to define an immutable property:

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*/
});

The previously mentioned method is supported in Firefox 4+ and at least Chrome 5+. If you want to also support Firefox 2+ and Chrome 1+, you can play with the __defineSetter__, to prevent onkeydown from being defined:

document.documentElement.__defineSetter__('onkeydown', function(){});
茶花眉 2025-01-04 12:20:19

您的直觉是正确的,作为 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 的解决方法,该 JavaScript 将在包含页面的上下文中执行:

编辑: 根据评论更新以引用插件中的 JS 文件,而不是托管在插件中的 JS 文件首先

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

首先,您需要在网络上的某个位置托管一个 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 插件的代码。

Your intuition is correct, the JavaScript that runs from a content script as part of a Chrome Extension is run in a sandbox that does not have access to the JavaScript that is executed in the containing page.

Per the 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

First off, I would recommend that you consider different shortcut keys. Overriding the functionality of existing shortcut keys for your own extension could provide a jarring user experience for someone that is expecting the Facebook shortcut key. Imagine if an extension overrode the ctrl-c and ctrl-p shortcuts that are a part of the desktop OS for copy and paste - I think you would have some upset users that would probably remove the thing that changed the behavior they learned prior.

However, if you are insistent, then here is a workaround to loading JavaScript that will execute in the context of the containing page:

Edit: Updated per comment to reference JS file in a plugin instead of one hosted on the web

First, you will need to create a JavaScript file in your chrome plugin: override-fb-hotkeys.js.

First, you will need to host a JavaScript file somewhere on the web that contains the script that you want to execute in the page, let us say you host it at: http://example.com/override-fb-hotkeys.js.

Then, from your content script, you can insert a script tag into the DOM that references your JavaScript file, something like this:

    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)

The JavaScript will then be fetched and executed in the context of the containing page, not the sandboxed code from the Chrome plugin.

若相惜即相离 2025-01-04 12:20:19

这是使用 jQuery 删除任何网页的所有快捷方式的方法

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

This is how you can do it using jQuery

Remove all shortcuts for any webpage:

$('[accessKey]').attr('accessKey','')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文