Javascript 在jquery.event.drag中触发dragstart后更新可用的放置目标

Javascript 在jquery.event.drag中触发dragstart后更新可用的放置目标,javascript,jquery,drag-and-drop,Javascript,Jquery,Drag And Drop,概述: 我有一个使用和的页面。 我需要能够拖放到不断添加到dom中的元素上,即使在拖动开始之后也是如此 问题: 当触发dragstart事件时,它会检查可用的拖放目标,并将它们添加到拖动对象中 我遇到的问题是,在触发dragstart事件后,我正在动态添加放置目标,因此用户无法放置到这些动态添加的放置目标上 示例: 问题: 如何更新拖动以允许在开始拖动后拖放已添加到dom中的元素?启用。为什么不将所有div放入页面并将其可见性设置为隐藏?然后使用setInterval()每秒更改每个对象

概述:

我有一个使用和的页面。 我需要能够拖放到不断添加到dom中的元素上,即使在拖动开始之后也是如此


问题:

当触发
dragstart
事件时,它会检查可用的拖放目标,并将它们添加到拖动对象中

我遇到的问题是,在触发
dragstart
事件后,我正在动态添加放置目标,因此用户无法放置到这些动态添加的放置目标上


示例:


问题:


如何更新拖动以允许在开始拖动后拖放已添加到dom中的元素?

启用。

为什么不将所有div放入页面并将其可见性设置为隐藏?然后使用setInterval()每秒更改每个对象的可见性。

您不能。在
dragstart
上,可能的放置区域是从DOM计算出来的,在
dragend
之前无法编辑。即使不断地重新绑定()(演示:)上的
.on(),也无法提供所需的效果

我解决这个问题的方式有点不同。(演示:)

  • 从HTML中的每个
    开始
  • 应用
    opacity:0
    使其不可见,应用
    width:0
    使其在隐藏时不会出现
    dropend
  • 使用
    setInterval
    显示下一个隐藏的div(
    $('.drop:not(.visible))。第一个()
    )每1000毫秒显示一次
  • JS:


    我无法使用jquery.event.drag和jquery.event.drop实现这一点,但我确实使它能够与本机HTML5事件一起工作:

    解决方案是在函数中绑定放置目标上的事件,并调用该事件来更新绑定。我想您可以使用类似的主体使用jquery.event.drag和jquery.event.drop来实现这一点。如果我能让这些工作,我会更新我的答案

    以下是JS:

    $(function() {
        var bind_targets = function() {
            $(".drop").on({
                dragenter: function() {
                    $(this).addClass("active");
                    return true;
                },
                dragleave: function() {
                    $(this).removeClass("active");
                },
                drop: function() {
                    $(this).toggleClass("dropped");
                }
            });
        };    
    
        $("div[draggable]").on({
            dragstart: function(evt) {
                evt.originalEvent.dataTransfer.setData('Text', 'data');
            },
            dragend: function(evt) {
                $('.active.drop').removeClass('active');   
            }
        });
      setInterval(function () {
          $("#dropWrap").append('<div class="drop">Drop</div>');
          // Do something here to update the dd.available
          bind_targets();
      }, 1000)
    });
    
    $(函数(){
    var bind_targets=函数(){
    美元(“.drop”)。在({
    dragenter:function(){
    $(此).addClass(“活动”);
    返回true;
    },
    dragleave:function(){
    $(此).removeClass(“活动”);
    },
    drop:function(){
    $(此).toggleClass(“已删除”);
    }
    });
    };    
    $(“div[draggable]”)。在({
    dragstart:函数(evt){
    evt.originalEvent.dataTransfer.setData('Text','data');
    },
    dragend:功能(evt){
    $('.active.drop').removeClass('active');
    }
    });
    setInterval(函数(){
    $(“#dropWrap”).append('Drop');
    //在此处执行某些操作以更新可用的dd
    绑定_目标();
    }, 1000)
    });
    
    您可以使用此代码段

    重要的函数是:
    $.event.special.drop.locate()

    在chrome/safari/firefox/ie9上进行了测试,似乎有效


    更新

    对于重叠事件,请查看以下代码是否有效。我在匿名函数中设置它只是为了避免任何全局变量。 其思想是使用事件的currentTarget属性来检查是否不是相同的元素触发了相同的事件。我在newdrop元素上设置了一个id,只是为了在这里进行测试

    (函数(){
    变量$body=$(“body”),
    newdrops=[],
    currentTarget={},
    ondragstart=函数(){
    $(this.css('opacity',.75);
    },ondrag=函数(ev,dd){
    $(this.css)({
    顶部:dd.offsetY,
    左:dd.offsetX
    });
    },ondragend=函数(){
    $(this.css('opacity','');
    for(var i=0,z=newdrops.length;i$(function() {
        var bind_targets = function() {
            $(".drop").on({
                dragenter: function() {
                    $(this).addClass("active");
                    return true;
                },
                dragleave: function() {
                    $(this).removeClass("active");
                },
                drop: function() {
                    $(this).toggleClass("dropped");
                }
            });
        };    
    
        $("div[draggable]").on({
            dragstart: function(evt) {
                evt.originalEvent.dataTransfer.setData('Text', 'data');
            },
            dragend: function(evt) {
                $('.active.drop').removeClass('active');   
            }
        });
      setInterval(function () {
          $("#dropWrap").append('<div class="drop">Drop</div>');
          // Do something here to update the dd.available
          bind_targets();
      }, 1000)
    });
    
    (function () {
        var $body = $("body"),
            newdrops = [],
            currentTarget = {},
            ondragstart = function () {
    
                $(this).css('opacity', .75);
            }, ondrag = function (ev, dd) {
                $(this).css({
                    top: dd.offsetY,
                    left: dd.offsetX
                });
            }, ondragend = function () {
    
                $(this).css('opacity', '');
                for (var i = 0, z = newdrops.length; i < z; i++)
                $(newdrops[i]).off('dropstart drop dropend').removeClass('tempdrop');
                newdrops = [];
            }, ondropstart = function (e) {
                if (currentTarget.dropstart === e.currentTarget) return;
                currentTarget.dropstart = e.currentTarget;
                currentTarget.dropend = null;
                console.log('start::' + e.currentTarget.id)
                $(this).addClass("active");
            }, ondrop = function () {
                $(this).toggleClass("dropped");
            }, ondropend = function (e) {
                if (currentTarget.dropend === e.currentTarget) return;
                currentTarget.dropend = e.currentTarget;
                currentTarget.dropstart = null;
                console.log('end::' + e.currentTarget.id)
                $(this).removeClass("active");
            };
    
        $body.on("dragstart", ".drag", ondragstart)
            .on("drag", ".drag", ondrag)
            .on("dragend", ".drag", ondragend)
            .on("dropstart", ".drop", ondropstart)
            .on("drop", ".drop", ondrop)
            .on("dropend", ".drop", ondropend);
    
    
    
        var cnt = 0;
        setInterval(function () {
            var dataDroppables = $body.data('dragdata')['interactions'] ? $body.data('dragdata')['interactions'][0]['droppable'] : [];
    
            var $newDrop = $('<div class="drop tempdrop" id="' + cnt + '">Drop</div>');
            cnt++;
            $("#dropWrap").append($newDrop);
            var offset = $newDrop.offset();
            var dropdata = {
                active: [],
                anyactive: 0,
                elem: $newDrop[0],
                index: $('.drop').length,
                location: {
                    bottom: offset.top + $newDrop.height(),
                    elem: $newDrop[0],
                    height: $newDrop.height(),
                    left: offset.left,
                    right: offset.left + $newDrop.width,
                    top: offset.top,
                    width: $newDrop.width
                },
                related: 0,
                winner: 0
            };
            $newDrop.data('dropdata', dropdata);
            dataDroppables.push($newDrop[0]);
            $newDrop.on("dropstart", ondropstart)
                .on("drop", ondrop)
                .on("dropend", ondropend);
            $.event.special.drop.locate($newDrop[0], dropdata.index);
            newdrops.push($newDrop[0]);
        }, 1000);
    })();