ostapische
ostapische

Reputation: 1592

Flying div into another div

jsfiddle link.
I want when the mousedown event triggered on #flyingDiv I can move it around a #holder, when the mouseup and mouse goes away from #holer I can't move it. In my code sometimes #flyingDiv positioned near the black border when i move mouse in the center of #holder.
HTML:

<div id="holder" style="position: relative; margin: 20px auto; border: 1px solid black; width: 400px !important; height: 400px !important;">
    <div id="flyingDiv" style="position: absolute; background-color: green; width: 10px !important; height: 10px !important; left: 195px; top: 195px;"></div>
</div>  

Javascript:

$(function(){
    var fd = $("#flyingDiv");
    $("#flyingDiv").bind("mousedown", function(event) {
        $(this).attr("pressed", true);
    });
    $("#holder").bind("mouseup", function(event) {
        $("#flyingDiv").removeAttr("pressed");
    });
    $("#holder").bind("mousemove", function(event) {
        var div = $("#flyingDiv");
        if (div.attr("pressed")) {
            var width = div.width();
            if (event.offsetX >= width / 2 && ($(this).width() - event.offsetX) >= width / 2) {
                div.css("left", parseInt(event.offsetX - width / 2) + "px");
            }
            var height = div.height();
            if (event.offsetY >= height / 2 && ($(this).height() - event.offsetY) >= width / 2) {
                div.css("top", parseInt(event.offsetY - height / 2) + "px");
            }
        }
    });
});  

UPD
I found that if the event.eventPhase == 3 it's old event. Link
But still code works not fast.

Upvotes: 4

Views: 1138

Answers (2)

arenaq
arenaq

Reputation: 2380

dont use bind, use $(element).mousedown().mouseup()

maybe something like this... http://jsfiddle.net/KQpe9/

    $(function() {
    $('.slider').slider();
});

$.fn.slider = function() {
    return this.each(function() {
        var $el = $(this);
        $el.css('top', 0);
        var dragging = false;
        var startY = 0;
        var startT = 0;
        $el.mousedown(function(ev) {
            dragging = true;
            startY = ev.clientY;
            startT = $el.css('top');
        });
        $(window).mousemove(function(ev) {
            if (dragging) {
                // calculate new top
                var newTop = parseInt(startT) + (ev.clientY - startY);

                //stay in parent
                var maxTop =  $el.parent().height()-$el.height();          
                newTop = newTop<0?0:newTop>maxTop?maxTop:newTop;
                $el.css('top', newTop );
            }
        }).mouseup(function() {
            dragging = false;
        });
    });
}

Upvotes: 1

algoni
algoni

Reputation: 635

I can replicate the problem on Chrome, and this seems to be a performance problem; a mouse move event fires up very rapidly, and doing both DOM querying and writing on every event will choke a slower client at some points, in which the style won't get a value for top and left for a few frames, and it will default to 0.

You might want to look into premade, optimized solutions like jQuery draggable, since you're already using jQuery.

Upvotes: 2

Related Questions