Avoid dynamically injecting the same script multiple times when using chrome.tabs.executeScript(…)

前端 未结 2 530
既然无缘
既然无缘 2020-12-10 18:18

I\'m building a Google Chrome extension. The basic setup is I have a Browser action button that injects jQuery and another bit of JavaScript into the active tab when it is

2条回答
  •  有刺的猬
    2020-12-10 18:41

    I believe the better way might be to do it on extension level. If you include third party libraries, then you would be re-including them as well, and never know what happens then.

    contentScript.js

    (function () {
    
      var Sz = Sizzle;
    
      //listen for events from the extension
      chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    
        if (!request._extension || request._extension !== 'my-extension-name') {
          console.log('Non extension request');
          return;
        }
    
        var channel = (request._channel) ? request._channel : false;
    
        if (channel === 'is-loaded') {
    
          sendResponse({isLoaded: true});
          return true;
    
        } else if (channel === 'example') {
          //do stuff 
        }
    
        return true;
    
      });
    
      //other code goes here
    
    });
    

    Background.js

    var util = {};
    
    util.sendMessage = function (data, cb) {
    
      chrome.tabs.query({active: true, currentWindow: true}, tabsQuery_cb);
    
      data['_extension'] = 'my-extension-name';
    
      function tabsQuery_cb(tabs) {
    
        var tab = tabs[0];
    
        console.log('sending message to ' + tab.id);
        console.log(data);
    
        //let the content script know to open the ad page
        chrome.tabs.sendMessage(tabs[0].id, data, cb);
    
      }
    
    }
    
    util.loadContentScript = function(cb) {
    
      var attempts = 0;
    
    
      checkIfLoaded();
    
       //checks if ContentScript is loaded by sending a message to the current
      function checkIfLoaded() {
    
        util.sendMessage({ _channel: 'is-loaded'}, sendMessage_cb);
    
      }
    
      function sendMessage_cb(response) {
    
        console.log('isLoadedCheck')
        console.log(response);
    
        if (response && response.isLoaded === true) {
          console.log('Script already loaded!');
          cb(true);
        } else {
          console.log('loading scripts');
          loadScripts();
        }
    
      }
    
      function loadScripts() {
    
        attempts++;
        console.log('loadScripts, attempt no. ' + attempts);
    
        if (attempts > 1) {
          console.log('Script couldnt be loaded');
          return cb(false);
        }
    
        var scripts = [
          "assets/sizzle-2.3.4.min.js",
          "app/contentScript.js"
        ];
    
        var i = -1;
    
        scriptLoaded();
    
        function scriptLoaded() {
    
          i++;
    
          if (i > scripts.length) {
            //all scripts have loaded at this point, check if replies with message
            checkIfLoaded();
          } else {
            console.log('Loading script ' + scripts[i]);
            chrome.tabs.executeScript(null, { file: scripts[i] }, scriptLoaded);
          }
    
    
        }
    
      }
    
    }
    

    Of course including third party libraries seems like a bad practice anyway, because it can skew with website's scripts. But what other way is there. Perhaps you could go to the extreme, and create a bootstrap content script which would check for presence of libraries and tell the extension script what exactly needs to be included. That's what I would consider on a more serious project.

提交回复
热议问题