2

I want to make a generic plugin, that has the following logic:

  1. Look for #add-to-cart button Save previously attached click handler(Idon't have access to this code)
  2. Attach plugin's click handler, that shows popup with email opt-in.
  3. After successful opt-in trigger the original click handler.

I don't have access to the website's code, so I have to make a generic solution.

My implementation looks like this:

var $addToCart = $('#add-to-cart');
var origClickHandler = $addToCart.click;
$addToCart.off('click').on('click', function() {
    // code to show opt-in popup ...
    var $optinButton = /* ... */ ;
    $optinButton.click(function() { // binding opt-in button to original click handler
        origClickHandler.apply($addToCart);
    });
});

But I'm getting error on the line origClickHandler.apply($addToCart):

jquery-2.1.1.min.js:4 Uncaught TypeError: this.on is not a function
    at HTMLButtonElement.n.fn.(anonymous function) (http://www.myshop.com/js/jquery-2.1.1.min.js:4:4893)

Update

  • My intent is to bind my plugin's click handler that will further call the original click handler(and not replace the original click handler entirely)
  • I tried to replace .apply() with .call() and got the same error.
  • I tried to replace origClickHandler.apply($addToCart); with $addToCart.off('click').on('click', origClickHandler); $addToCart.click(); and got the same error as well

Update 2

I accomplished what I wanted by cloning the button and hiding the original button:

var $addToCart = $('#add-to-cart');
var $addToCartClone = $addToCart.clone(false); // false - not copying the events and handlers
$addToCart.before($addToCartClone).hide();
$addToCartClone.click(function() {
    // code to show opt-in popup ...
    var $optinButton = /* ... */ ;
    $optinButton.click(function() { // binding opt-in button to original click handler
        $addToCart.click();
    });
});

It seems like when I call .off('click') jquery disables the click handler that was attached and I can't use it anymore. I don't know the reason, but it should work.

I will leave the question unanswered in case anyone finds the reason why original click handler stops working after calling .off('click').

Oleksandr.Bezhan
  • 2,028
  • 3
  • 22
  • 31
  • `$('#add-to-cart').click(function() { .... } );` works quite well. Are you trying to override an existing click handler ? If so, you can do `$('#add-to-cart').off();` or for older jquery `$('#add-to-cart').unbind('click');` before binding to your new method. – Kraang Prime Jan 05 '17 at 19:51
  • 1
    @KraangPrime He doesn't want to stop the old click handler completely, just do an extra check first. – Barmar Jan 05 '17 at 20:16
  • But how are you going to check if a person has already signed up? Or are you just going to annoy everyone, all the time? :) – Serg Chernata Jan 05 '17 at 20:17
  • @Barmar, the first block i provided does that. I gave the additional code to remove the handler with an "**Are you trying to override an existing click handler ? If so, you can do**" following the directions on how to append a new click handler to the same object/event. – Kraang Prime Jan 05 '17 at 20:26
  • @KraangPrime I see I misunderstood. What he actually seems to want is to bind a different button's click handler to the original button's click handler. – Barmar Jan 05 '17 at 20:29
  • 1
    @Barmar - that is not what I am getting out of this, although it is not outside the scope of possibility that you could be correct -- and the question/intent is not clear. -- If that is in fact the case, then this is a Possible duplicate of [jQuery find events handlers registered with an object](http://stackoverflow.com/questions/2518421/jquery-find-events-handlers-registered-with-an-object) – Kraang Prime Jan 05 '17 at 20:33
  • You should be using `.call()`, not `.apply()`. `.apply()` needs a second argument containing an array of arguments. – Barmar Jan 05 '17 at 20:33
  • @Barmar I changed `.apply()` to `.call()` and got the same error. – Oleksandr.Bezhan Jan 06 '17 at 08:56

0 Answers0