-1

I want to replace an old .live() function with .on().

.live()

 var jqRow = $('#' + id + ' tr');
 jqRow.live("click", function () {
            myFunction(this);
            return false;
        });

.on()

var jqRow = $('#' + id + ' tr');
$(document).on("click", jqRow, function () {
                    myFunction(this);
                    return false;
        });

The this of the .live() method returns a JS object (I need this). The this of the .on() method returns a jQuery object, that causes myFunction to fail.

How can I get the same non jQuery this object like in the live function?

Keith L.
  • 2,084
  • 11
  • 41
  • 64
  • 2
    Are you positive that `this` is a jQuery object? `this` in JavaScript is immutable so it cannot possibly be set to a jQuery object, as far as I'm aware. – Jack Franklin Aug 20 '12 at 09:03
  • @JackFranklin this can have different values depending on how function is called for example. – Peter Aug 20 '12 at 09:04
  • I have been tested this script and `console.log(this)` returns an JS `document` object, not jQuery object – Kir Aug 20 '12 at 09:05
  • 1
    I understand that, but I didn't think it was possible to set it to a jQuery object, as `this` is always set based on the scope in which the function was invoked. @Keith L, could you put an example on JSFiddle? – Jack Franklin Aug 20 '12 at 09:05

5 Answers5

3

If this is really a jQuery object, you can use this[0] or this.get(0):

The .get() method grants us access to the DOM nodes underlying each jQuery object.

Blender
  • 289,723
  • 53
  • 439
  • 496
3

Your syntax is incorrect, your jqRow variable is a jQuery object, but the .on() function only takes string selectors. If you pass a jQuery object, that argument is ignored, and it's the same as setting up a non-delegated event handler on the document itself.

Change this:

var jqRow = $('#' + id + ' tr'); // this line creates a jQuery object
$(document).on("click", jqRow, function () {
    myFunction(this);
    return false;
});

to this:

var jqRow = '#' + id + ' tr'; // this line initialises a string
$(document).on("click", jqRow, function () {
    myFunction(this);
    return false;
});
Anthony Grist
  • 38,173
  • 8
  • 62
  • 76
  • Not true, `on()` can take a jQuery selector as the second argument. See: http://jsfiddle.net/2W8pM/ – Jack Franklin Aug 20 '12 at 09:15
  • @JackFranklin Using `e.target` isn't the same as using `this`, your jsFiddle is meaningless. Take a look at [this one](http://jsfiddle.net/2W8pM/1/), that actually matches the code in the question. – Anthony Grist Aug 20 '12 at 09:17
  • @JackFranklin To make that clearer: when you pass anything other than a string as an argument, it's ignored (because it's invalid) and you get a direct event handler attached to the `document` for `click` events. jQuery will make `this` the document itself, but `e.target` will be the element that was originally clicked on and caused the event to propagate up the DOM all the way to the document. – Anthony Grist Aug 20 '12 at 09:20
  • Anthony, my apologies, I misread. You are indeed correct, have amended my answer. – Jack Franklin Aug 20 '12 at 09:31
3

Following on from my comment, it's not possible for this to be a jQuery object. This is because the value of this within a function is set when the function is invoked, and cannot explicitly be set, it's immutable. It is possible for $(this) to be a jQuery object though, obviously.

EDIT

As @Anthony Grist pointed out, the real issue here is using a jQuery selector in .on(). If you change it to pass in a string selector, the value of this is set accordingly. My apologies for the oversight, here's a working JSFiddle.

For what it's worth, if you're delegating to a single selector, I would just call .on() on that selector:

$("#foo").on("click", function() {});

Otherwise...

If you're unable to pass in the string selector and have to pass in an actual jQuery object, you can work around it using the event object. This code works:

var jqRow = $('#foo');
$(document).on("click", jqRow, function (e) {
  myFunction(e.target);
  return false;
});

var jqRow2 = $('#bar');
jqRow2.live("click", function () {
  myFunction(this);
  return false;
 });


function myFunction(x) {
  console.log(x);
  console.log($(x).attr("id"));
}

Working JSFiddle

Remember, with the syntax you're using there for delegating does not bind an event to jqRow, it binds it to the document. jQuery doesn't let you pass in a jQuery object as to be delegated to. So the first part of the above code is fairly pointless, you could just do:

var jqRow = $('#foo');
$(document).on("click", function (e) {
  if($(e.target).attr("id") === "foo") {
    myFunction(e.target);
  }
  return false;
});

This is why the value of this within your .on() is not the object clicked, as you expected as jQuery can't delegate the event to a jQuery object, it needs a selector. So passing in e.target should fix your issue.

Jack Franklin
  • 3,765
  • 6
  • 26
  • 34
  • That's incorrect - `this` will be the element that was actually clicked on *provided* you correctly use `.on()` - passing a jQuery object is invalid. Using `e.target` is a workaround for not knowing how to actually use jQuery. – Anthony Grist Aug 20 '12 at 09:21
2

you can use get() function, which takes index as parameter or you can use [].

var jqRow = $('#' + id + ' tr');
$(document).on("click", jqRow, function () {
                    myFunction(this.get(0));
                    // or this myFunction(this[0]);
                    return false;
        });
Peter
  • 240
  • 1
  • 4
  • 12
0

Use

$(document).ready(function()
{ 
    var id="" ;  // ID of your Element
     var jqRow = $('#' + id);
      jqRow.on("click", 'tr', function ()
      {
                //alert($(this));
                myFunction($(this));
                return false;
       });


 });​

GajendraSinghParihar
  • 9,051
  • 11
  • 36
  • 64