0

I have a dropdown menu which contains a input and several buttons. The dropdown should hide when I click one of the buttons or somewhere else, but don't hide when keypress on the input. I use the following code, it doesn't work. Though it works when I use

$('.dropdown input').click(function(e){

})

instead of live.

But I do need live, so is there any solution for this?

/*  dropdown menu   */
$('.dropdown input').live('click', function(e) {
    e.stopPropagation();
});

$(document).click(function(e){
    if(e.isPropagationStopped()) return;  //important, check for it!
});
thecodeparadox
  • 86,271
  • 21
  • 138
  • 164
Jensen
  • 1,653
  • 4
  • 26
  • 42
  • 1
    could you post the html as well? FYI - `.live()` has been deprecated in jquery 1.7, I recommend use `.on()` or `.delegate()` – William Calvin May 08 '12 at 18:20
  • is `.dropdown input` dynamically created? – Rene Pot May 08 '12 at 18:20
  • You should be using on() now btw. Live doesn't work like click because it is already propagated down to the document level. It's not stopped at the input. – scottheckel May 08 '12 at 18:21
  • You can't do stopPropagation() on a live event because the live listener is applied to the $(document), not the element and therefore the event HAS to propagate in order to reach $(document). – Adam Jenkins May 08 '12 at 18:21
  • http://stackoverflow.com/questions/3353275/jquery-stoppropagation-problem-with-live-method can help! – foxybagga Oct 15 '12 at 16:10

3 Answers3

1

e.stopPropagation() will do no good for you in .live(), because the handler is bound to the document, so by the time the handler is invoked, the event has already bubbled.

You should stopPropagation from a more local ancestor of the element being clicked.

Since you were using .live(), I assume there are some dynamic elements being created. If so, the proper element to bind to will depend on the rest of your code.


Side note, but you never "need" .live(). There are other ways to handle dynamically created elements.

cliffs of insanity
  • 3,683
  • 1
  • 16
  • 18
  • @Jensen: If you're dynamically creating elements, you can bind handlers directly to them upon creation. Or you can use jQuery's other event delegation methods like `on` or `delegate`. Or you can do your own event delegation. – cliffs of insanity May 08 '12 at 18:46
  • ...if you don't know what event delegation is, then you should read up on it. It's a very simple concept, but extremely useful. The `live()` method uses event delegation, but it hides the fact, so people often don't realize it. – cliffs of insanity May 08 '12 at 18:47
  • I am dynamically creating dropmenus. I used the code @thecodeparadox provided, but the dropmenu still hides when I click on input – Jensen May 08 '12 at 18:59
  • @Jensen: Is there a common ancestor that contains all the drop menus? Here's an example using the `body`, but you should use a more local one if possible. `$('body').on('click','.dropdown input', function(e) {e.stopPropagation();})`. When the click event bubbles up to the `body`, if it took place on the `input` that descends from `.dropdown`, propagation will be stopped at that point, so it won't reach the `document`. Again, try to find a more local container than the `body` if possible. – cliffs of insanity May 08 '12 at 19:05
  • ...or like I said earlier, you can bind the handler directly to the `input` when it is dynamically created. – cliffs of insanity May 08 '12 at 19:07
0

did you try:

$('.dropdown').on('click', 'input', function(e) {
    e.stopPropagation();
});

OR

$('.dropdown').delegate('input', 'click', function(e) {
    e.stopPropagation();
});

NOTE: e.stopPropagation(); is not effective for live event

According to you question I have a dropdown menu which contains a input and several buttons. The dropdown should hide... means that dropdown is already exists within you DOM. If it already exists then you don't need live event.

thecodeparadox
  • 86,271
  • 21
  • 138
  • 164
0

what version of jQuery are you using? > 1.7 then:

$(document).on({"click":function(e){
  //do your work, only input clicks will fire this
}},".dropdown input",null);

notes: properly paying attention to event.target should help out with overlapping 'click' definitions using .on();

DefyGravity
  • 5,681
  • 5
  • 32
  • 47