javascript - 如何在YouTube上检测页面导航并无缝修改其外观?

标签 javascript google-chrome google-chrome-extension

我正在制作一个简单的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网站上,有几种方法可以检测页面转换:

使用后台页面脚本的

  • :webNavigation APItabs API
  • 使用内容脚本: transitionend event用于视频页面上的进度表
  • ,使用内容脚本和视频导航上触发的特定于站点的事件:

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

    enter image description here

    在这种情况下,我们需要 yt-navigate-start

    笔记:
  • 用于我们可能需要的其他任务 yt-navigate-finish
  • 旧的youtube设计使用 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/

    相关文章:

    asp.net - OnClientClick ="return confirm(' 你确定要删除吗');"

    javascript - chrome - 从浏览器控制台运行 javascript 函数 "undefined"

    javascript - Chrome 扩展程序 - 如何将 DOM 从内容脚本发送到后台页面?

    google-chrome-extension - Chrome 扩展 : How to get key events

    javascript - 执行简单的 javascript 作为 chrome 插件

    javascript - Aurelia - 在插槽内引用自定义元素 View 模型

    javascript - 如何使用 angularjs 延迟加载 google jsapi 图表?

    google-chrome-extension - Chrome 扩展程序 background.html 中的 Google Analytics 跟踪

    javascript - 删除显示 HTML 字符的 elementFromPoint()

    javascript - 检查用户是否已在 Jquery 中滚动到底部 [代码无法在 Chrome 上运行]