更改页面javascript代码(TamperMonkey)以将键盘笔触发送到父DOM

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了更改页面javascript代码(TamperMonkey)以将键盘笔触发送到父DOM相关的知识,希望对你有一定的参考价值。

我有一个使用TradingView小部件的页面,您可以在其中键入键盘上的任意键以触发符号搜索。我使用Chrome的调试器来断点,并确切地知道执行此操作的代码行。我希望将按键事件起泡到通用DOM,由我自己的自定义函数处理。

该怎么做?任何示例代码将不胜感激。这是TradingView的代码片段(“ t”是关键事件):

            a || (o.handle = a = function(t) 
                return s === Te || t && Te.event.triggered === t.type ? s : Te.event.dispatch.apply(a.elem, arguments)
            

因此,我希望将键事件发送到我自己的函数中,而不是return语句。完整的TradingView代码,其中代码为:https://static.bitmex.com/assets/tradingView/static/tv-chart.min-6ce28e05fd34b9cf06a4e63b29980a72.js

答案

而不是更改页面代码(这是可能的,但可能很乏味),请考虑更改您自己的侦听器以在capturing阶段而不是冒泡阶段中运行。例如,代替

document.body.addEventListener('keypress', fn);

document.body.addEventListener('keypress', fn, true);

它将在事件冒泡到内部元素之前运行。

如果运行fn之前需要完成内部元素上页面的侦听器,则可以在小的fn之后调用setTimeout

document.body.addEventListener('keypress', () => setTimeout(fn), true);

[如果您还想阻止小部件的代码运行,请确保在捕获侦听器中调用stopPropagation,以使事件不会捕获到小部件中:

const fn = (event) => 
  event.stopPropagation();
  // rest of code
;

如果要发送关键事件的容器在iframe内,由于安全问题,父窗口将根本看不到该事件。

most页上,您可以使用postMessage将事件传达给上级,例如:

// ==UserScript==
// @name             0 New Userscript
// @include          https://www.bitmex.com/app/trade/XBTUSD
// @include          https://static.bitmex.com/chartEmbed*
// @grant            GM_getValue
// @run-at document-start
// ==/UserScript==

if (window.location.host === 'www.bitmex.com') 
  const mainFn = () => 
    console.log('b');
  ;
  // We're on the top level
  const keydown = (e) => 
    e.stopPropagation();
    if (!e.altKey && e.key === 'b') 
      mainFn();
    
  ;
  window.addEventListener('keydown', keydown, true);
  window.addEventListener('message', (e) => 
    if (e.origin === 'https://static.bitmex.com' && e.data === 'keydown inside iframe') 
      mainFn();
    
  );
 else 
  // We're in the iframe
  // When a keypress is detected, message the parent window
  const keydown = (e) => 
    console.log('iframe kd');
    e.stopPropagation();
    if (!e.altKey && e.key === 'b') 
      window.top.postMessage('keydown inside iframe', '*');
    
  ;
  window.addEventListener('click', keydown, true);

@run-at document-start是必需的,因为iframe具有正在运行forbids userscripts without it的CSP。

但是不幸的是,还有另一个问题:在这种特殊情况下,iframe窗口also在用户脚本有机会运行之前,会在页面加载时覆盖EventTarget.prototype.addEventListener。尽管您可以[[通常]]使用// @run-at document-start来确保在页面脚本覆盖变量之前保存对变量的引用,但这在iframe中是不可能的。 iframe中的Chrome用户脚本无法在页面加载开始时就运行。[没有引用EventTarget.addEventListener(或EventTarget.prototype.onclickEventTarget.prototype.onkeydown设置器等),无法访问注册用户操作的浏览器级API。

我认为您要找的东西在Tampermonkey中是不可能的。

以上是关于更改页面javascript代码(TamperMonkey)以将键盘笔触发送到父DOM的主要内容,如果未能解决你的问题,请参考以下文章

更改页面javascript代码(TamperMonkey)以将键盘笔触发送到父DOM

javascript 从另一个页面更改元素

ASP.NET WebForm中JavaScript修改了页面上Label的值,如何在后台代码中获取

我可以在客户端更改页面的 HTML 状态代码吗?

如何在不更改 javascript 中的 URL 的情况下重新加载当前页面一次?

如何使用 Javascript 保存 CSS 更改?