【问题标题】:jquery draggable and sortable no pluginjquery可拖动和可排序无插件
【发布时间】:2014-06-27 03:28:08
【问题描述】:

我讨厌插件,所以我找到了一种只使用 jquery 来拖动和排序 html 元素的方法....

它的工作方式是我有四个 div 绝对定位在一个相对定位的 div 内。当鼠标按下四个 div 之一时,代码会获取 div 的位置并将其保存在两个全局变量中。代码将文档绑定到 mousemove 事件并获取鼠标光标的位置。当您移动鼠标时,使用 css() 方法将鼠标光标的位置分配给 div(鼠标左光标坐标减去 div 宽度的一半,鼠标顶部坐标减去 div 高度的一半)。如果 div 的右边缘或左边缘移出容器 div 的边界,则使用 css() 方法将 div 恢复到其旧位置。当您将 div 鼠标上移时,代码会获取 div 的新坐标并遍历其他 div 的坐标并确定哪个 div 最接近位置(哪个 div 的顶部坐标距当前 div 的当前顶部坐标最多 50px 并离开坐标也最多离当前div的当前左坐标50px)。然后代码将 mousemove 从文档中解除绑定,并将最近的 div 的位置与刚刚获得 mouseup 的 div 的最旧位置交换。

我的html代码:

    <div style="position: relative; width: 800px; height: 500px; overflow: hidden; border: 1px solid red;">



<div class="draggable"  id="div1" style=" position: absolute; width: 300px; height: 150px; margin: 1px 2px; top: 0px; left: 0px; border: 1px solid red;"  >

<table border="1" width="250" height="140" align="center" style=""><tbody>
<tr><td width="" height="" align="center" valign="center">

1

</td></tr>
<tr><td width="" height="20" align="center" valign="top" colspan="" style="">   


</td></tr></tbody></table>

</div>

<div class="draggable"  id="div2" style=" position: absolute; width: 300px; height: 150px; margin: 1px 2px; top: 0px; left: 400px; border: 1px solid red;"  >

<table border="1" width="250" height="140" align="center" style=""><tbody>
<tr><td width="" height="" align="center" valign="center">

2

</td></tr>
<tr><td width="" height="20" align="center" valign="top" colspan="" style="">   


</td></tr></tbody></table>

</div>


<div class="draggable" id="div3" style=" position: absolute; width: 300px; height: 150px; margin: 1px 2px; top: 200px; left: 0px; border: 1px solid red;"  >

<table border="1" width="250" height="140" align="center" style=""><tbody>
<tr><td width="" height="" align="center" valign="center">

3

</td></tr>
<tr><td width="" height="20" align="center" valign="top" colspan="" style="">   


</td></tr></tbody></table>

</div>


<div class="draggable"  id="div4" style=" position: absolute; width: 300px; height: 150px; margin: 1px 2px; top: 200px; left: 400px; border: 1px solid red;"  >

<table border="1" width="250" height="140" align="center" style=""><tbody>
<tr><td width="" height="" align="center" valign="center">

4

</td></tr>
<tr><td width="" height="20" align="center" valign="top" colspan="" style="">   


</td></tr></tbody></table>



</div>




</div>

我的 jquery 代码:

$(document).ready(function(){ 


$(".draggable").mousedown(function(){

dragging = $(this).prop("id");
oldTop = $(this).position().top; 
oldLeft = $(this).position().left;

$("#"+dragging).css("cursor", "move");

$(document).mousemove(function(event){

var top = event.pageY - ($("#"+dragging).height()/2); 
var left = event.pageX - ($("#"+dragging).width()/2); 
var bottom = event.pageY + ($("#"+dragging).height()/2); 
var right = event.pageX + ($("#"+dragging).width()/2);

if(top > 0 && left > 0 && bottom < 500 && right < 800){ 

 $("#"+dragging).css( "left", left+"px").css("top", top+"px");

}else{

$("#"+dragging).css("cursor", "normal").css( "left", oldLeft+"px").css("top", oldTop+"px");

$(document).unbind("mousemove");

}

});




}).mouseup(function(){

newLeft = $(this).position().left;  
newTop = $(this).position().top;
var i = 0;

$(document).unbind("mousemove");

$(".draggable").not($(this)).each(function(){

var posLeft = $(this).position().left; 
var posTop = $(this).position().top;

var topDiff = Math.abs(posTop - newTop); 
var leftDiff = Math.abs(posLeft - newLeft); 



if(leftDiff <= 50 && topDiff <= 50){ 

$("#"+dragging).css("cursor", "normal").css( "left", posLeft+"px").css("top", posTop+"px");

$(this).css("left", oldLeft+"px").css("top", oldTop+"px");

i++;

}

}); 


if(i == 0){  

$("#"+dragging).css("cursor", "normal").css( "left", oldLeft+"px").css("top", oldTop+"px"); 

}

});



});

代码运行良好。唯一出乎意料的是,div1不能和其他div一起拖动排序,div2只能和div1一起拖动排序,div3只能和div1和div2拖动排序,div4可以拖动排序与任何 div。该代码应该可以工作,以便可以拖动任何 div 与其余 div 进行排序。

相反,如果您拖动 div1 并将其放置在 div2 或 div3 或 div4 的正上方(放置 div1 使其顶部坐标距 div2 顶部坐标至多 50px,div1 左坐标距 div2 左坐标至多 50px)它只会恢复到原来的位置,即使我的代码没有指定应该发生这种情况。这两个 div 应该交换位置。将 div2 拖动到 div3 或 div4 以及将 div3 拖动到 div4 时也会发生同样的情况。我不知道为什么会这样。我认为这与我在 jquery 代码末尾附近的 foreach 有关。我真的不知道。如果有人知道如何改进此代码,我将不胜感激。

我希望能够对代码进一步做的是:

  • 拖动任何 div 以与其余任何 div 进行排序。

  • 如果可以使用相对定位的 div1、div2、div3 和 div4,并且仍然能够拖动任何 div 与任何其他 div 进行排序。

我也不太擅长 javascript。所以javascript越少越好。

谢谢。

【问题讨论】:

  • 请以有组织的方式缩进您的代码。它确实有助于理解。

标签: jquery html


【解决方案1】:

我知道你提到你讨厌插件。您还提到您使用 jQuery。

出于好奇,为什么不使用 jQueryUI?它具有draggabledroppablesortable 功能。在 StackOverflow 上,您已经回答了 100 多个问题。

IMO,您正在尝试做的是重新发明轮子。

【讨论】:

  • 我不太懂这个插件。我理解我的代码,我想改进它。
【解决方案2】:

我得到了完全符合我要求的代码。最重要的是,它不需要绝对定位。它使用元素的静态定位,非常完美。

一切正常,但出乎意料的是,最初,光标在 div 上垂直居中,但在拖动时不是水平或沿 div 的宽度居中,尽管它应该是。通过做一些意想不到的事情来解决这个问题。请参阅对 jquery 代码的评论。

html 更改:

<table id="container" border="0" width="800" height="500" align="center" style="position: relative; border: 1px solid red;"><tbody>
<tr><td width="" height="" align="center" valign="center">


    <div class="draggable"  id="div1" style="width: 200px; height: 100px; margin: 1px 2px; border: 1px solid red; display: inline-block;"  >

        <table border="1" width="100%" height="100%" align="center" style=""><tbody>
        <tr><td width="" height="" align="center" valign="center">

        1

        </td></tr>
        <tr><td width="" height="20" align="center" valign="top" colspan="" style="">   


        </td></tr></tbody></table>

    </div>

    <div class="draggable"  id="div2" style="width: 200px; height: 100px; margin: 1px 2px; border: 1px solid red; display: inline-block;"  >

        <table border="1" width="100%" height="100%" align="center" style=""><tbody>
        <tr><td width="" height="" align="center" valign="center">

        2

        </td></tr>
        <tr><td width="" height="20" align="center" valign="top" colspan="" style="">   

        </td></tr></tbody></table>

    </div>


    <div class="draggable" id="div3" style="width: 200px; height: 100px; margin: 1px 2px; border: 1px solid red; display: inline-block"  >

        <table border="1" width="100%" height="100%" align="center" style=""><tbody>
        <tr><td width="" height="" align="center" valign="center">

        3

        </td></tr>
        <tr><td width="" height="20" align="center" valign="top" colspan="" style="">   

        </td></tr></tbody></table>

    </div>


    <div class="draggable"  id="div4" style="width: 200px; height: 100px; margin: 1px 2px; border: 1px solid red; display: inline-block;"  >

        <table border="1" width="100%" height="100%" align="center" style=""><tbody>
        <tr><td width="" height="" align="center" valign="center">

        4

        </td></tr>
        <tr><td width="" height="20" align="center" valign="top" colspan="" style="">   

        </td></tr></tbody></table>

    </div>


    <div class="draggable"  id="div5" style="width: 200px; height: 100px; margin: 1px 2px; border: 1px solid red; display: inline-block;"  >

        <table border="1" width="100%" height="100%" align="center" style=""><tbody>
        <tr><td width="" height="" align="center" valign="center">

        5

        </td></tr>
        <tr><td width="" height="20" align="center" valign="top" colspan="" style="">   

        </td></tr></tbody></table>

    </div>

    <div class="draggable"  id="div6" style="width: 200px; height: 100px; margin: 1px 2px; border: 1px solid red; display: inline-block;"  >

        <table border="1" width="100%" height="100%" align="center" style=""><tbody>
        <tr><td width="" height="" align="center" valign="center">

        6

        </td></tr>
        <tr><td width="" height="20" align="center" valign="top" colspan="" style="">   

        </td></tr></tbody></table>

    </div>

    <div class="draggable"  id="div7" style="width: 200px; height: 100px; margin: 1px 2px; border: 1px solid red; display: inline-block;"  >

        <table border="1" width="100%" height="100%" align="center" style=""><tbody>
        <tr><td width="" height="" align="center" valign="center">

        7

        </td></tr>
        <tr><td width="" height="20" align="center" valign="top" colspan="" style="">   

        </td></tr></tbody></table>

    </div>



</td></tr></tbody></table>

jQuery 代码:

$(document).ready(function(){ 


    $(document).on("mousedown", ".draggable", function(){

        sortable = $(this);
        sortableDomPos = sortable.index();
        sortable.fadeTo(1, 0);
        oldLeft = sortable.position().left; oldTop = sortable.position().top;

        dragging = $(this).clone();
        dragging.css("position", "absolute").css("left", oldLeft+"px").css("top", oldTop+"px").css("pointer-events", "none").appendTo("#container");


        $(document).mousemove(function(event){

            var top = event.pageY - ($(dragging).height()/2); 
            var left = event.pageX - ($(dragging).width()); // ** should be ** var left = event.pageX - ($(dragging).width()/2);
            var bottom = event.pageY + ($(dragging).height()/2); 
            var right = event.pageX + ($(dragging).width()/2);

            if(top > 0 && left > 0 && bottom < 500 && right < 900){ 
                $(dragging).css( "left", left+"px").css("top", top+"px");
            }else{
                $(document).unbind("mousemove"); $(dragging).remove(); sortable.fadeTo(1, 1);
            }

        });



    });


    $(document).on("mouseup", ".draggable, #container", function(){

        $(document).unbind("mousemove"); $(dragging).remove();  sortable.fadeTo(1, 1);

        if($(this).prop("class") == "draggable"){

            var thisDomPos = $(this).index();

            if(sortableDomPos >= thisDomPos){
                sortable.insertAfter($(this)); $(this).insertAfter($(".draggable").eq(sortableDomPos));
            }
            else{
                sortable.insertBefore($(this)); $(this).insertBefore($(".draggable").eq(sortableDomPos));
            }

        }

    });


});

【讨论】:

    猜你喜欢
    • 2011-12-11
    • 1970-01-01
    • 2012-06-23
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-07
    相关资源
    最近更新 更多