检测 Google Chrome 扩展的 browser_action 表单中的按钮点击

Posted

技术标签:

【中文标题】检测 Google Chrome 扩展的 browser_action 表单中的按钮点击【英文标题】:Detect a button click in the browser_action form of a Google Chrome Extension 【发布时间】:2021-12-27 20:10:58 【问题描述】:

如此简单的事情怎么会如此不可能?

我想要做的就是单击我的扩展程序的 browser_action 按钮,打开一个带有几个设置的表单,然后单击表单上的按钮来启动一个进程。

我这辈子都无法让后台表单中的按钮点击工作。

我试图让http://developer.chrome.com/extensions/contentSecurityPolicy.html#H2-3 的示例工作,但它没有。 browser_action 和 background 的规则有区别吗?这就是我的事件监听器没有触发的原因吗?

有人可以提供一个工作示例吗?

manifest.json:


    "name": "Convert",
    "version": "0.1",
    "description": "Converts the current page",
    "browser_action": 
        "default_icon": "exticon.png",
        "default_popup": "background.html"
    ,
    "content_scripts": [
        "matches": ["*://*/*"],
        "js": ["contentscript_static.js"]
    ],
    "permissions": [
        "tabs", "http://*/*", "https://*/*"
    ]

背景.html:

<html>
    <head>
        <title>Converter</title>
        <script src="background.js"/>
        <script>
        // Initialize the localStorage
        if (null == localStorage["htmlImport"])
           localStorage["htmlImport"] = false;

        // Called when the user clicks on the browser action icon.
        chrome.browserAction.onClicked.addListener(function(tab) 
            console.log('in listener');
                 // execute the content script
                 chrome.tabs.executeScript(null, 
                    
                       file: "contentscript.js",
                       allFrames: true   // It doesn't work before 4.0.266.0.
                    );
              );

        // Listen to the requests from the content script
        chrome.extension.onRequest.addListener(
              function(request, sender, sendResponse)
              
                 switch (request.name)
                 
                    case "getPreferences":
                       sendResponse(
                          
                             prefIgnoreLinks : localStorage["htmlImport"]
                          );
                       break;

                    case "PressShortcut":
                       sendResponse();  // don't response.

                       // execute the content script
                       chrome.tabs.executeScript(null, 
                          
                             file: "contentscript.js",
                             allFrames: true   // It doesn't work before 4.0.266.0.
                          );

                       break;

                    default:
                       sendResponse();  // don't response.
                       break;
                 
              );


        </script>
    </head>
    <body style='min-width:250px;'>
        Link depth: <input type='text' name='depth' value='3'/><br/>
        <input type='checkbox' name='changedomain'>Include external domains</input><br/>
        <button id='beginConvert'>Convert</button>
    </body>
</html>

background.js:

function awesome() 
  // Do something awesome!
  console.log('awesome')

function totallyAwesome() 
  // do something TOTALLY awesome!
  console.log('totallyAwesome')


function awesomeTask() 
  awesome();
  totallyAwesome();


function clickHandler(e) 
  setTimeout(awesomeTask, 1000);

// Add event listeners once the DOM has fully loaded by listening for the
// `DOMContentLoaded` event on the document, and adding your listeners to
// specific elements when it triggers.
//document.addEventListener('DOMContentLoaded', function () 
//  document.querySelector('button').addEventListener('click', clickHandler);
//);

// Add event listeners once the DOM has fully loaded by listening for the
// DOMContentLoaded event on the document, and adding your listeners to
// specific elements when it triggers.
document.addEventListener('DOMContentLoaded', function () 
//  console.log('event listener for button connected to beginConversion()');
    //document.querySelector('button').addEventListener('click', beginConversion);
    document.getElementById('beginConvert').addEventListener('click', clickHandler);
);

【问题讨论】:

分享您拥有的代码或简化的示例将大大提高每个人帮助您的能力。如果您正在关注链接到的页面上的示例之一,您使用的是哪一个? 添加了代码示例,这样像 Mike 这样的非透视开发者也可以参与其中。 ;-) 您的 manifest.json 文件引用了“contentscript_static.js”,但未包含在您的问题中。 让 background.html 成为弹出窗口的内容不是一个好主意。弹出窗口应该有一个不同的 html 文件。 您已将 JS 嵌入到您的 background.html 文件中。我认为这违反了要求从外部文件导入 JS 的新 contentSecurityPolicy(在 Manifest V2 中)。不再允许嵌入。 【参考方案1】:

你的目标

点击扩展按钮 扩展弹出窗口打开时带有控件 根据扩展弹出窗口中的控件在当前选项卡上执行脚本

提示

将背景页面视为控制中心。它接收来自您的 Chrome 扩展程序中各种脚本的传入请求,具有更高的权限来执行跨域请求(如果在清单中定义)等操作。 您应该使用manifest version 2,因为不推荐使用版本 1。 清单版本 2 不允许内联脚本,因此所有脚本都需要作为自己的文件加载。

示例

manifest.json


    "name": "*** Popup Example",
    "manifest_version": 2,
    "version": "0.1",
    "description": "Run process on page activated by click in extension popup",
    "browser_action": 
        "default_popup": "popup.html"
    ,
    "background": 
        "scripts": ["background.js"]
    ,
    "permissions": [
        "tabs", "http://*/*", "https://*/*"
    ]

background.js

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) 
        switch (request.directive) 
        case "popup-click":
            // execute the content script
            chrome.tabs.executeScript(null,  // defaults to the current tab
                file: "contentscript.js", // script to inject into page and run in sandbox
                allFrames: true // This injects script into iframes in the page and doesn't work before 4.0.266.0.
            );
            sendResponse(); // sending back empty response to sender
            break;
        default:
            // helps debug when request directive doesn't match
            alert("Unmatched request of '" + request + "' from script to background.js from " + sender);
        
    
);

popup.html

<html>
    <head>
        <script src="popup.js"></script>
        <style type="text/css" media="screen">
            body  min-width:250px; text-align: center; 
            #click-me  font-size: 20px; 
        </style>
    </head>
    <body>
        <button id='click-me'>Click Me!</button>
    </body>
</html>

popup.js

function clickHandler(e) 
    chrome.runtime.sendMessage(directive: "popup-click", function(response) 
        this.close(); // close the popup when the background finishes processing request
    );


document.addEventListener('DOMContentLoaded', function () 
    document.getElementById('click-me').addEventListener('click', clickHandler);
)

contentscript.js

console.log("chrome extension party!");

运行示例截图

在浏览器窗口打开到 exampley.com 的情况下单击扩展按钮

点击“点击我!”后扩展弹出窗口中的按钮


zip 中的示例文件

http://mikegrace.s3.amazonaws.com/***/detect-button-click.zip

【讨论】:

非常感谢,迈克!您帖子中的来源与 .zip 文件的内容有区别吗?我问的原因是因为 .zip 文件似乎已损坏或无效。 没有区别。再试一次,它现在应该可以工作了。另外,如果它帮助或解决了您的问题,请不要忘记投票并接受。 谢谢,迈克,这很有帮助!我接受了答案。不幸的是,我的名声比能够投票的答案差两点。当我不再是一个无名小卒时,我会回来做这件事。 :-) 很高兴为您提供帮助。你现在应该有足够的代表了; ) 我有一个问题:在 contentscript.js 中,我如何访问 popup.html 的 HTML 元素?【参考方案2】:

以前的答案不再有效,我花了几个小时才了解如何管理解决方法。我希望这能让你比我走得更快。

首先,你在this页面(在页面底部)的最后一个方法,它是异步的,所以记得给它一个回调。您需要的代码是这样的 smtg:

chrome.browserAction.onClicked.addListener(function (tab) 
    chrome.tabs.query('active': true, getActiveTabCallback);
);

第二,您需要了解一件让我费时费力的事情:如果您不使用背景 html 页面,您将无法在 Chrome 主窗口中看到任何 console.log .你需要去扩展页面 (chrome://extensions) 并点击你的扩展 background page 链接(是的,你没有背景页面,但 Chrome 给你一个假的)。这种类型的扩展(基于事件)应该具有包含 smtg 的 manifest.json,如下所示:

"background": 
    "scripts": ["background.js"],
    "persistent": false
,

问候!

【讨论】:

以上是关于检测 Google Chrome 扩展的 browser_action 表单中的按钮点击的主要内容,如果未能解决你的问题,请参考以下文章

centos-stream-9安装chrome谷歌浏览器

centos-stream-9安装chrome谷歌浏览器

检测活动标签是Chrome扩展程序中的新标签

在microsoft边缘扩展中未定义chrome

Google禁止从第三方网站安装Chrome扩展程序

带有 Chrome 扩展的 Google 日历 API