2

How can I get a reference to the click handler of an element in JQuery?

Here is what I am trying to do:

Store the click handler, Change the click handler for the next click, Restore the original click handler

var originalClick = $(settings.currentTarget).click;
$(settings.currentTarget).off("click");

$(settings.currentTarget).click(function (e) {
    e.preventDefault();
    settings.model.modal.close();

    $(settings.currentTarget).off("click");
    $(settings.currentTarget).click(originalClick);
});

The above code works the first time, however, when I click on the element again it fails:

 Uncaught TypeError: Object [object HTMLAnchorElement] has no method 'on' 

Update:
I now realize that this is a really bad design that I am trying to do. I have resolved this issue by maintaining a visibility boolean in my viewmodel, if it is true, don't re-open the modal.

mcottingham
  • 1,926
  • 2
  • 18
  • 28
  • `$(settings.currentTarget).click` is the function you are binding the event handler with. It is not the event handler itself. How was the original event handler bound? With jQuery or any other way? – Felix Kling Jun 19 '13 at 20:24
  • @FelixKling the original click handler was bound using knockout. – mcottingham Jun 19 '13 at 20:25
  • This might be able to help: http://stackoverflow.com/questions/2518421/jquery-find-events-handlers-registered-with-an-object – musicnothing Jun 19 '13 at 20:26
  • So you used a `click` binding? I don't know how it works internally but I assume knockout is using `addEventListener`. There is no way to get a reference to handlers bound this way. – Felix Kling Jun 19 '13 at 20:27
  • I think you're getting that message because you're calling `$(settings.currentTarget).off("click");` again during the click and never called .On first. It looks like it was already .off as you have at the top. – Panama Jack Jun 19 '13 at 20:28
  • @Pjack .off should be removing the click handler on line 4, then I should be adding a new click handler using the original function. – mcottingham Jun 19 '13 at 20:30
  • @FelixKling is there anyway to accomplish what I am trying to do if knockout uses addEventListener? – mcottingham Jun 19 '13 at 20:31

2 Answers2

7

$(...).click is the jQuery click() method, not your event handler.

You can use an undocumented internal API to get the list of event handlers:

jQuery._data( elem, "events" );
Community
  • 1
  • 1
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

What happens if you try it this way?

  var originalClick = $(settings.currentTarget).click;
    $(settings.currentTarget).off("click");

    $(settings.currentTarget).on("click",function (e) {
        e.preventDefault();
        settings.model.modal.close();

        $(settings.currentTarget).off("click");
        $(settings.currentTarget).click(originalClick);
    });
Panama Jack
  • 24,158
  • 10
  • 63
  • 95
  • Unfortunately that gives me the same thing. I think that what I need to do is get this new click handler to execute before the original one and stopPropagation, just not sure how to do that. – mcottingham Jun 19 '13 at 20:51
  • I don't think you're using .Off() correctly. Why are you trying to unbind something that you haven't bound yet? From the jQuery documentation `The off() method removes event handlers that were attached with .on().` The first time you call it, you never attached it with .on() first. You might be mixing things. – Panama Jack Jun 19 '13 at 21:02
  • Can you give more info on what you're trying to do? What is `settings.currentTarget`? Also I noticed you said you were using knockout.js. Any reason this part can't be done with jQuery? – Panama Jack Jun 19 '13 at 21:17
  • Using `var originalClick = $(settings.currentTarget).click;` doesn't make sense. `jQuery.fn.click` is a jQuery method, not an event handler. You cannot bind it as event handler. – Felix Kling Jun 19 '13 at 21:30
  • @FelixKling I know, that is what I told him. I think he used knockout or something to bind initially. – Panama Jack Jun 19 '13 at 22:07