views:

30

answers:

1

Hi!

I've simplified the HTML and Javascript.

The HTML structure

ul -> li -> a

The javascript

var $ul = $('#the-list');

$ul.find('a').click(function(e){
    e.stopImmediatePropagation();
    console.debug('a');
});

$ul.unbind('click').click(function(){
    console.debug('ul');
});

The problem

The first time a link is clicked, everything works fine. But after the list content is updated with $ul.html(newHtml) and the code above is run again, the event on $ul is called first.

First time:

  1. a
  2. Stops there

Second time:

  1. ul
  2. a

What would cause such a behaviour? Please excuse the reverse structure of this question

+1  A: 

If you're wiping out the contents of your ul, you shouldn't bind event listeners to the contents; instead, bind a click listener to the ul itself, and you can listen to click events on the ul as well as its children, all in one listener. This is called event delegation.

$ul.click(function (e) {
    var $target = $(e.target);
    console.log($target);
});

If you want to specifically listen for click events on the ul and anchor elements it contains, you can use $.live():

$ul.add($ul.find('a')).live('click', function (e) {
    console.log(e.target);
});

Should give you the click events you want. I'm not 100% sure of this, since .add might change things a bit, but that's the basic idea. Testing this now.

Matt Ball
Couldn't make the event target method work; the target element is the <ul>, even when I click an <a>. Tried to add an empty click handler on <a>, but no dice.
Znarkus
@Znarkus: sorry, I got a bit sidetracked. Which clicks are you actually interested in? The `<a/>` s?
Matt Ball
I want one handler for the <ul> and one for all <a>, but if the user clicks an <a>, that event should take precedence
Znarkus
@Znarkus: you're really never going to see clicks from the `<ul>` - only from its children, the `<li>` s and their children. That said, you can get *all* of those events by listening only for click events on the `<ul>` itself, since the clicks on its children will bubble up. Like this: http://jsfiddle.net/5eJCW/1/
Matt Ball
But everything works until I update the content of the `<ul>`, this is what confuses me
Znarkus
This works for me: http://jsfiddle.net/5eJCW/2/ . What isn't working for you? How about a jsfiddle link or something like that?
Matt Ball
I'd have to give you access to our repo, which I can't, sorry :( One very weird thing: The event object sent to the <a> handler is different from <ul>'s. This is <ul>'s event object: http://z.markushedlund.se/events.jpg
Znarkus
Why is that weird? Why does it matter at all? I'm not asking to see all of it, but I can only get so far offering suggestions to a problem that I haven't been told and I can't reproduce. http://sscce.org/ Sorry, but I'm just not psychic.
Matt Ball
Yeah I know, but I can't seem to reproduce the problem myself outside this project. I am very thankful for all your help and time! I'll get back when I have more to go on, thanks again
Znarkus