Chrome extension - page refresh twice and then removed on YouTube

I want to make a small extension that introduces simple html to a YouTube page right below the video. It works fine if I just find the YouTube URL. However, if I select a video from youtube offers, then my html code is entered twice but deleted. I see him appearing and then disappearing almost immediately.

My code is:

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'); }); } } ); 
+2
source share
3 answers

chrome.tabs.onUpdated also works for iframe, and for youtube there are many iframes that will trigger this event, in addition, youtube does not reload the page when you switch from one video to another. For more information about the problem with youtube, you can take a look at these threads:

So my recommendation would be to use chrome.webNavigation api and combine webNavigation.onCompleted with webNavigation.onHistoryStateUpdated , the sample code would look like this

Given that you discover the youtube video page, I suggest you use 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"); } }); } }); 
+7
source

I think youTube uses Ajax calls on some pages to load things, so your code is replaced with an Ajax response.

Use the setTimeout () function to check in a few seconds if your code is on the page, if not, add it again.

0
source

Here is just one way to use it only once using 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 } } 

In short, you are doing a global var chrome._LAST_RUN to track whether this event was already fired less than a second ago.

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

Source: https://habr.com/ru/post/1210115/


All Articles