如何检测 YouTube 上的页面导航并无缝修改其外观? [英] How to detect page navigation on YouTube and modify its appearance seamlessly?

查看:22
本文介绍了如何检测 YouTube 上的页面导航并无缝修改其外观?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

是否可以在浏览器中呈现 HTML 之前检测到 YouTube 上的页面导航并将 HTML 插入页面,以便立即显示添加的内容而没有任何延迟并且不需要刷新页面?

示例链接:

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

注意事项:

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

ma​​nifest.json:

<代码>{名称":YouTube 播放列表长度",版本":0.0.1",manifest_version":2,说明":…………",内容脚本":[{匹配":[*://*.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')) {返回;}var seconds = [].reduce.call(document.getElementsByClassName('timestamp'),功能(总和,ts){var minsec = ts.textContent.split(':');返回总和 + minsec[0] * 60 + minsec[1] * 1;},0,);如果(!秒){console.warn('没有时间戳.空播放列表?');返回;}var timeHMS = new Date(seconds * 1000).toUTCString().split(' ')[4].replace(/^[0:]+/, '');//修剪前导零document.querySelector('.pl-header-details').insertAdjacentHTML('beforeend', '<li>Length: ' + timeHMS + '</li>');}

I'm making a simple Chrome extension to add up the length of each video in a YouTube playlist and insert the total length in the page. I've succeeded at that, but my script only works after refreshing a page but not when the site is navigated. That's not very convenient though.

Is it possible to detect page navigation on YouTube and insert HTML into the page before it's rendered in the browser so that the added content is shown immediately without any delay and no page refresh is required?

Example link: https://www.youtube.com/playlist?list=PL_8APVyhfhpdgMJ3J80YQxWBMUhbwXw8B

P.S. My question is not the same as Modify elements immediately after they are displayed (not after page completely loads) in greasemonkey script? because I've tried MutationObserver and the problem is the same - a refresh is needed to show changes to the web page:

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 site doesn't reload pages on navigation, it replaces the history state.

The extension's content scripts aren't reinjected when URL changes without a page being reloaded. Naturally when you reload a page manually the content script is executed.

There are several methods to detect page transitions on Youtube site:

  • using a background page script: webNavigation API, tabs API

  • using a content script: transitionend event for the progress meter on video pages

  • using a content script and a site-specific event triggered on video navigation:

    Run getEventListeners(document) in devtools console and inspect the output.

    yt-navigate-start is what we need in this case.

    Notes:

    • for other tasks we might want yt-navigate-finish
    • the old youtube design was using 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"
  }]
}

Note: the matches key encompasses the entire youtube.com domain so that the content script runs when the user first opens the home youtube page then navigates to a watch page.

content.js:

document.addEventListener('yt-navigate-start', process);

if (document.body) process();
else document.addEventListener('DOMContentLoaded', process);

The process function will alter the page.
Note, the specified element classes and structure will change in the future.

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

这篇关于如何检测 YouTube 上的页面导航并无缝修改其外观?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆