检测并处理活动HTML页面中的按钮单击 [英] Detect and handle a button click in the active HTML page

查看:117
本文介绍了检测并处理活动HTML页面中的按钮单击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在为Firefox创建一个WebExtension,它在6秒后在活动选项卡上的活动HTML页面中显示一个小格子(而不是 browser_action中的 popup.html !)。我做了一个小例子,在div中显示一个按钮。我的问题是,我不知道如何检测此按钮的 click 事件,以便我可以启动一个函数?在我处理content.js事件监听器的那一刻,

manifest.json:

  {
manifest_version:2,
name:Study06,
version:1.0,
description:我的网络扩展,
权限:[
标签,
all_urls>,
报警
],
background:{
scripts:[background.js]
}
}

background.js:

  browser.alarms.create( ,{delayInMinutes:0.1}); 
browser.alarms.onAlarm.addListener(injectScript);
function getActiveTab(){
return browser.tabs.query({active:true,currentWindow:true});
}
函数injectScript(){
getActiveTab()。then((tabs)=> {
browser.tabs.executeScript(null,{
file: /content.js
});
//发送消息给contentscript
browser.tabs.sendMessage(tabs [0] .id,{message:Hello});
});
}

6秒后,content.js将被加载并发送消息给内容。 js将被发送。



content.js:

document.addEventListener('DOMContentLoaded',function(){
var button = document.getElementById('button_id');
button.addEventListener('click',function(){
console.log(CLICK);
});
});

browser.runtime.onMessage.addListener(createModal);

函数createModal(){
document.getElementsByTagName('body')[0] .appendChild(modal1);
}

//使用按钮$ b $创建div div modal1 = document.createElement(div);
modal1.style.paddingTop =100px;
modal1.setAttribute(id,mymodal1);
modal1.style.position =fixed;
modal1.style.top = 0;
modal1.style.left = 0;
modal1.style.zIndex = 1000000;
modal1.style.overflow =auto;
var button1 = document.createElement(button);
button1.setAttribute(id,button_id);
button1.innerHTML =点击我;
modal1.appendChild(button1);

content.js 中的事件侦听器不起作用。
我还为按钮创建了一个JavaScript文件 javascriptForButtonEvent.js ,并在清单 content_script 中添加了此脚本。另外,要将该文件注入后台脚本中,如下所示:

$ b

  browser.tabs.executeScript(null, {
file:/content.js;
file:/javascriptForButtonEvent.js
});

但是,这些解决方案并不适合我(单击按钮时没有任何反应)。有没有办法处理来自活动HTML页面的事件?

解决方案

您的点击事件侦听器永远不会被添加到DOM。你有:

document.addEventListener('DOMContentLoaded',function(){

在注入脚本时,除非您明确注入 document_start ,您的脚本保证是在> DOMContentLoaded 之后注入了至少 1 鉴于事件已经被触发,并且只触发一次,您的 DOMContentLoaded 侦听器从不被调用。由于注入的工作原理,您不需要监听 DOMContentLoaded 事件,只需移动你的初始化,使其在你的代码的主要序列中执行(添加按钮后):

 的document.getElementById( 'button_id')。的addEventListener( '点击',函数(){
console.log(CLICK);
});



不需要搜索<按钮> 你创建



但是,在这种情况下,你自己添加了这个按钮。没有必要在DOM中搜索它。你已经有一个参考。在创建按钮时添加侦听器:
$ b

  var button1 = document.createElement( '按钮'); 
button1.id ='button_id';
button1.textContent ='点击我';
button1.addEventListener('click',function(){
console.log(CLICK);
});
modal1.appendChild(button1);



不要使用通用的ID或类

对于扩展,您不应该使用与 button_id 一样通用的ID或类。这样做很可能会导致与注入内容的随机页面发生名称冲突。你应该选择一个你用作命名空间的文本序列。然后,您可以将此名称空间添加到所有ID和类。例如,你的ID应该是这样的: Study06-button_id 。确切地说,你使用的是个人选择。但是,它应该是特定于你正在开发的扩展。



当收听 DOMContentLoaded ,你应该检查 readyState



任何时候使用 DOMContentLoaded 侦听器或窗口 load listener,你应该总是检查 document.readyState ,以确保您在 DOMContentLoaded 事件之前添加侦听器被解雇(或者 load 事件,如果那是你正在听的话)。当你想听这些事件时,这应该是正常的习惯。如果在事件触发后添加侦听器,侦听器将永远不会运行。



添加 DOMContentLoaded 听众,你应该使用类似于:


$ b

  if(document.readyState ==='loading' ){
document.addEventListener('DOMContentLoaded',afterLoaded);
} else {
afterLoaded();
}

函数afterLoaded(){
// DOM最初加载后需要发生的一切。

$ / code>







  1. 请注意,使用 tabs.executeScript() ,您必须认真地 work 让您的 tabs.executeScript()执行在脚本实际上在 document_start 注入的时间范围内。所需的确切时间对于不同的浏览器而言是不同的。如果您使用 manifest.json content_script 条目,则此时间由浏览器处理。


Currently, I am creating a WebExtension for Firefox which displays a small div in the active HTML page on the active tab after 6 seconds (not the popup.html in browser_action!). I made a small example that shows a button in the div. My problem is that I don't know how to detect a click event of this button so I can kick off a function? In the moment I handle the event listener in content.js

manifest.json:

{
  "manifest_version": 2,
  "name": "Study06",
  "version": "1.0",
  "description": "My web extension",
  "permissions": [
  "tabs",
    "<all_urls>",
    "alarms"
  ],
  "background": {
    "scripts": ["background.js"]
  }
}

background.js:

browser.alarms.create("", {delayInMinutes: 0.1});
browser.alarms.onAlarm.addListener(injectScript);
function getActiveTab() {
  return browser.tabs.query({active: true, currentWindow: true});
}
function injectScript() {
  getActiveTab().then((tabs) => {
    browser.tabs.executeScript(null, {
      file: "/content.js"
    });
    // send message to contentscript
    browser.tabs.sendMessage(tabs[0].id, {message: "Hello"});
  });
}

After 6 seconds, content.js will be loaded and a message to content.js will be sent.

content.js:

document.addEventListener('DOMContentLoaded', function() {
  var button = document.getElementById('button_id');
  button.addEventListener('click', function() {
    console.log("CLICK");
  });
});

browser.runtime.onMessage.addListener(createModal);

function createModal(){
  document.getElementsByTagName('body')[0].appendChild(modal1);
}

//create div with button
var modal1 = document.createElement("div");
modal1.style.paddingTop = "100px";
modal1.setAttribute("id", "mymodal1");
modal1.style.position = "fixed";
modal1.style.top = 0;
modal1.style.left = 0;
modal1.style.zIndex = 1000000;
modal1.style.overflow = "auto";
var button1 = document.createElement("button");
button1.setAttribute("id", "button_id");
button1.innerHTML = "Click me";
modal1.appendChild(button1);

The event listener in content.js is not working. I also created a JavaScript file javascriptForButtonEvent.js with an event listener for the button and added this script in manifest content_script. Also, to inject this file in background script like:

browser.tabs.executeScript(null, {
      file: "/content.js";
      file: "/javascriptForButtonEvent.js"
    });

But, these solutions didn't work for me (when clicking the button nothing happens). Is there a way to handle events from the active HTML page?

解决方案

Your click event listener never gets added to the DOM. You have:

document.addEventListener('DOMContentLoaded', function() {

When injecting scripts, unless you are explicitly injecting at document_start, your script is guaranteed to be injected at least after DOMContentLoaded has already fired.1 Given that the event has already fired, and only fires once, your DOMContentLoaded listener is never called. As a result of how injection works, you do not need to listen for the DOMContentLoaded event at all. Just move your initialization such that it executes in the main sequence of your code (after you add the button):

document.getElementById('button_id').addEventListener('click', function() {
    console.log("CLICK");
});

No need to search for the <button> you create

However, in this case, you are adding this button yourself. There is no need to go searching for it in the DOM. You already have a reference to it. Add the listener at the time you are creating the button:

var button1 = document.createElement('button');
button1.id = 'button_id';
button1.textContent = 'Click me';
button1.addEventListener('click', function() {
    console.log("CLICK");
});
modal1.appendChild(button1);

Don't use generic IDs or classes

For extensions, you should not use IDs or classes that are as generic as button_id. Doing so results in a good chance that you will have a name collision with the random pages into which you are injecting content. You should pick a sequence of text which you use as a "namespace". You can then prepend this namespace to all IDs and classes. For instance, your ID should be something like: Study06-button_id. Exactly what you use is a personal choice. But, it should be specific to the extension you are working on.

When listening for DOMContentLoaded, you should check readyState

Any time you use a DOMContentLoaded listener, or a window load listener, you should always check the document.readyState to make sure that you are adding the listener prior to the DOMContentLoaded event being fired (or load event, if that is what you are listening for). This should be normal habit when you want to listen for these events. If you add the listener after the event has fired, the listener will never be run.

For adding a DOMContentLoaded listener, you should use something like:

if(document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded',afterLoaded);
} else {
    afterLoaded();
}

function afterLoaded(){
    //Everything that needs to happen after the DOM has initially loaded.
}


  1. Note that when using tabs.executeScript() you have to seriously work at having your tabs.executeScript() execute in a time-frame where the script is actually injected at document_start. The exact timing that is needed is different for different browsers. If you use a manifest.json content_script entry, this timing is handled by the browser.

这篇关于检测并处理活动HTML页面中的按钮单击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆