2

I am having problem with binding a jQuery event to gmail 'body'

$('body').on('click', function(event) {
        console.log("Entered function");
});

Visit IMDB.com (for example) and in Google Chrome developer console paste in the above code. When you click on the page, you can see "Entered function" printed on the console.

But when I try the same with gmail, I get the following message:

TypeError: Object #<HTMLBodyElement> has no method 'on'

What is going on with gmail, and how do I work around this?

EDIT :-

Non JQuery Version:

document.addEventListener("click", function() {
   console.log("Entered function");
}, false);

Like the commenters have pointed out, jQuery is not loaded with Gmail, here is a non jQuery version, it works when you click on gmail, but when you click on a link (open an email with some links in them) it doesn't work anymore.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
jason
  • 3,471
  • 6
  • 30
  • 43
  • Does Gmail really use jQuery? – Álvaro González Apr 12 '13 at 21:16
  • Your updated event listener assumes that the event is actually making it to the document level. It's likely something in gmail is trapping the event and preventing it from bubbling up to document. – PaulProgrammer Apr 12 '13 at 22:10
  • 1
    @jason In your [previous question](http://stackoverflow.com/questions/15868627/clicking-a-link-in-gmail-doesnt-trigger-my-jquery-event-what-can-i-do-to-fix-i), I said (in a comment) that you have to use `addEventListener` with capture=true. The third argument must be true in order to listen to the event at capture phase. – Rob W Apr 13 '13 at 09:18
  • @RobW thanks for this suggestion, it worked! could you add it as an answer, so I can accept it. – jason Apr 13 '13 at 18:16

4 Answers4

4

Most DOM events, including the click event are dispatched as follows:

  1. Capture phase (from document(window, document, document.documentElement, ...) down the tree to the clicked element).
  2. Bubble phase (from the clicked element up the tree to document ..., window).

Events bound with jQuery are always triggered in #2, at the bubbling phase. Gmail appears to bind an event add capture phase, and calls event.stopPropagation(); when the user clicks on <a> elements. This methods stops the propagation of the event, so jQuery will never know about the event because #2 never occurs.

So, drop jQuery and use vanilla JavaScript to bind the event:

document.addEventListener('click', function(event) {
    // Do whatever you want
}, true);

By setting the third argument of addEventListener to true, the listener is triggered at capture phase.


Regarding the jQuery error (from the question):
Gmail doesn't load jQuery, so you cannot use it. Usually, you would get ReferenceError: "$ is not defined". Instead, you saw "TypeError: Object # has no method 'on'", because $ is defined as a shorthand for document.querySelector in Chrome's developer tools when the page doesn't declare $.

If you included jQuery with your extension, it can be used by switching to the appropriate context. For more details, see Why will jQuery not load in Facebook?

Community
  • 1
  • 1
Rob W
  • 341,306
  • 83
  • 791
  • 678
1

I poked around what gmail is loading, and it appears that gmail doesn't load jquery.

PaulProgrammer
  • 16,175
  • 4
  • 39
  • 56
1

Not all websites use jQuery. If you want to have access to a specific jQuery library version you're going to need to load that so you have access to it in your extension.

Justin Helgerson
  • 24,900
  • 17
  • 97
  • 124
  • You actually always need to load you own. Chrome extensions don't have access to any of the javascript on the page, including libraries. That means it doesn't matter if a website uses jQuery or not. – BeardFist Apr 12 '13 at 21:27
  • Probly I am getting the Jquery from some other browser extensions then. But if you load Jquery into the console in IMDB and try, you should be able to re-create it the above error message. – jason Apr 12 '13 at 21:40
1

So I tested it, and it works just fine. Like I said in my comment, you need to inject jQuery yourself in all cases. You cannot access the page's javascript, nor any javascript from other extensions. Some example code:

manifest.json

{
  "name": "Gmail jQuery Test",
  "version": "0.1",
  "description": "Gmail jQuery Test",
  "manifest_version": 2,
  "permissions": [
    "https://mail.google.com/*"
  ],
  "content_scripts": [{
    "matches": ["https://mail.google.com/*"],
    "js": ["jquery.js", "script.js"],
    "all_frames": true
  }]
}

script.js

$('body').on('click', function(event) {
  console.log("Entered function");
});

This shows the message on the inbox page, and inside of any message and other pages.

BeardFist
  • 8,031
  • 3
  • 35
  • 40