【问题标题】:Chrome extension - page update twice then removed on YouTubeChrome 扩展程序 - 页面更新两次然后在 YouTube 上删除
【发布时间】:2016-08-16 22:33:04
【问题描述】:

我想制作一个小扩展,将一个简单的 html 注入到视频下方的 YouTube 页面中。如果我简单地访问一个 youtube 网址,它就可以正常工作。但是,如果我从 youtube 提供的视频中选择一个视频,那么我的 html 代码会被注入两次但被删除。我可以看到它几乎立即出现然后消失。

我的代码是:

background.js

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {

    if ( changeInfo.status == 'complete' && tab.status == 'complete' && tab.url != undefined ) {

        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            chrome.tabs.sendMessage(tabs[0].id, {method: "reDraw"}, function(response) {
                console.log("Injection ready!");
            });
        });

    }

});

content.js

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
        if (request.method == "reDraw") {
            $.get(chrome.extension.getURL('/mytest.html'), function(data) {
                $(data).insertAfter('#placeholder-player');
            });   
        } 
    }
);  

【问题讨论】:

    标签: javascript html google-chrome-extension youtube


    【解决方案1】:

    这是一种只使用chrome.webNavigation.onHistoryStateUpdated触发一次的方法

    // background.js
    'use strict';
    
    console.log('QboAudit Background Script');
    
    chrome.runtime.onInstalled.addListener(details => {
      console.log('QboAudit previousVersion', details.previousVersion);
    })
    
    chrome.webNavigation.onHistoryStateUpdated.addListener( (details) => {
      console.log('QboAudit Page uses History API and we heard a pushSate/replaceState.')
      if(typeof chrome._LAST_RUN === 'undefined' || notRunWithinTheLastSecond(details.timeStamp)){
        chrome._LAST_RUN = details.timeStamp
        chrome.tabs.getSelected(null, function (tab) { 
          if(tab.url.match(/.*\/app\/auditlog$/)){
            chrome.tabs.sendRequest(tab.id, 'runQboAuditLog')
          }
        })
      }
    })
    
    const notRunWithinTheLastSecond = (dt) => {
      const diff = dt - chrome._LAST_RUN
      if (diff < 1000){
        return false
      } else {
        return true
      }
    }
    

    简而言之,您创建一个全局变量 chrome._LAST_RUN 来跟踪该事件是否已经在不到一秒前触发。

    // contentscript.js
    chrome.extension.onRequest.addListener((request, sender, sendResponse) => {
      //console.log('request', request)
      if (request == 'runQboAuditLog')
        new QboAuditLog()
    });
    

    【讨论】:

      【解决方案2】:

      chrome.tabs.onUpdated 也会为 iframe 触发,对于 youtube,有许多 iframe 会触发此事件,除此之外,当您从一个视频转到另一个视频时,youtube 不会重新加载页面。有关 youtube 问题的更多详细信息,您可以查看以下主题:

      所以我的建议是使用chrome.webNavigation api,并将webNavigation.onCompletedwebNavigation.onHistoryStateUpdated 结合使用,示例代码如下所示

      考虑到您正在检测 youtube 视频页面,我建议您使用 chrome.webNavigation.onHistoryStateUpdated

      // To handle youtube video page
      chrome.webNavigation.onHistoryStateUpdated.addListener(function(details) {
          if(details.frameId === 0) {
              // Fires only when details.url === currentTab.url
              chrome.tabs.get(details.tabId, function(tab) {
                  if(tab.url === details.url) {
                      console.log("onHistoryStateUpdated");
                  }
              });
          }
      });
      

      【讨论】:

      • 这个解决方案在大多数情况下都可以正常工作,但我刚刚意识到一个流行的 chrome 扩展程序会阻止此事件触发,因此我的扩展程序无法正常工作。
      • @Vmxes,更多细节?
      • 在我安装“适用于 YouTube 的 Magic Actions 6.9.0.0”之前,您的解决方案运行良好。如果启用此扩展,则不会触发 onHistoryStateUpdated 事件或未访问我的扩展侦听器。
      • 我可以将它添加到我的内容脚本中还是应该在背景页面上?
      【解决方案3】:

      我猜 youTube 在某些页面上使用 Ajax 调用来加载内容,因此您的代码正在被 Ajax 响应替换。

      使用 setTimeout() 函数在几秒钟后检查您的代码是否在页面上,如果不在,请重新添加。

      【讨论】:

        猜你喜欢
        • 2019-12-19
        • 1970-01-01
        • 1970-01-01
        • 2013-07-12
        • 2013-01-26
        • 1970-01-01
        • 1970-01-01
        • 2012-01-10
        相关资源
        最近更新 更多