page_action 单击不起作用,而 browser_action 单击在 Chrome 扩展中起作用?

page_action click does not work while browser_action click works in Chrome Extension?

我想制作一个简单的浏览器扩展程序,例如 Font Face Ninja,它会在单击 page_actionbrowser_action 时切换 UI。

以下使用 browser_action 的代码有效 -

background.js

chrome.browserAction.onClicked.addListener(function(tab) {
  console.log(`clicked browserAction`)
})

manifest.json

{
    ...
    "browser_action": {
    "default_icon": {
      "19": "icon19.png",
      "38": "icon38.png"
    }
  },
    ...
}

虽然以下使用 page_action 的代码不起作用 -

background.js

chrome.pageAction.onClicked.addListener(function(tab) {
  console.log(`clicked pageAction`)
})

manifest.json

{
    ...
    "page_action": {
    "default_icon": {
      "19": "icon19.png",
      "38": "icon38.png"
    }
  },
    ...
}

根据MDN docs,

Page actions are like browser actions, except that they are associated with particular web pages rather than with the browser as a whole. If an action is only relevant on certain pages, then you should use a page action and display it only on relevant pages. If an action is relevant to all pages or to the browser itself, use a browser action.

确认我想使用 page_action 但它不起作用。

如何使用 page_action 使其工作?

页面操作

可以在我的 Github 上找到让 page_action 工作的方法 → https://github.com/deadcoder0904/insert-remove-ui-chrome-extension/tree/page_action

background.js

var hasExecutedOnce = false

function addUI(tabId) {
  chrome.tabs.sendMessage(tabId, {
    from: 'background',
    subject: 'isUIAdded?',
  })
}

chrome.runtime.onInstalled.addListener(function() {
  chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
    chrome.declarativeContent.onPageChanged.addRules([
      {
        conditions: [
          new chrome.declarativeContent.PageStateMatcher({
            pageUrl: { hostEquals: 'www.google.co.in' },
          }),
        ],
        actions: [new chrome.declarativeContent.ShowPageAction()],
      },
    ])
  })
})

chrome.pageAction.onClicked.addListener(function(tab) {
  if (!hasExecutedOnce) {
    chrome.tabs.executeScript(
      tab.id,
      {
        file: 'contentScript.js',
      },
      function() {
        addUI(tab.id)
      },
    )
    hasExecutedOnce = true
  }
  addUI(tab.id)
})

contentScript.js

var body = document.getElementsByTagName('body')[0]

function insertUI() {
  var div = document.createElement('div')
  div.setAttribute('id', 'sample-extension-12345')
  div.innerHTML = `<h1>Sample Extension</h1>`
  body.appendChild(div)
}

function removeUI() {
  document.getElementById('sample-extension-12345').remove()
}

function main() {
  chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.subject === 'isUIAdded?') {
      const id = document.getElementById('sample-extension-12345')
      if (id === null) insertUI()
      else removeUI()
    }
  })
}

main()

浏览器操作

在master分支上也有browser_action的解决方案→https://github.com/deadcoder0904/insert-remove-ui-chrome-extension/

background.js

var hasExecutedOnce = false

function addUI(tabId) {
  chrome.tabs.sendMessage(tabId, {
    from: 'background',
    subject: 'isUIAdded?',
  })
}

chrome.browserAction.onClicked.addListener(function(tab) {
  if (!hasExecutedOnce) {
    chrome.tabs.executeScript(
      tab.id,
      {
        file: 'contentScript.js',
      },
      function() {
        addUI(tab.id)
      },
    )
    hasExecutedOnce = true
  }
  addUI(tab.id)
})

contentScript.js

var body = document.getElementsByTagName('body')[0]

function insertUI() {
  var div = document.createElement('div')
  div.setAttribute('id', 'sample-extension-12345')
  div.innerHTML = `<h1>Sample Extension</h1>`
  body.appendChild(div)
}

function removeUI() {
  document.getElementById('sample-extension-12345').remove()
}

function main() {
  chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.subject === 'isUIAdded?') {
      const id = document.getElementById('sample-extension-12345')
      if (id === null) insertUI()
      else removeUI()
    }
  })
}

main()