2016-04-23 49 views
2

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

我的代码是:

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

回答

7

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"); 
      } 
     }); 
    } 
}); 
+0

该解决方案是工作在大多数情况下细,但我意识到,一个受欢迎的Chrome扩展的一个防止这种事件,火灾等我的分机不能正常工作。 – Vmxes

+0

@Vmxes,更多详情? –

+0

您的解决方案工作正常,直到我安装了“Magic Actions for YouTube 6.9.0.0”。如果启用了此扩展,那么onHistoryStateUpdated事件未被触发或未访问我的扩展侦听器。 – Vmxes

0

我猜YouTube是使用Ajax调用一些页面加载的东西,所以你的代码正在被Ajax响应所取代。

使用setTimeout()函数几秒钟后检查代码是否在页面上,如果没有,则再次添加它。

0

下面是使用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() 
});