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

问题描述 投票:0回答:1

我有一个使用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

javascript google-chrome tampermonkey userscripts
1个回答
0
投票

而不是更改页面代码(这是可能的,但可能很乏味),请考虑更改您自己的侦听器以在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中是不可能的。

© www.soinside.com 2019 - 2024. All rights reserved.