XandruDavid
XandruDavid

Reputation: 310

jQuery event.stopPropagation() and event issues

I'm creating a jQuery script that add a pin to a map on click event, the problem is that i need that event to work only on the map not his sons too..

This is my code:

$("div#map").click(function (e) {
    $('<div class="pin"></div>').css({
        left: a_variable,
        top: another_variable
    }).appendTo(this);

    $("div.pin").click(function (e) { e.stopPropagation(); });
})

Another problem is that under this code i have something like this:

$("div.pin").mousedown(function (e) {
    if(e.which == 1) {
        console.log("down");
        moving = true;
        $(this).addClass("moving");
    } else if(e.which == 3) {
        console.log("right");
    }
});

Will this work with pins created after the script load too?

JsFiddle: http://jsfiddle.net/vB2Gb/

Upvotes: 0

Views: 123

Answers (3)

Arun P Johny
Arun P Johny

Reputation: 388316

Since you are dealing with dynamically added elements, you need to use event delegation.

$("#map").click(function (e) {
    $('<div class="pin"></div>').css({
        left: a_variable,
        top: another_variable
    }).appendTo(this);
}).on('click', '.pin', function (e) {
    //have a single delegated click handler
    e.stopPropagation();
}).on('mousedown', '.pin', function (e) {
    //use a delegated handler for mousedown also
    if (e.which == 1) {
        console.log("down");
        moving = true;
        $(this).addClass("moving");
    } else if (e.which == 3) {
        console.log("right");
    }
})

Also see Event binding on dynamically created elements?

Upvotes: 0

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93551

I made a number of adjustments to your code:

JSFiddle: http://jsfiddle.net/TrueBlueAussie/vB2Gb/1/

$(function () {
    var $map = $("div#map");
    $map.click(function (e) {
        var $pin = $('<div class="pin"></div>').css({
            left: (((e.pageX + 3 - $map.position().left) * 100) / $map.width()) + "%",
            top: (((e.pageY - 10 - $map.position().top) * 100) / $map.height()) + "%"
        });
        $pin.appendTo($map);
    })
    $map.on('click', "div.pin", function (e) {
        e.stopPropagation();
    });

    var moving = false;

    var pin_id;
    var pin_left;
    var pin_top;

    $map.on('mousedown', "div.pin", function (e) {
        if (e.which == 1) {
            console.log("down");
            moving = true;
            $(this).addClass("moving");
        } else if (e.which == 3) {
            console.log("right");
        }
    });

    $map.on('contextmenu', "div.pin", function (e) {
        return false;
    });

    $(document).mousemove(function (e) {
        if (moving) {
            if (e.pageX <= $map.position().left) {
                pin_left = 0;
            } else if (e.pageY <= $map.position().top) {
                pin_top = 0;
            } else {
                console.log("moving");
                pin_id = 1;
                pin_left = (((e.pageX + 3 - $map.position().left) * 100) / $map.width());
                pin_top = (((e.pageY - 10 - $map.position().top) * 100) / $map.height());
                $(".moving").css("left", pin_left + "%");
                $(".moving").css("top", pin_top + "%");
            }
        }
    });

    $(document).mouseup(function (e) {
        if (moving) {
            console.log("up");
            moving = false;
            $(".moving").removeClass("moving");
            dbMovePin(pin_id, pin_left, pin_top);
        }
    });

});

function dbMovePin(pin_id, pin_left, pin_top) {
    $.post(
        "mapsave.php", {
        action: "move_pin",
        id: pin_id,
        left: pin_left,
        top: pin_top
    },

    function (data, status) {
        //alert("Data: " + data + "\nStatus: " + status);
    });
}

This includes using delegated events (with on) for both the mouse down events and the pin click. Sharing a single variable for the map etc

Upvotes: 1

XandruDavid
XandruDavid

Reputation: 310

Event Delegation does what i need:

I've changed

 $("div.pin").mousedown(function (e) { ... });    

with

$("div#map").on("mousedown", "div", function (e) {

Upvotes: 0

Related Questions