我尝试覆盖网站上的事件侦听器已经有一段时间了,但视频播放器(jwplayer)遇到了问题。关键事件被绑定和捕获,并且不能轻易被覆盖。
这是脚本:
// ==UserScript==
// @name test
// @author test
// @version 1.1.5
// @match *://*.example.com/*
// @require https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// ==/UserScript==
/* globals $ */
document.addEventListener('keydown', function(e){
if (e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey)
{
switch (e.keyCode)
{
case 37:
alert('37');
// JQuery code to change the page
break;
case 39:
alert('39');
// JQuery code to change the page
break;
}
}
}, true);
测试是这样完成的:
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://third-party.example.com/js/jwplayer8/jwplayer.core.controls.html5.js';
document.getElementsByTagName('head')[0].appendChild(script);
script.onload = function() {
alert( 'loaded' );
}
Jwplayer 的控件只是一个简单的开关盒,并且调用与我相同的键,其中包括:键 37 和 39。将我正在监视的键更改为其他键不会改变任何东西。
当玩家注意力不集中时,一切都会按预期进行。当播放器启动并捕获按键时,它会破坏用户脚本。
页面加载时,网站的脚本加载两次。第一个打开一个对话框,简单地说“已加载”,正如它应该的那样。然而,在第二次加载对话框时,虽然仍然说“已加载”,但现在有一个名为“https://third-party.example.com的页面说:”的标题,而不是像以前那样没有标题。
同样,使用快捷键 Ctrl + 箭头(向左或向右)会产生相同的结果。警报只显示“37”或“39”,就像它们应该的那样,并且对话框没有标题,如预期的那样。
一旦 jwplayer 成为焦点,对话框就会显示脚本已加载的信息。标题变为“https://third-party.example.com 的页面说:”,然后“37”或“39”作为其中的信息。
我最初的计划是简单地取消 jwplayer 的焦点,但考虑到警报正确执行,但其后面的任何代码却没有执行,这使得这变得很困难。
在 JavaScript 中处理事件有两个阶段。一是事件捕获阶段,事件从父级流向子级。另一个是事件冒泡阶段,事件自下而上流动(子级到父级)。
您可以通过将第三个参数设置为
.addEventListener()
到true
来打开捕获。然后,您可以使用 event.stopPropagation()
确保事件不会渗透到视频播放器。
document.addEventListener('keydown', function(e){
e.stopPropagation();
// Any other code
}, true); // <= This tells JS to use the event capturing phase