Jquery/Javascript拖放一个父元素到另一个父元素

3
我一直在使用JQuery UI的可拖动功能,但在将元素从一个父级拖到另一个父级时,保持元素位置的问题一直困扰着我。一旦将元素移动到另一个父级,它的定位就会严重偏差。然后,我开始计算偏移量并将其应用于元素,这样就可以解决问题了。但是,在我开始对页面进行样式设置后,一切变得更糟了。
这似乎是一个简单的要求,所以不确定是否漏掉了什么明显的技巧?
如果上面的内容不清楚,请见谅,很难解释清楚。
谢谢 Steve 附:以下只有js代码,它不太美观,有些值我现在已经硬编码了:
$(document).ready(function() { 
  makeDraggable($(".draggable"));
});

function makeDraggable(el) {
  var clone ;
  var x = 0;
  var y = 0;
  $(el).draggable({
    zIndex: 1000,
    start:function() {
      if($(this).parent().parent().attr("id") == "browser") {
        clone = $(this).clone();
        makeDraggable($(clone));
        $(clone).css("position","absolute");
        $(clone).css("z-index","0");
        $(this).parent().append($(clone));
      } // end if
    },
    drag:function() {},
    stop:function() {
      if($(this).parent().parent().attr("id") == "browser") {
        var offset = 0;
        var total_item_width = parseInt($(this).css("padding-left"))+parseInt($(this).css("padding-right"))+$(this).width();

        $(clone).css("position","relative");
        $("#canvas").append($(this));

        offset = ($("#canvas").find(".draggable").size()-1)*total_item_width;  
        $(this).css("left",parseInt($(this).css("left"))+827-offset);

        offset = ($("#canvas").find(".draggable").size()-1)*($(this).height()+12);
        $(this).css("top",parseInt($(this).position().top));
      } // end if
    }
  });
}

如果难以解释,请发布代码。 - Lukman
可能需要在父元素中检查CSS位置属性:https://dev59.com/4HE95IYBdhLWcg3wHqIV - zack
3个回答

1
当拖动一个对象时,jquery会直接将偏移量(top/left)样式应用于该元素。如果您要将此可拖动对象添加到新容器中,则新容器是父级,并且偏移量将从容器位置而不是屏幕位置应用——至少这是我的理解。
这是我使用的解决方法:助手克隆接收样式,让您的原始元素可以干净地附加。 开始/停止切换显示,使其看起来像您正在拖动实际元素。
$("#draggable").draggable({
    revert: 'invalid',
    helper: 'clone', 
    zIndex: 350, 
    start:  function() { $(this).toggle(); }, 
    stop:   function() { $(this).toggle(); } 
});
$("#droppable").droppable({
    accept: '#draggable',
    drop: function(event, ui) {
                // example of effecting parent
                // $(this).addClass('highlight').find('p').html('Dropped!');
                $(ui.draggable).draggable("destroy").appendTo($(this));
    }
});

谢谢,我会尝试一下并看看效果如何。 - Steven Cheng
我测试了你的脚本,首先在 $(ui.draggable).draggable("destroy").appendTo($(this)); 上它生成了一个错误,快速谷歌一下建议我使用 disable 而不是 destroy,我尝试了并且代码成功执行了。 但是,它把元素放到了新的父元素中,而没有保持原位置。不确定我上面的问题是否清楚,但基本上当我拖动元素时,我需要重新分配父级并保持在新父级内的位置。 - Steven Cheng

1

看起来你应该考虑重新组织你的DOM。我不明白为什么你在拖动开始时将位置从相对定位改为绝对定位,然后在放下时又改回相对定位。随着布局变得更加复杂,这会导致灾难性的后果,自然会给标签带来很多机会跳来跳去。如果你在Firebug中检查一下,你会发现一些子元素在它们的父元素之外,这可能是你在放置到父元素上时没有预料到的。

如果你是新手,并且只是想完成任务,那么最好将这些可拖动元素保持为绝对定位,这样可以最大程度地减少预测行为的困难。但是为了在各种分辨率下拥有漂亮的网站,你真的应该掌握浏览器如何根据它们的属性放置可见对象。

祝你好运 :)


自从我最初发布这篇文章以来,我已经以更简单的方式实现了我的解决方案。我修改了我的DOM,并且在编程上也使拖放变得更加容易。虽然我仍在学习,但在项目的这个部分中,我肯定已经有了重要的元素定位经验。感谢您的回答! - Steven Cheng
很高兴你正在掌握它,简单是关键!+1会很不错的;-) - sillyMunky

0

这对我来说效果最好。

$(function() {
    var unit;
    $(".unit").draggable();
    $("#rpgGrid td").droppable({
        drop : function(event, ui) {
            jQuery(ui.draggable).css({
                "top": "0",
                "left": "0"
            });
            $(this).append(ui.draggable, function() {
                $(ui.draggable).remove();
            });
        }
    });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接