How to detect page navigation on YouTube and modify its appearance seamlessly?

前端 未结 2 920
自闭症患者
自闭症患者 2020-11-22 11:03

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 scrip

2条回答
  •  星月不相逢
    2020-11-22 11:17

    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(window) 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:

    window.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', '
  • Length: ' + timeHMS + '
  • '); }

提交回复
热议问题