Search code examples
javascripthtmlgoogle-chrome-extensionyoutube

Chrome extension - page update twice then removed on YouTube


I want to make a small extension that injects a simple html into a YouTube page right under the video. It works fine if I simple visiting a youtube url. However if I choose a video from youtube offers then my html code is injected twice but removed. I can see that it to appear and then disappear 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');
            });   
        } 
    }
);  

Solution

  • chrome.tabs.onUpdated will also fire for iframes, and for youtube, there are many iframes will trigger this event, besides that, youtube doesn't reload the page when you go from one video to another. For more details about youtube issue, you could take a look at these threads:

    So my recommendation would be using chrome.webNavigation api, and combining webNavigation.onCompleted with webNavigation.onHistoryStateUpdated, sample code would look like the following

    Considering you are detecting youtube video page, I would suggest you used 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");
                }
            });
        }
    });