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

前端 未结 2 830
自闭症患者
自闭症患者 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', '<li>Length: ' + timeHMS + '</li>');
    }
    
    0 讨论(0)
  • 2020-11-22 11:23

    2017 answer:

    I use this for new Material Design version Youtube

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

    and this for old Youtube

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

    code come from 2 script I wrote call
    "Youtube subtitle downloader" and "Youtube auto subtitle downloader".

    both of them work, I tested.

    if you are interested in my script and want know more detail:
    https://github.com/1c7/Youtube-Auto-Subtitle-Download

    0 讨论(0)
提交回复
热议问题