1

How can a chrome extension click on a button on active page?

There is banal page on the Web. There is simple element of button type with specific ID on the page. Also there is Chrome extension with a button. I'd like to click to extension button and the button in turn clicks to page button.

var someElement = document.getElementById('someElement');
someElement.addEventListener('click', function () {
  // here I'd like to click on a button with specific ID.
});
Xan
  • 74,770
  • 16
  • 179
  • 206
Andrej B.
  • 187
  • 1
  • 5
  • 14
  • "This question body does not meet our quality standards." There is zero effort demonstrated, both in solving and searching for a solution. Take a moment to look through [this guide](http://stackoverflow.com/help/how-to-ask). – Xan Oct 09 '15 at 07:20
  • 1
    Xan, I've tried to find something, but useless. I'd like to know only how to click on button. But SOF forces me to write more than I want. And I wrote SOF's comment. – Andrej B. Oct 09 '15 at 07:45
  • 1
    Tell us what you know already. Tell you what you think the structure of the extension should be. We will not write a whole extension for you, show us which part needs help. – Xan Oct 09 '15 at 07:46
  • We can't read your mind but apparently you need [tabs.executeScript](https://developer.chrome.com/extensions/tabs#method-executeScript) to inject something like `document.getElementById('someElement').click()`, see [Page Redder sample extension](https://developer.chrome.com/extensions/samples#search:executescript). And take a look at the most popular questions to see the examples of properly stated questions. – wOxxOm Oct 09 '15 at 08:11
  • It's not that hard to write a much better question, is it? Now you have a bit of code that you think is relevant, and that shows how much you understand already; also, now the problem is better specified (what should trigger the action and what should happen). – Xan Oct 09 '15 at 08:23

1 Answers1

6

The very first thing you want to do is to read the Overview page, especially the Architecture part. Read it thoroughly, and it will answer many questions you have.

Your problem can be split into two parts.

  1. How to trigger something with a click on your extension.

  2. How to click something inside the active tab.

Before I proceed, I'll reiterate what wOxxOm said: there's a great small example in the docs that does nearly what you want. But if you want to be someone taught to fish, not given a fish, read on.

How to trigger something with a click on your extension

It depends on what kind of UI you're using; the simplest is a Browser Action button.

Simplest button:

If you add a browser action to the manifest without specifying a popup:

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

then clicking on it will raise chrome.browserAction.onClicked event to your extension's pages. The only page open at any time you need it is a background page, the role of which is usually the central dispatch for extension events. So, you need a background page that listens to that event:

"background": {
  "scripts": ["background.js"]
},

and

// background.js
chrome.browserAction.onClicked.addListener(function(tab) {
  // Okay, the actual action should go here
  // And look, we already have the required Tab object for free!
});

Variations (exercises for the reader):

  • If you do specify a "default_popup" in your manifest, then chrome.browserAction.onClicked will not trigger. Instead, a small popup page will open with the HTML file you specify; you can add UI/logic there as you wish, the principle will be the same as normal webpages but with Chrome API access, except:

  • If your extension targets only a few specific pages, consider using Page Actions instead of Browser Actions.

  • As noted in the documentation, Event pages are preferable to Background pages. In this case, you can use an Event page easily without any side effects, but in general this may require some thinking.

  • You could inject your own UI into the page itself with Content scripts; this is an advanced topic and will not be covered here.

How to click something inside the active tab

Since you've read the Architecture overview, you already know that the only part of the extension that can interact with the DOM of an open page is a Content script.

Content scripts can either be specified in the manifest (and then they will automatically be injected and ready for you when a matching page is opened), or they can be manually injected into the page.

In your case, you want to do something simple, and only when clicked. This is a perfect job for programmatic injection, so we'll stick with that.

Assuming the solution from the previous section, you are in a context of a background page and already have the current tab as the tab variable:

// background.js
chrome.browserAction.onClicked.addListener(function(tab) {
  // Do something with tab
});

Programmatic injection is done with chrome.tabs.executeScript method. At a minimum, you need to specify the tab you want to inject to, and the code that will be run:

// background.js
chrome.browserAction.onClicked.addListener(function(tab) {
  chrome.tabs.executeScript(tab.id, {
    code: "document.getElementById('#specificId').click()"
  });
});

That's not all yet though. The extension must have permissions to execute code in an open tab.

You could use "host permissions" that are defined by a match pattern to give access to specific pages, but remember that we are only triggering it when the user clicks the extension.

For that specific case, there's a special permission "activeTab". It is sufficient to do a lot of things with the currently active tab when the extension is explicitly invoked, and clicking its button is explicit enough.

So, add to manifest:

"permissions": ["activeTab"],

And that should be all you need for this to work.

Extra credit:

  • While not necessary for this simple purpose, you may want more complicated code than a single line to be executed in the tab. Then it makes sense to use a separate file and invoke executeScript with "file" instead of "code".

  • Just triggering a click on a button does not require you to directly interact with JavaScript running in the page itself, as DOM events are shared. However, it's important to understand that normally, content scripts can't interact with the page's own scripts, which is called "isolated world". There are ways to bypass it if you really need it, but it's an advanced topic better explained elsewhere.

  • Sometimes you need the content script to persist, answer some commands and maybe send its own queries to the extension's pages. In that case, it's probably better to auto-inject through the manifest and use Messaging instead of executeScript.

Community
  • 1
  • 1
Xan
  • 74,770
  • 16
  • 179
  • 206