编辑:
查看当前解决方案的答案底部。
原答案:
当您认为自己已经在这里搜索了足够长的时间以提出问题时,您会发现一些真正有用的东西。
根据this question 的回答,我将代码更新为:
function getVideo() {
var videos = document.getElementsByTagName("video");
if (videos.length >= 1) {
return [videos[0], "main"];
}
// Code that will run only inside iframe
if (parent === top) {
var videos = document.getElementsByTagName("video");
if (videos.length >= 1) {
return [videos[0], "iframe"];
}
}
return [null, null]; // if a video doesn't exist
}
并将其包含在我的清单中,以便脚本也可以注入 iframe:
"content_scripts": [{
"all_frames": true,
...
...
}],
这行得通,但它确实使我的其他功能非常难看。示例:
// if a video exists, set it to the speed and give a notification
function setSpeed(newSpeed) {
var returnVal = getVideo();
var video = returnVal[0], type = returnVal[1];
if (video != null && type === "main") {
video.playbackRate = newSpeed;
inWindowAlert("Speed: " + newSpeed, 1000);
setIcon(newSpeed);
}
if (parent === top) {
if (video != null && type === "iframe") {
video.playbackRate = newSpeed;
inWindowAlert("Speed: " + newSpeed, 1000);
setIcon(newSpeed);
}
}
}
我会尝试提出一个更清洁的解决方案,但目前它可以工作。希望这对任何人都有帮助。
新解决方案:
只是想更新一下,说明我完全重写了扩展程序的逻辑以更轻松地处理这个问题。
新的解决方案允许在每个帧中运行的内容脚本的每个实例独立运行,并简单地收集其上下文中的所有视频。我还将它们收集在Set 中以避免意外重复。
我仍然想再次检查以消除全局变量的使用,但扩展现在运行良好,因此它可能会保持一段时间。
新代码:
function getVideos() {
let new_videos = document.getElementsByTagName("video");
if (new_videos.length >= 1) {
VIDEOS = new Set(new_videos);
return VIDEOS;
}
return new Set();
}
和
// set video to the speed and give a notification, restricts available speeds
function setSpeed(newSpeed, video) {
//* BUG-FIX: playback rates below 0.07 rather than 0 were causing errors
newSpeed = newSpeed > 16 ? 16 : newSpeed < 0.07 ? 0 : newSpeed;
// limit decimal values to 2 digits, + in front truncates 2.00 -> 2
SPEED = +newSpeed.toFixed(2);
video.playbackRate = SPEED;
tempAlert("Speed: " + SPEED, 2000, video);
setIcon(SPEED);
}
其中VIDEOS 和SPEED 是全局变量。