我正在制作一个简单的Chrome扩展程序,以将YouTube播放列表中每个视频的长度相加并将总长度插入页面中。我已经成功做到了,但是我的脚本仅在刷新页面后才起作用,但在浏览网站时却不起作用。但这不是很方便。
是否有可能检测YouTube上的页面导航并将HTML插入页面,然后在浏览器中呈现HTML,以便立即显示添加的内容而没有任何延迟并且不需要刷新页面?
示例链接:https://www.youtube.com/playlist?list=PL_8APVyhfhpdgMJ3J80YQxWBMUhbwXw8B
附言我的问题与Modify elements immediately after they are displayed (not after page completely loads) in greasemonkey script?不同,因为我已经尝试过MutationObserver且问题是相同的-需要刷新以显示对网页的更改:
var observer = new MutationObserver(function(mutations) {
for (var i=0; i<mutations.length; i++) {
var mutationAddedNodes = mutations[i].addedNodes;
for (var j=0; j<mutationAddedNodes.length; j++) {
var node = mutationAddedNodes[j];
if (node.classList && node.classList.contains("timestamp")) {
var videoLength = node.firstElementChild.innerText;
observer.disconnect();
var lengthNode = document.createElement("li");
var lengthNodeText = document.createTextNode(videoLength);
lengthNode.appendChild(lengthNodeText);
document.getElementsByClassName("pl-header-details")[0].appendChild(lengthNode);
return;
}
}
}
});
observer.observe(document, {childList: true, subtree: true});
最佳答案
YouTube网站不会重新加载导航页面,而是替换了history state。
更改URL而不重新加载页面时,不会重新插入扩展程序的内容脚本。自然,当您手动重新加载页面时,将执行内容脚本。
在YouTube网站上,有几种方法可以检测页面转换:
使用后台页面脚本的
transitionend
event用于视频页面上的进度表在devtools控制台中运行
getEventListeners(window)
并检查输出。在这种情况下,我们需要 yt-navigate-start 。
笔记:
spfdone
event manifest.json :
{
"name": "YouTube Playlist Length",
"version": "0.0.1",
"manifest_version": 2,
"description": ".............",
"content_scripts": [{
"matches": [ "*://*.youtube.com/*" ],
"js": [ "content.js" ],
"run_at": "document_start"
}]
}
请注意:
matches
键包含整个youtube.com域,以便在用户首次打开YouTube主页后,导航至观看页面时运行内容脚本。content.js :
window.addEventListener('yt-navigate-start', process);
if (document.body) process();
else document.addEventListener('DOMContentLoaded', process);
process
函数将更改页面。注意,指定的元素类和结构将来会更改。
function process() {
if (!location.pathname.startsWith('/playlist')) {
return;
}
var seconds = [].reduce.call(
document.getElementsByClassName('timestamp'),
function (sum, ts) {
var minsec = ts.textContent.split(':');
return sum + minsec[0] * 60 + minsec[1] * 1;
},
0,
);
if (!seconds) {
console.warn('Got no timestamps. Empty playlist?');
return;
}
var timeHMS = new Date(seconds * 1000).toUTCString().split(' ')[4]
.replace(/^[0:]+/, ''); // trim leading zeroes
document.querySelector('.pl-header-details')
.insertAdjacentHTML('beforeend', '<li>Length: ' + timeHMS + '</li>');
}
关于javascript - 如何在YouTube上检测页面导航并无缝修改其外观?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62333124/