2017-08-24 56 views
0

我希望我的Chrome扩展程序能够像这样运行:如何使用Background.js更新选项卡然后执行内容脚本?

用户单击该图标,即会显示硬编码的URL“www.example.com”。它不会打开新选项卡,而是更新窗口。然后,我想执行内容脚本并能够在更新的页面上提醒“正在工作”。

这里是我到目前为止有:

Background.js

chrome.browserAction.onClicked.addListener(function(activeTab) 
{ 
chrome.tabs.query({'active': true, 'lastFocusedWindow': true}, function 
(tabs) 
    { 

chrome.tabs.update({ 
url: "http://www.example.com/" 
}); 
}); 
function test() 
{ 
chrome.tabs.executeScript(null, {file: "myscript.js"}); 

} 




chrome.tabs.onUpdated.addListener(function(tabid, changeinfo, tab) { 
var url = tab.url; 
    if (url !== undefined && changeinfo.status == "complete") { 

    test(); 
} 
}); 
}); 

内容脚本

alert('working'); 

结果是奇数。当我点击图标时,它会提示example.com很好,但是有时候警报有效,有时不会。即使是更奇怪的,如果我双击它,它会更频繁地工作,但如果我点击它一堆,警报加起来,然后我一次获得许多警报(我只是想要一个)。

回答

1
  • content.js可以设置一个全局变量,所以你可以检查它跳过回注。

    if (window[chrome.runtime.id]) { 
        alert('Oi! Reinjected.'); 
    } else { 
        window[chrome.runtime.id] = true; 
        alert('Oi!'); 
    } 
    
    // do something 
    

    根据您的内容脚本做什么,你可以添加一个message listener,将处理来自你的背景页面,而不是重新运行整个代码的请求。

  • background.js检查活动标签已经被导航到感兴趣的部位(或浏览到它),注入的内容脚本(注释掉inject();跳过回注)。

    检查本身很简单:注入一个内容脚本代码来检查全局变量。此代码与给定页面的其他内容脚本(isolated world)在相同的上下文中运行。

    const SITE_URL = 'http://www.example.com'; 
    
    chrome.browserAction.onClicked.addListener(tab => { 
        if (tab.url === new URL(SITE_URL).href) { 
        checkIfInjected(tab).then(tab => { 
         console.log('already injected in %d, reinjecting anyway', tab.id); 
         inject(tab); 
        }).catch(inject); 
        } else { 
        updateTabAndWaitForStart(tab.id, {url: SITE_URL}) 
         .then(inject); 
        } 
    }); 
    
    function checkIfInjected(tab) { 
        return runContentScript(tab.id, { 
        code: 'window[chrome.runtime.id]', 
        }).then(results => { 
        resolve(results[0] ? tab : Promise.reject(tab)); 
        }); 
    } 
    
    function inject(tab) { 
        return runContentScript(tab.id, { 
        file: 'content.js', 
        runAt: 'document_end', 
        allFrames: false, 
        }); 
    } 
    
    function runContentScript(tabId, options) { 
        return new Promise(resolve => { 
        chrome.tabs.executeScript(tabId, options, resolve); 
        }); 
    } 
    

    // onUpdated listener waits for our tab to get an URL, detaches on success 
    

    function updateTabAndWaitForStart(tabId, options) { 
        return new Promise(resolve => { 
        chrome.tabs.update(tabId, options, newTab => { 
         chrome.tabs.onUpdated.addListener(
         function onUpdated(updatedId, info, updatedTab) { 
          if (updatedId === newTab.id && info.url) { 
          chrome.tabs.onUpdated.removeListener(onUpdated); 
          resolve(updatedTab); 
          } 
         } 
        ); 
        }); 
        }); 
    } 
    
  • manifest.json的应该包含您导航到和活动标签的网站权限。

    当然,像<all_urls>这样的较大权限会包含这些内容,但确切列表的优势在于,扩展程序网店中的安装警告仅显示网站。

    *在网站URL权限是可选的(作用与每个API设计相同)。
    最后/是强制性的(这是一条路径)。

    { 
        "name": "test", 
        "version": "0.0.1", 
        "manifest_version": 2, 
        "description": ".............", 
        "background": { 
        "scripts": ["background.js"], 
        "persistent": false 
        }, 
        "browser_action": { 
        "default_title": "click me" 
        }, 
        "permissions": ["activeTab", "http://www.example.com/*"] 
    } 
    
相关问题