I am trying to create a chrome extension that will click on an element on a webpage when you click a button on the extension, but for some reason it does nothing no matter what I try.
I've got this so far
manifest.json
{ "manifest_version": 2, "name": "Such Activity", "description": "Wow", "version": "1.0", "permissions": [ "tabs", "<all_urls>" ], "browser_action": { "default_icon": "icon.png", "default_popup": "popup.html" }, "content_scripts": [ { "matches": [ "<all_urls>" ], "js": ["content_script.js"] } ] }
popup.html
<!doctype html> <html> <head> <title>activity</title> <style> </style> <script src="content_script.js"></script> </head> <body> <button id="clickactivity">click</button> </body> </html>
content_script.js
function ClickPlanet() { var planets = document.getElementsByClassName("planet-name"); var randomplanet = Math.floor(Math.random() * planets.length); var clickplanet = planets[randomplanet]; clickplanet.click(); setInterval(function () { ClickPlanet() }, 2000); } document.addEventListener('DOMContentLoaded', function () { document.getElementById('clickactivity').addEventListener('click', ClickPlanet); });
All I seem to be getting is this error
Uncaught TypeError: Cannot read property 'click' of undefined
I've been fiddling around with this for hours, but I can't get it to work. Any and all help is appreciated!
On click — meaning the extension is able to see and alter what's in your browser only when you actively click it (and then only for the site that's currently open in that specific tab)
Looks like you are misunderstanding the content script's behavior.
Quoting the official documentation:
Content scripts are JavaScript files that run in the context of web pages. By using the standard Document Object Model (DOM), they can read details of the web pages the browser visits, or make changes to them.
So, using your content_script.js
in your popup.html
doesn't make much sense, and obviously results in an error because you don't have any button with class="planet-name"
in your popup.html
page.
To do what you want, you need to create a different script for your popup.html
, and add a listener to that button, so when it gets clicked, you can inject the content_script.js
script into the page to click the "planet" element.
So you'll have to:
manifest.json
removing the "content_scripts"
field.popup.js
file to add in your popup.html
page.popup.js
to inject the content_script.js
file using chrome.tabs.executeScript()
(Manifest V2) or chrome.scripting.executeScript()
(Manifest V3).content_script.js
to make it click the button directly on the page.NOTE: since January 2021, you should use the new Manifest V3. See below for an up-to-date answer if you are using Manifest V3.
First of all, edit your manifest.json
, it should look like this:
{ "manifest_version": 2, "name": "Such Activity", "description": "Wow", "version": "1.0", "permissions": ["tabs", "<all_urls>"], "browser_action": { "default_icon": "icon.png", "default_popup": "popup.html" } }
Then, remove your content_script.js
from the popup.html
and replace it with the popup.js
script:
<!doctype html> <html> <head><title>activity</title></head> <body> <button id="clickactivity">click</button> <script src="popup.js"></script> </body> </html>
Create the popup.js
script and add the listener to the button that will inject the script into the current page:
function injectTheScript() { chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { // query the active tab, which will be only one tab //and inject the script in it chrome.tabs.executeScript(tabs[0].id, {file: "content_script.js"}); }); } document.getElementById('clickactivity').addEventListener('click', injectTheScript);
Now, in your content_script.js
, you'll need to click the button directly, and also you will not need to use DOMContentReady
, because Chrome waits to inject the script by itself. So, your new content_script.js
will be:
function clickPlanet() { var planets = document.getElementsByClassName("planet-name"), randomplanet = Math.floor(Math.random() * planets.length), clickplanet = planets[randomplanet]; clickplanet.click(); } clickPlanet();
Edit your manifest.json
, it should look like this:
{ "manifest_version": 3, "name": "Such Activity", "description": "Wow", "version": "1.0", "permissions": ["scripting"], "host_permissions": ["<all_urls>"], "action": { "default_title": "Click Me", "default_popup": "popup.html" } }
Then, remove your content_script.js
from the popup.html
and replace it with the popup.js
script:
<!doctype html> <html> <head><title>activity</title></head> <body> <button id="clickactivity">click</button> <script src="popup.js"></script> </body> </html>
Create the popup.js
script and add the listener to the button that will inject the script into the current page:
function injectTheScript() { // Wuery the active tab, which will be only one tab and inject the script in it. chrome.tabs.query({active: true, currentWindow: true}, tabs => { chrome.scripting.executeScript({target: {tabId: tabs[0].id}, files: ['content_script.js']}) }) } document.getElementById('clickactivity').addEventListener('click', injectTheScript)
Now, in your content_script.js
, you'll need to click the button directly, and also you will not need to use DOMContentReady
, because Chrome waits to inject the script by itself. So, your new content_script.js
will be:
const planets = document.getElementsByClassName("planet-name") const elementToClick = planets[Math.floor(Math.random() * planets.length)] elementToClick.click()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With