leitmotif
leitmotif

Reputation: 23

adding a click event listener to all elements - Firefox Add-on

i want to assign a click handler to all html elements in page. but after user clicked my addon button, not at pageload.

below is the starting point. i couldn't manage to assign a global click handler. any ideas?? thanks.

var buttons = require('sdk/ui/button/action');

var button = buttons.ActionButton({
  id: "fieldResolver",
  label: "Field Resolver",
  icon: {
    "16": "./icon-16.png",
    "32": "./icon-32.png",
    "64": "./icon-64.png"
  },
  onClick: handleClick
});

function handleClick() {

}

when i use jquery i get this error, so jquery is not an option: Message: ReferenceError: $ is not defined either document object is not available

Upvotes: 0

Views: 990

Answers (2)

ZER0
ZER0

Reputation: 25322

First of all, the code of your add-on is living in a different, more privileged context than the code of the page – in the close future, they'll be also two different process – So you do not have access directly to the page: you have to use a content script. I suggest to you to read carefully the page linked, because it will provide to you how they can communicate each other.

Said that, the idea to me would be: When the user click on a button, attach a content script to the current page, if there isn't already. In the content script, listen for the click event, and do your stuff.

Here the example for your main.js

const { ActionButton } = require("sdk/ui/button/action");
const { data } = require("sdk/self")
const tabs = require('sdk/tabs');

let button = ActionButton({
  id: "fieldResolver",
  label: "Field Resolver",
  icon: {
    "16": "./icon-16.png",
    "32": "./icon-32.png",
    "64": "./icon-64.png"
  },
  onClick: handleClick
});

function handleClick() {
  // get the current tab
  let tab = tabs.activeTab;

  // you would probably want to store worker somewhere to be sure
  // that you won't attach more than once
  let worker = tab.attach({
    contentScriptFile: data.url("content.js")
  });
}

As you can see, you need a contentScriptFile, that has to be in your add-on's data folder. Your content.js will looks like:

function clickHandler (event) {
  // do something with the element clicked
  console.log(event.target.outerHTML);
}

window.addEventListener("click", clickHandler);

// We want to clean the page if the worker is destroyed
self.port.on("detach", function() {
  window.removeEventListener("click", clickHandler);
})

You can remove the worker calling worker.destroy() anytime. And as I said, you want probably to store the worker somewhere, like a Map, so that you'll attach the script only if there isn't any worker for that tab / url.

Upvotes: 2

Noitidart
Noitidart

Reputation: 37238

Add click listener to the window and then check event.target:

function handleClick() {
    //try using jquery here. if $ doesnt work try window.$
    window.addEventListener('click', intercept, false);
}

function intercept(e) {
    //try using jquery here. if $ doesnt work try window.$ or try e.target.ownerDocument.defaultView.$
    var elementClicked = e.target;
    console.log('elementClicked = ', elementClicked);
    elementClicked.style.border = '1px solid red';
}

Upvotes: 0

Related Questions