【问题标题】:Chrome extension: Add content (enable/disable icon)Chrome 扩展:添加内容(启用/禁用图标)
【发布时间】:2016-12-30 10:34:13
【问题描述】:

我正在为 Google Chrome 编写一个扩展程序,当用户单击插件图标时,我正在尝试在当前页面中添加内容。

我想添加启用/禁用扩展以及显示/隐藏我为每个页面注入的内容的可能性。

ma​​nifest.json

"content_scripts": [
  {
    "matches": [
      "http://*/*",
      "https://*/*"
    ],
    "css": ["css/style.css"],
    "js": [
      "js/content.js"
    ]
  }
]

我看不到如何仅为单击图标的页面添加内容,因为这样,每个页面都有脚本。

我也尝试了后台脚本,但没有成功。

你有什么想法吗?

谢谢!

【问题讨论】:

  • 是添加到页面中的图标,还是您在浏览器工具栏中看到的扩展图标?
  • 我想到了浏览器工具栏。
  • 那么您需要始终包含脚本,但仅在单击按钮时调用您想要运行的任何函数。你不会有条件地包含一些东西——你总是包含它。
  • 不需要在所有页面上都包含内容脚本。这是一个不好的做法。官方Page Redder 示例扩展完全符合您的要求。这个集合有许多其他有用的例子。在您的情况下,您需要 file: "js/content.js" 而不是 Page Redder 中使用的 code: "...."
  • 好的,谢谢,我会看看这个样本。我不喜欢一直包含内容脚本的想法,但如果这是唯一的解决方案……

标签: javascript google-chrome google-chrome-extension


【解决方案1】:

您应该使用chrome.tabs.executeScriptchrome.tabs.insertCSS 来实现此目的。完整示例:

Background.js

chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.insertCSS(tab.id, {file: "content_style.css"});
    chrome.tabs.executeScript(tab.id, {file: "content_script.js"});
});

Manifest.json

{
  "name": "Inject js and CSS",
  "version": "1",
  "manifest_version": 2,
  "browser_action": {
    "default_icon": {
      "16": "icon16.png",
      "19": "icon19.png",
      "32": "icon32.png",
      "38": "icon38.png"
    }
  },
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  "permissions": [
    "activeTab"
  ]
}

编辑:更新为使用 activeTab、事件页面和新的图标大小。

【讨论】:

  • @wOxxOm 感谢您的建议,我已经更新了我的答案。
  • 使用此解决方案,每次用户单击按钮时都会添加脚本。因此,用户可以多次注入内容:-/
  • @vermotr 是的,这个例子可以做到这一点。您可以在注入页面的内容脚本中使用message passing 来检测它是否已经存在并防止再次发送。
【解决方案2】:

你怎么看?

ma​​nifest.json

{
  "manifest_version": 2,

  "name": "Extension",
  "description": "My extension",
  "version": "0.1",

  "icons": {
    "16": "icons/icon_16.png",
    "48": "icons/icon_48.png",
    "128": "icons/icon_128.png"
  },

  "browser_action": {
    "default_title": "Extension",
    "default_icon": "icons/icon_16_disabled.png"
  },

  "background": {
    "scripts": ["js/background.js"],
    "persistent": true
  },

  "permissions": [
    "activeTab",
    "tabs"
  ]
}

background.js

var activedTab = {};
var injectedTab = {};

chrome.browserAction.onClicked.addListener(function(tab) {
  if (typeof activedTab[tab.id] === 'undefined') {
    activedTab[tab.id] = true;
    chrome.tabs.insertCSS(tab.id, {file: 'style.css'});
    chrome.tabs.executeScript(tab.id, {file: 'js/content.js'});
    chrome.browserAction.setIcon({path: 'icons/icon_16.png'});
  } else if (activedTab[tab.id]) {
    activedTab[tab.id] = false;
    chrome.browserAction.setIcon({path: 'icons/icon_16_disabled.png'});
    if (injectedTab[tab.id]) {
      chrome.tabs.sendMessage(tab.id, {greeting: 'hide'});
    }
  } else {
    activedTab[tab.id] = true;
    chrome.browserAction.setIcon({path: 'icons/icon_16.png'});
    if (injectedTab[tab.id]) {
      chrome.tabs.sendMessage(tab.id, {greeting: 'show'});
    }
  }
});

chrome.runtime.onMessage.addListener(function(request, sender) {
  switch (request.greeting) {
    case 'content_injected':
      injectedTab[sender.tab.id] = true;
      if (activedTab[sender.tab.id] == false) {
        chrome.tabs.sendMessage(sender.tab.id, {greeting: 'hide'});
      }
      break;
  }
});

chrome.tabs.onUpdated.addListener(function(tabId) {
  delete activedTab[tabId];
  chrome.browserAction.setIcon({path: 'icons/icon_16_disabled.png'});
});

chrome.tabs.onActiveChanged.addListener(function(tabId) {
  if (activedTab[tabId]) {
    chrome.browserAction.setIcon({path: 'icons/icon_16.png'});
  } else {
    chrome.browserAction.setIcon({path: 'icons/icon_16_disabled.png'});
  }
});

content.js

console.log('loaded');
chrome.extension.sendMessage({greeting: 'content_injected'});

chrome.runtime.onMessage.addListener(function(request) {
  switch (request.greeting) {
    case 'show':
      console.log('show');
      break;
    case 'hide':
      console.log('hide');
      break;
  }
});

【讨论】:

    【解决方案3】:

    我为我的 chrome 扩展程序构建了相同的功能。 这将创建一个开/关开关/切换(搜索谷歌时有这么多名字来解决这个问题:)) 我通过以下方法在应用程序和内容脚本之间使用按摩:

    清单

    在所有页面上插入我的内容脚本 (hover.js) 并运行我的扩展脚本 (background.js)

    ....
    "browser_action": {
        "default_icon": {
          "19": "icons/icon-active.png"
        }
      },
    "content_scripts": [ 
    { 
      "matches": ["<all_urls>"], 
      "css": ["css/hover.css"], 
      "js": ["js/hover.js"] 
    } 
    ],
    "background" : { "scripts": ["js/background.js"] },
    ....
    

    background.js

    在这里,我们正在准备后台脚本(在所有 chrome 窗口上运行)以发送和接收扩展状态

        // start extension as active
    var status = true;
    
    // set toggle of extension on browser action click and notify content script
    chrome.browserAction.onClicked.addListener(function(tabs) {
      if (status == 'true'){
        status = false;
        chrome.browserAction.setIcon({path: "icons/16x16.png"});
      } 
      else{
        status = true;
        chrome.browserAction.setIcon({path: "icons/icon-active.png"});
      }
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        chrome.tabs.sendMessage(tabs[0].id, {status: status});
      });
    });
    
    // check status on tab update and notify content script
    chrome.tabs.onActivated.addListener(function() {
      if (status == 'true'){
        chrome.browserAction.setIcon({path: "icons/icon-active.png"});
      } 
      else{
        chrome.browserAction.setIcon({path: "icons/16x16.png"});
      }
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        chrome.tabs.sendMessage(tabs[0].id, {status: status});
      });
    });
    
    //send extension status on request
    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        if (request.status == "getStatus")
          sendResponse({status: status});
    });
    

    如您所见,有 3 个功能:

    1. 更改浏览器操作按钮单击的状态。

    2. 当您移动到不同的选项卡并通知内容脚本时检查状态(每个选项卡都有自己的内容脚本“实例”,因此在一个选项卡中禁用可能在另一个选项卡中仍处于活动状态)。

    3. 根据内容脚本的请求发送状态响应。

    内容脚本

    // check extension status
    chrome.runtime.sendMessage({status: "getStatus"}, function(response) {
        if (response.status == 'true'){
            // check elements mouse is hover
            document.addEventListener("mouseover", setLink, true);
        }
        else{
            document.removeEventListener("mouseover", setLink, true);
        }
    });
    
    // wait for massage from background script
    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse) {
        if (request.status == 'true'){
            // check elements mouse is hover
            document.addEventListener("mouseover", setLink, true);
        }
        else{
            document.removeEventListener("mouseover", setLink, true);
        }
    });
    

    每个内容脚本应首先通过向后台脚本发送消息来检查扩展程序的状态并接收状态更新。

    另外,如果我们在一个选项卡中关闭扩展,当我们更改选项卡时,我们会通知内容脚本更改。

    我确信这可以在脚本方面做得更好,但我希望它会有所帮助......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-20
      • 1970-01-01
      • 2015-03-07
      • 1970-01-01
      相关资源
      最近更新 更多