2

As an exercise, I'm trying to add an event listener to an ebay.com element.

Expected result: show an alert and stop the web page from going to the next URL.

What happens: the alert is shown but the next URL is shown anyway.

I found something interesting on the product pages where I'm testing out preventDefault, stopPropagtion and stopImmediatePropagation.

No matter which combinations I use, nothing seem to work.

The basic code is:

$('#binBtn_btn').click(function(evt){
    alert('hi');
    evt.stopPropagation(); //or any other option.
});

The thing is that I get the alert, but it still goes to the next page, as if I never stopped the propagation.

I read a lot of articles about event handling, but I couldn't find the answer. Your help is much appreciated.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
alexunder
  • 2,075
  • 3
  • 16
  • 29
  • What does the element look like? – PeterKA Nov 09 '14 at 16:45
  • It's an add to cart button. – alexunder Nov 09 '14 at 16:52
  • 1
    How about you create an example of your problem first in a JSFiddle. Trying to attach events on random sites isn't a productive way to understand Events in JavaScript. – istos Nov 09 '14 at 16:55
  • Read http://stackoverflow.com/questions/18147242/event-preventdefault-vs-event-stoppropagation – vmontanheiro Nov 09 '14 at 18:45
  • @vcrzy it's not the same question... these are different things. If you would try doing what it says there, you won't be able to stop their functionality. I suggest you look at dave salomon's answer below. It works. – alexunder Nov 09 '14 at 19:08

2 Answers2

1

try using evt.preventDefault() like this:

$('#binBtn_btn').click(function(evt){ 

    evt.preventDefault();
    alert('hi');  

});

Then it will not go to the next page.

1

My best guess it that the Button has its own click handler, and it's firing before yours.

$('#binBtn_btn').data("events") shows us that there is indeed a click event. Remove that using off.

$('#binBtn_btn').off('click');

Clicking the button now will still cause the form the submit, as all we're doing is browsing to a page. The button is actually just an a tag.

$('#binBtn_btn').click(function(e){
    alert('Gotcha!');
    e.preventDefault();
});

Let's see what happens if we remove their handler, add ours, and then re-add their one...

var existing = $('#binBtn_btn').data('events').click[0];
$('#binBtn_btn').off('click');
$('#binBtn_btn').click(function(e){ alert('foo'); e.stopImmediatePropagation(); return false; });
$('#binBtn_btn').data('events').click.push(existing);

Same, but just looking at the function for the click handler (rather than tweaking the events.click array directly...)

var existing = $('#binBtn_btn').data('events').click[0].handler;
$('#binBtn_btn').off('click');
$('#binBtn_btn').click(function(e){ alert('foo'); e.stopImmediatePropagation(); e.preventDefault(); });
$('#binBtn_btn').click(existing);

As expected, what is now the second handler -- their handler -- doesn't first. (I've added a return false; rather than e.preventDefault();, just to demonstrate different ways of doing things!)

You can check out what they're doing by placing a breakpoint and viewing the existing var above. You'll see that at the end of their function, they do indeed call e.preventDefault();.

Hope this helps.

Dave Salomon
  • 3,287
  • 1
  • 17
  • 29
  • There's still something that is unclear. Maybe you can clarify that for me. According to my understanding, e.stopImmediatePropagation(); should, well, stop immediate propagation. so basically, if my alert is fired, it's not suppose to fire anything else. Can you help me with an explanation? Thanks. – alexunder Nov 09 '14 at 18:19
  • @alex No worries. I believe this is due to the ordering of the click handlers. The first one is firing before yours can get to `stopImmediatePropagation();`. I've updated my answer with a test, which shows this is likely to be the case. If your one fires first, the existing one doesn't fire (if we add it back AFTER your one.) – Dave Salomon Nov 09 '14 at 18:38
  • Thank you for your assistance. You've been a great help. One more question please - regarding your last paragraph. How did you manage to break on their code and how did you got to see their function? – alexunder Nov 09 '14 at 19:05
  • 1
    @alex, I've set up a blog, and my [first post](http://davesalomon.com/blog/2014/11/09/basic-debugging/) is specially to talk about this. It's bascally F12, viewing the event handlers on the element (well, object), and digging through there. Thanks! – Dave Salomon Nov 09 '14 at 21:30
  • I kept trying this thing on other sites and I found that this method doesn't work on a site like flipkart.com. There, for example, an input element is used, and everything is processed in AJAX. When I use $().data('events') i get undefined. why is that? – alexunder Nov 10 '14 at 14:34
  • `.data("events")` was removed in jQuery 1.8. You'll probably find them in `$._data($(elem), 'events');`. It work's on eBay 'cos they're using an old version. – Dave Salomon Nov 10 '14 at 15:17
  • Is there a way to make it work on a site like flipkart? Cause there it's a different mechanism. – alexunder Nov 10 '14 at 16:23
  • `$('.btn-buy-now').click(function(e){ alert('foo'); return false; });` works for http://www.flipkart.com/huawei-honor-t1/p/itmdzvf2cgvghuat?pid=TABDZVBFP9CFGB6K . Based on the fact that there's no click handlers present, you can just injector your own without worry. `return false;` will prevent the form being submitted. (As would `e.preventDefault();`) – Dave Salomon Nov 10 '14 at 16:57