Вместо того, чтобы изменять код страницы (что возможно, но может быть утомительно), рассмотрите возможность изменения собственного слушателя для работы в фазе захвата , а не в фазе пузырьков. Например, вместо
document.body.addEventListener('keypress', fn);
do
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, родительское окно выиграло вообще не видите событие из-за проблем безопасности.
На большинстве страниц вы сможете сообщить о событии родителю с помощью 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 есть CSP, который запрещает запуск пользовательских скриптов без него .
Но, к сожалению, есть еще одна проблема: в этом В конкретном случае окно iframe также перезаписывает EventTarget.prototype.addEventListener
на странице объявление, прежде чем пользовательский скрипт сможет запустить. Хотя вы можете обычно использовать // @run-at document-start
, чтобы сохранить ссылку на переменную до того, как сценарий страницы перезапишет ее, в iframe это невозможно; Chrome usercripts в iframes не может работать в самом начале загрузки страницы.
Без ссылки на EventTarget.addEventListener
(или EventTarget.prototype.onclick
или EventTarget.prototype.onkeydown
setters, et c) нет способа получить доступ к API уровня браузера, который регистрирует действия пользователя.
Я не думаю, что то, что вы ищете, возможно в Tampermonkey.