views:

38

answers:

1

I've run into the problem that has been addressed here without a workaround: I can't use stopPropagation() on dynamically spawned elements.

I've tried creating a condition to exclude a click within the dimensions of the spawned element, but that doesn't seem to work at all.

Here is what I got:

1) a large background element ("canvas") that is activated to be "sensitive to clicks on it" by a button

2) the canvas, if activated, catches all clicks on it and spawns a small child form ("child") within it

3) the child is positioned relative to the mouse click position. If the mouse click was on the right half of the canvas, the child will be positioned 200 pixels to the left of that spot. (On the right if the click was in the left half)

4) every new click on the canvas removes the existing child (if any) and spawns a new child at the new position (relative to the click)

The problem: Since the spawned child element is on top of the canvas, a click on it counts as a click on the canvas. Even if the child is outside of the boundaries of the canvas, clicking on it will trigger the action as described in 4) again . This shouldn't happen.

=========== CODE: The button to activate the canvas:

$('a#activate').click(function(event){
    event.preventDefault();
    canvasActive(); 
});

I referenced the above to show you that the canvas click-catching is happening in a function. Not sure if this is relevant...

This is the function that catches clicks on the canvas:

function canvasActive() {
    $('#canvas').click(function(e){
        e.preventDefault();

        //get click position relative to canvas
        posClick = {
            x : Math.round(e.pageX - $(this).offset().left),
            y : Math.round(e.pageY - $(this).offset().top)
        };

        //calculate child position
        if(posClick.x <= $canvas.outerWidth(false)/2) {
            posChild = {
                x: posClick.x + 200, //if dot is on the left side of canvas
                y: posClick.y
            };
        } else {
            posChild = {
                x: posClick.x - 600, //if dot is on the right
                y: posClick.y
            };
        }

        $(this).append(markup); //markup is just the HTML for the child

    });
}

I left out the unimportant stuff. The question is:

How can I prevent a click inside of a spawned child from executing the function? I tried getting the child's dimensions and doing something like "if posClick is within this range, don't do anything" - but I can't seem to get it right.

Perhaps someone has come across this dilemma before. Any help is appreciated.

+2  A: 

I don't actually see any jQuery .live() code. Regular events added with bind, click, etc. are not "live" events.

In any case, all you need to do here is check the item that was passed into the event to see if it's the canvas:

$('#canvas').click(function(e){
    if($(this).is('#canvas')){
      // it really was the canvas that was clicked!
      // could also check "e.currentTarget"--it's the same as "this"
      // do your thing and return false
    }
}
Michael Haren
Thanks for the input Michael. I tried doing the exact conditional you mention, with the result that it doesn't trigger the event at all. Really weird... If I take out the condition and log e.currentTarget, it gives me [object HTMLDivElement] but no specific identifier. I'm really not sure what's going wrong here... I'll try taking the canvas click function out of the function and moving things around now.
bobsoap
P.S. I was referring to a live() event because I had tried to use stopPropagation() in a live() event of the child element, in my first attempt to exclude a click on it from triggering the canvas. Sorry about the confusion.
bobsoap
Add the element's ID attribute to your log message to see what's going on
Michael Haren
$(e.currentTarget).attr('id') is always "canvas", even when clicking on a child. Lol. How can that be?
bobsoap
Alright, I believe I finally got it:1) I created a variable which is checked for on the first line of the canvas click function:if(canvas_active === true)2) The most important part - this is outside of the canvas click function:$('#child').live('mouseover', function() { canvas_active = false;}).live('mouseout', function() { canvas_active = true;});What I gathered is that e.currentTarget cannot return anything else other than (this) from within an event (it's actually also spelled out on the reference page you link to). So I can't check from within the canvas click function...
bobsoap
...but this has to happen outside of it, in a separate function. And I just saw that all my line breaks in the above note got killed. I hope it still makes sense though. Thanks again Michael for your invaluable help that pushed me into the right direction.
bobsoap