Detecting and handling a button on an active HTML page

I am currently creating a WebExtension for Firefox that displays a small div on the active HTML page on the active tab after 6 seconds (and not popup.html in browser_action !). I made a small example that shows a button in a div. My problem is that I don’t know how to detect the click event of this button so that I can run the function? The moment I am processing 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 will be sent to content.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); 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 does not work. I also created a javascriptForButtonEvent.js JavaScript file with an event listener for the button and added this script to the content_script manifest. Also, to insert this file in the background script, for example:

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

But these solutions did not work for me (nothing happens when a button is pressed). Is there a way to handle events from an active HTML page?

0
source share
1 answer

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

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

When entering scripts, unless you explicitly inject into document_start , your script will be guaranteed to be entered at least after DOMContentLoaded already running. 1 Given that the event has already been fired and only fires once, your DOMContentLoaded listener DOMContentLoaded never called. As a result of how the injection works, you do not need to listen to the DOMContentLoaded event DOMContentLoaded all. Just move your initialization so that it runs in the main sequence of your code (after adding the button):

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

No need to search for the <button> that you create

However, in this case, you add this button yourself. No need to look for it in the DOM. You already have a link to it. Add a listener during button creation:

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

Do not use generic identifiers or classes

For extensions, you should not use identifiers or classes that are common as button_id . This gives a good chance that you will have a clash of names with random pages into which you enter content. You must select the sequence of text that you use as the "namespace". You can then add this namespace to all identifiers and classes. For example, your identifier should look something like this: Study06-button_id . Exactly what you use is a personal choice. But this should be specific to the extension you are working on.

When listening to DOMContentLoaded you should check readyState

Each time you use the DOMContentLoaded or the window load listener, you should always check document.readyState so that you add a listener before the DOMContentLoaded event DOMContentLoaded (or load if that is what you are listening to). This should be a normal habit when you want to listen to these events. If you add a listener after the event has been fired, the listener will never be fired.

To add a DOMContentLoaded listener DOMContentLoaded 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. } 

  • Note that when using tabs.executeScript() you will have to seriously work when executing tabs.executeScript() in the time frame when the script is actually entered into document_start . The exact time it takes is different for different browsers. If you use manifest.json content_script , this time is handled by the browser.
0
source

Source: https://habr.com/ru/post/1266366/


All Articles