【问题标题】:How to detect page navigation on YouTube and modify its appearance seamlessly?如何检测 YouTube 上的页面导航并无缝修改其外观?
【发布时间】:2016-03-08 18:06:17
【问题描述】:

我正在制作一个简单的 Chrome 扩展程序,以将 YouTube 播放列表中每个视频的长度相加,并将总长度插入页面中。我已经成功了,但是我的脚本仅在刷新页面后才有效,但在网站导航时无效。不过这样不太方便。

是否可以在 YouTube 上检测页面导航并将 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});

【问题讨论】:

  • 嗯,我试过了,但它不适合我的目的。我要插入组合视频长度的页面部分在加载每个视频的时间戳时已经加载,所以我有同样的问题,需要刷新页面以显示注入的 HTML。更新了我的问题,因为它被标记为重复。
  • 刚刚试过了,不,没有解决。仍然需要刷新。
  • 感谢您到目前为止提供的帮助。这是脚本,底部还有清单:pastie.org/private/yyc7piosnsna4yq7oymia

标签: javascript google-chrome google-chrome-extension


【解决方案1】:

YouTube 网站不会重新加载导航页面,它会替换 history state

在没有重新加载页面的情况下更改 URL 时,不会重新注入扩展程序的内容脚本。当您手动重新加载页面时,自然会执行内容脚本。

有几种方法可以检测 Youtube 网站上的页面转换:

  • 使用后台页面脚本:webNavigation APItabs API

  • 使用内容脚本:transitionend event 用于视频页面上的进度条

  • 使用内容脚本和视频导航触发的特定站点事件:

    在 devtools 控制台中运行 getEventListeners(document) 并检查输出。

    yt-navigate-start 是我们在这种情况下所需要的。

    注意事项:

    • 对于我们可能想要的其他任务yt-navigate-finish
    • 旧的 youtube 设计使用 spfdone event

ma​​nifest.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

document.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>');
}

【讨论】:

  • 供参考,这里是后台脚本方式的例子:stackoverflow.com/a/21071357/72321
  • 这个解决方案工作正常,但不幸的是只适用于 YouTube 旧设计。
  • 网站上向某些用户显示了一个新的yt-navigate-start 事件。此外,我稍微概括了答案,以解释如何找到实际事件。
  • 你确定他们使用pushState 吗?几天前我因为一个问题而快速浏览了一下(我会发现它回到 VTC 作为这个 btw 的欺骗),但是覆盖了history.pushStatehistory.replaceState,以便在这些方法中包含一个事件发射器根本没有用,即使我在页面加载之前覆盖了。
  • @Kaiido,是的,他们只是使用 hack 通过 iframe 恢复原始 API 绑定:puu.sh/wRIZg/6a3ad30828.png
【解决方案2】:

2017 年答案:

我将它用于新的 Material Design 版本的 Youtube

body.addEventListener("yt-navigate-finish", function(event) {
    // code here
});

这适用于旧 Youtube

window.addEventListener("spfdone", function(e) {
    // code here
});

代码来自我编写的 2 个脚本调用
“Youtube 字幕下载器”和“Youtube 自动字幕下载器”。

它们都有效,我测试过。

如果您对我的脚本感兴趣并想了解更多详情:
https://github.com/1c7/Youtube-Auto-Subtitle-Download

【讨论】:

  • 请注意,此信息包含在现有答案中(尽管它使用yt-navigate-start
  • 是的,这个不讲原理,直接给出代码,我觉得这个答案还是有一定价值的,所以我还是保留这个答案。 :D 谢谢你提到它@Xan
猜你喜欢
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多