我想做一个小扩展,将一个简单的html注入到视频正下方的YouTube页面中。如果我简单地访问 youtube 网址,它可以正常工作。但是,如果我从 youtube 优惠中选择视频,那么我的 html 代码会注入两次但被删除。我可以看到它几乎立即出现然后消失。
我的代码是:
背景.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!");
});
});
}
});
内容.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');
});
}
}
);
chrome.tabs.onUpdated
也会触发iframes,对于YouTube,有很多iframe会触发此事件,除此之外,当您从一个视频转到另一个视频时,YouTube不会重新加载页面。有关YouTube问题的更多详细信息,您可以查看以下线程:
- https://bugs.chromium.org/p/chromium/issues/detail?id=165854
- Chrome webNavigation.onComplete不起作用?
- chrome扩展程序chome.tabs.on更新运行两次?
chrome.webNavigation
api,并将webNavigation.onCompleted
与webNavigation.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.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()
});
我猜 youTube 在某些页面上使用 Ajax 调用来加载内容,因此您的代码被替换为 Ajax 响应。
使用 setTimeout() 函数在几秒钟后检查您的代码是否在页面上,如果没有,请再次添加它。