当前位置:  开发笔记 > 编程语言 > 正文

如何在Youtube上检测页面导航并在呈现页面之前修改HTML?

如何解决《如何在Youtube上检测页面导航并在呈现页面之前修改HTML?》经验,为你挑选了2个好方法。

我正在制作一个简单的Chrome扩展程序,以在YouTube播放列表中添加每个视频的长度,并在页面中插入总长度.我已经成功了,但我的脚本仅在刷新页面后才起作用,但在网站导航时却不起作用.但这不是很方便.

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

示例链接:https://www.youtube.com/playlist?list = PL_8APVyhfhpdgMJ3J80YQxWBMUhbwXw8B

PS我的问题与在greasemonkey脚本中显示后立即修改元素(不是在页面完全加载后)后的问题不同?因为我已经尝试过MutationObserver并且问题是相同的 - 需要刷新才能显示对网页的更改:

var observer = new MutationObserver(function(mutations) {
    for (var i=0; i

wOxxOm.. 19

Youtube网站不会在导航上重新加载页面,它会替换历史状态.

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

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

使用后台页面脚本:webNavigation API,tabs API

使用内容脚本:视频页面上的进度表transitionend事件

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

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

在此输入图像描述

yt-navigate-start是我们所需要的.
请注意,在某些情况下仍然显示旧的youtube设计使用spfdone事件


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"
  }]
}

请注意,当我们在加载内容脚本document_start就会使我们的DOMContentLoaded收听稍早些的运行相比,在内容脚本注入的默认行为后小幅 DOMContentLoaded.随着document_start内容脚本时没有什么文件中运行body,甚至没有任何head元素.document但是,附加一个监听器是可能的.

content.js:

window.addEventListener("spfdone", process); // old youtube design, just in case    
window.addEventListener("yt-navigate-start", process); // new youtube design

document.addEventListener("DOMContentLoaded", process); // one-time early processing
window.addEventListener("load", postProcess); // one-time late postprocessing 

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

    postProcess我们附加的功能在load打开网站时只运行一次.在加载所有脚本后,将其用于页面的一次性处理.



    1> wOxxOm..:

    Youtube网站不会在导航上重新加载页面,它会替换历史状态.

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

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

    使用后台页面脚本:webNavigation API,tabs API

    使用内容脚本:视频页面上的进度表transitionend事件

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

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

    在此输入图像描述

    yt-navigate-start是我们所需要的.
    请注意,在某些情况下仍然显示旧的youtube设计使用spfdone事件


    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"
      }]
    }
    

    请注意,当我们在加载内容脚本document_start就会使我们的DOMContentLoaded收听稍早些的运行相比,在内容脚本注入的默认行为后小幅 DOMContentLoaded.随着document_start内容脚本时没有什么文件中运行body,甚至没有任何head元素.document但是,附加一个监听器是可能的.

    content.js:

    window.addEventListener("spfdone", process); // old youtube design, just in case    
    window.addEventListener("yt-navigate-start", process); // new youtube design
    
    document.addEventListener("DOMContentLoaded", process); // one-time early processing
    window.addEventListener("load", postProcess); // one-time late postprocessing 
    

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

    postProcess我们附加的功能在load打开网站时只运行一次.在加载所有脚本后,将其用于页面的一次性处理.



    2> NamNamNam..:

    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

    推荐阅读
    赛亚兔备_393
    这个屌丝很懒,什么也没留下!
    DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
    Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有