26

This question has been asked/answered (mostly) before, BUT I've tried three things to stop the event from bubbling but nothing has worked:

return false;
e.stopPropagation();
e.preventDefault();  

(return false should take care of the other two, correct?)

Here's the html:

<div class="tags-holder">
    <input type="text" class="addField" id="addField_<%= visit.id %>"  placeholder="add a new tag">
</div>

And the JS (UPDATE CLEANED UP):

    $('.addField').show().keyup(function(event){
  event.preventDefault();
  
      if(event.keyCode == 13 || event.keyCode==9) {
    ProfilePage.createTag( this, 'nada', 'addField')
        $(this).hide().val('');

        return false;       
   }

});

I left the redundant stoppers in there but really shouldn't return false simply kill the bubbling? (using Chrome).

Clue? keyCode=13 is "Enter"

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
bear
  • 1,318
  • 5
  • 16
  • 26
  • Why are you doing `$(field).functionCall()` instead of `field.functionCall()`? – Yes Barry Nov 02 '11 at 21:22
  • 1
    I created a [jsFiddle](http://jsfiddle.net/thomas_peklak/dNKZ7/3/) of your code and do not see any problems - what is the behaviour you are trying to prevent? – topek Nov 02 '11 at 21:34
  • thanks. That works; maybe it's something with event bubbling given the DOM (I didn't post the whole page). The issue is that it fires the createTag() function twice, which is problematic :) – bear Nov 02 '11 at 21:41
  • @mmmshuddup I cleaned that up now--thanks for your input. – bear Nov 02 '11 at 21:42
  • You bet! Yeah I tried playing with the jsFiddle too and it's working fine for me! Which browser(s) are having issues? – Yes Barry Nov 02 '11 at 21:46
  • using Chrome @mmmshuddup – bear Nov 02 '11 at 21:47
  • would it be better make this a form and let submit handle it? @topek – bear Nov 02 '11 at 21:49
  • Ok but then I'm confused because you said in parenthesis "(working in Chrome)".. – Yes Barry Nov 02 '11 at 21:49
  • So--I meant I am working in Chrome. The code is not (so I guess I'm not working in Chrome either ;) – bear Nov 02 '11 at 21:55
  • Ohh ok gotcha. I tried this in Chrome as well and it is working (meaning that the block of code in the if statement is only running _once_ after enter is pressed). Are you sure that createTag() is being called twice and not that _the code inside that function_ isn't doing something twice? – Yes Barry Nov 02 '11 at 21:57
  • @mmmshuddup great point--testing... – bear Nov 02 '11 at 22:00
  • I put console.log('please only fire once') on the first line of the function; it fired twice. Appears to be the bubbling. – bear Nov 02 '11 at 22:03
  • also tested removing a form/submit reference. No luck. bubblicious – bear Nov 02 '11 at 22:10
  • I don't think it's bubbling at all. I think you have a nested elements with an .addField class. This might be causing you to assign the function to two different elements that happen to be nested...which in turn looks like bubbling -- but it's not. – mqsoh Nov 03 '11 at 01:49
  • thanks @mqsoh will examine that. – bear Nov 03 '11 at 04:34
  • I woke up this morning and my first thought was 'What the hell was I talking about? That's what bubbling *is*.' Anyway, I think your problem will be solved with input.addField. There's no input nesting and therefore no bubbling. – mqsoh Nov 03 '11 at 11:33
  • thanks @mqsoh I'm taking it apart now. That field is generated in a loop, so there are 15 other instances with that class, though all have different IDs. Frankly it would be easier to add a Save button but I find that extra step unnecessary. – bear Nov 03 '11 at 15:39
  • I think I got it @mqsoh ... see below. – bear Nov 03 '11 at 19:57

9 Answers9

11

I had same issue and I used above method and it work for me.

$(document).unbind('keypress').bind('keypress', function (e) {
   // some logic here
});
Badiparmagi
  • 1,285
  • 1
  • 14
  • 24
Goyat Parmod
  • 131
  • 1
  • 4
11

Wow. Your help was great and helped me think it through.

BUT the solution feels a bit like a cop-out; effective, but the condition should never be there in the first place.

Here it is, which I found in the comments from here: http://yuji.wordpress.com/2010/02/22/jquery-click-event-fires-twice/

    $('.plus').unbind('click').bind('click',function(e){    
console.log('clicked')
    var id=$(this).attr('plus_id');
    var field=$('<input type="text">').attr({'placeholder':'add a new tag','id': 'addField_' + id, 'visit_id':id});
    field.focus();
    field.show().keydown(function(event){
        event.stopImmediatePropagation();
        if(event.keyCode == 13 || event.keyCode==9) {
            console.log(event)
            ProfilePage.createTag( field, 'nada', 'addField')
            field.hide().val('');
            return false;       
        }
    }).click(function(e){
        return false;
    })
    ;
$(this).append(field);
return false;       
   });
bear
  • 1,318
  • 5
  • 16
  • 26
  • Oh weird. So it's working for you now? If so, that's great! But based on that article you posted, it sounds like the issue was having more than $(document).ready() function. What's up with that? – Yes Barry Nov 03 '11 at 20:10
  • 1
    Incidentally, I was reading more about it and it appears that this is a specific issue with setting keyup event handlers. It is *apparently* recommended to use the _keypress_ handler.. http://stackoverflow.com/questions/2387316/jquery-textbox-keyup-firing-twice – Yes Barry Nov 03 '11 at 20:15
  • i'll check that out @mmmshuddup but I think the issue is very specific to the project; it turns out everything on the page is firing extra events. – bear Nov 04 '11 at 01:59
  • so @mmmshuddup, what I posted here works. But it turns out it was an issue in another function that was pulling in additional content. Unbinding the events works, but it's also something that shouldn't be necessary with better implementation IMHO. Thanks for the help! – bear Nov 06 '11 at 23:39
  • 7
    For me, the `event.stopImmediatePropagation();` was the key to getting jQuery to stop calling the handler twice. – Joshua Dwire Nov 03 '13 at 02:27
  • a good explanation on .stopImmediatePropagation() vs rest given here... https://stackoverflow.com/questions/5302903/jquery-event-stopimmediatepropagation-vs-return-false – nipiv Oct 02 '14 at 09:32
7

Try unbinding the event first then bind it, refer below code:

$('.addField').show().unbind('keyup').keyup(function(event){
 event.preventDefault();

  if(event.keyCode == 13 || event.keyCode==9) {
ProfilePage.createTag( this, 'nada', 'addField')
    $(this).hide().val('');

    return false;       
}

An explanation is here, i had written a post about this on my new blog.

Ghost-Man
  • 2,179
  • 1
  • 21
  • 25
1

Hope this will solve your problem. Instead of using event.preventDefault() use these two shown below. In case of Microsoft browsers use event.cancelBubble = true; In case of W3C model browsers use event.stopPropagation();

And Instead of Keyup event kindly use the keypress event, because during keypress itself the input will be sent to input field so whatever inputs you don't want to appear will appear on the field. So the enter button event will be triggered.

Instead of return false use event.returnValue = false.

AmGates
  • 2,127
  • 16
  • 29
0

This is a problem which always drives me insane but i think this is the solution simply return false, if you return true it repeats it self randomly so im guessing it must have a listener which listens out for true responses.

Short Answer Add return false;

$("#register-form #first_name").keyup(function(event) {
console.log('hello world');
return false;

});

in the original question if you look at the code closely is seems the return false was written one line too early.

centralhubb.com
  • 2,705
  • 19
  • 17
0

I had this issue using Angular 11 EventEmitters. I solved it by creating a new instance of my event emitter whenever the event is triggered.

@Output() keypress = new EventEmitter();
onKeyPress(event) {
   this.keypress = new EventEmitter();
   this.keypress.emit(event);
 }
todji
  • 141
  • 7
0

I passed through the same and this structure worked for me:

const onKeyPress = (e: React.KeyboardEvent): void => {
    if (onSubmit && e.key.toLowerCase() === 'enter') {
      onSubmit();

      e.stopPropagation();
      e.preventDefault();
    }
};
Neeevs
  • 1
  • 1
0

Try changing all the instances of

$(field).functionCall() 

to

field.functionCall() 

since field is already a jQuery object.

Ok now we've established that this wasn't the error. I tested in Firefox 7 and Chrome 15 and saw that the code block in the if statement is only fired once when enter is pressed. Try checking to make sure that something inside the createTag() function isn't doing something twice.

Yes Barry
  • 9,514
  • 5
  • 50
  • 69
  • bad habit...jquery ignores it but I've made the change but there's no improvement. – bear Nov 02 '11 at 21:33
  • Dangit. Yeah admittedly that one was a shot in the dark anyway. Hmm let me think on this one for a moment. – Yes Barry Nov 02 '11 at 21:39
  • @user508708 I made a mock function for createTag() in that same jsFiddle that topek created. The alert is only fired once.. At this point it's much too difficult to determine without knowing what's in the DOM exactly and what the ProfilePage object is referencing.. – Yes Barry Nov 02 '11 at 22:10
  • I think you're right. The page is pretty dynamic and likely impractical to post in its entirety. I'll start narrowing it down and see if I can isolate the issue. I'm surprised, though, that we can't just kill the bubbling...oh, one more clue: I'm initializing this in $(document).ready(function() – bear Nov 02 '11 at 22:13
0

What do you think is catching the event when it bubbles. I only get one firing with this test page.

<!DOCTYPE html>
<html>
  <head>
    <title>Scratch</title>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.setOnLoadCallback(function (){
        $('input[type="text"]').keyup(function (){
          console.debug('keyup');
        });
      });
      google.load('jquery', '1.6.4');
    </script>
  </head>
  <body>

    <div class="something">
      <input type="text" />
    </div>
  </body>
</html>

Maybe it's your selector. Is it nested inside another .addTag? When I change the jQuery selector and also make the div and input the same class I start to get two events firing. Like this:

$('.thing').show().keyup(...);

...and...

<div class="thing">
    <input class="thing" type="text" />
</div>
mqsoh
  • 3,180
  • 2
  • 24
  • 26