在拖动另一个元素之前,可拖动的将不起作用

Posted

技术标签:

【中文标题】在拖动另一个元素之前,可拖动的将不起作用【英文标题】:draggable won't work untill another element is dragged 【发布时间】:2021-09-26 00:24:49 【问题描述】:

我在使用可拖动的 div 时遇到问题,我正在尝试构建一个用户界面,您可以在其中从调色板拖放到工作区中。

基本上我所做的是我有一个隐藏的 div,其中包含每个调色板项目所代表的元素,当我单击调色板项目时,我克隆相应的隐藏项目并将其附加到编辑器 div(因此可以移动all arround),然后触发鼠标事件(因此您不必再次单击即可移动它)。

之后,克隆的项目(已存储在全局变量中)在放置时从文档中删除,如果元素被放置在工作区上,那么我将元素附加到工作区(因此只能在工作区),但在您将新元素放入工作区之前不会移动。

这是我的代码:。

CSS:

<style>
    #editor
        position: relative;
        height: 100%;
        width: 100%;
        background: lightcyan;
    
    #elements
        display: none;
    
    #palette
        height: 100%;
        width: 125px;
        float: left;
        background: lightgrey;
    
    .editor-pane
        height: 10%;
        width: 20%;
        float: left;
        background: lightyellow;
        position: absolute;
    
    .editor-palette-item
        width: 16px;
        height: 16px;
    
    .palette-item-container
        cursor: pointer;
        cursor: hand;
        padding: 16px;
    

    #workspace
        height: 100%;
        width: 70%;
        float: left;
        background: white;
    
    body
        width: 97%;
        height: 750px;
    
</style>

html:

<div id="editor" style="border: solid; ">
    <div id="palette">
        <div class="palette-item-container" elementId="element1">
            <div class="ui-icon ui-icon-alert"></div>
            Element1
        </div>
        <div class="palette-item-container" elementId="element2">
            <div class="ui-icon ui-icon-alert"></div>
            Element2
        </div>
        <div class="palette-item-container" elementId="element3">
            <div class="ui-icon ui-icon-alert"></div>
            Element3
        </div>
    </div>

    <div id="workspace">
        
    </div>
    
    <div id="elements">
        <div id="element1" class="editor-pane"></div>
        <div id="element2" class="editor-pane"></div>
        <div id="element3" class="editor-pane"></div>
    </div>
</div>

脚本

<script>
    var ElementCopy = null;
    
    $('#palette .palette-item-container').mousedown(function(evt) 
        ElementCopy = $('#' + $(this).attr("elementId")).clone().removeAttr('id');
        $('#editor').append(ElementCopy);
        ElementCopy.draggable(
            containment: "parent"
        );
        ElementCopy.css("left", evt.clientX - 20 + "px");
        ElementCopy.css("top", evt.clientY - 20 + "px");
        ElementCopy.trigger(evt);
        // console.log(evt);

        ElementCopy.mouseup(function(e)
            ElementCopy.draggable( "destroy" );
            ElementCopy.remove();
        );
    ); 
    
    $('#workspace').droppable(
        drop: function(evt) 
            if (ElementCopy)
                $('#workspace').append(ElementCopy);
                $('#workspace .editor-pane').resizable(
                    containment: "parent"
                )
                .draggable(
                    containment: "parent"
                );
                // $('#workspace .editor-pane').addClass('ui-draggable-handle');
            
        
    );

</script>

<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
        <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
        <title>Document</title>
        <style>
            #editor
                position: relative;
                height: 100%;
                width: 100%;
                background: lightcyan;
            
            #elements
                display: none;
            
            #palette
                height: 100%;
                width: 125px;
                float: left;
                background: lightgrey;
            
            .editor-pane
                height: 10%;
                width: 20%;
                float: left;
                background: lightyellow;
                position: absolute;
            
            .editor-palette-item
                width: 16px;
                height: 16px;
            
            .palette-item-container
                cursor: pointer;
                cursor: hand;
                padding: 16px;
            

            #workspace
                height: 100%;
                width: 70%;
                float: left;
                background: white;
            
            body
                width: 97%;
                height: 750px;
            
        </style>
    </head>
    <body>
        <div id="editor" style="border: solid; ">
            <div id="palette">
                <div class="palette-item-container" elementId="element1">
                    <div class="ui-icon ui-icon-alert"></div>
                    Element1
                </div>
                <div class="palette-item-container" elementId="element2">
                    <div class="ui-icon ui-icon-alert"></div>
                    Element2
                </div>
                <div class="palette-item-container" elementId="element3">
                    <div class="ui-icon ui-icon-alert"></div>
                    Element3
                </div>
            </div>
        
            <div id="workspace">
                <!-- <div id="element2" class="editor-pane"></div> -->
            </div>
            
            <div id="elements">
                <div id="element1" class="editor-pane">element1 data</div>
                <div id="element2" class="editor-pane">element2 data</div>
                <div id="element3" class="editor-pane">element3 data</div>
            </div>
        </div>

        <script>
            var ElementCopy = null;
            /*  $("#element2").resizable(
                    containment: "parent"
                ).draggable(
                    containment: "parent"
            ); */
            $('#palette .palette-item-container').mousedown(function(evt) 
                // console.log($(this).attr("elementId"));
                ElementCopy = $('#' + $(this).attr("elementId")).clone().removeAttr('id');
                $('#editor').append(ElementCopy);
                ElementCopy.draggable(
                    containment: "parent"
                );
                ElementCopy.css("left", evt.clientX - 20 + "px");
                ElementCopy.css("top", evt.clientY - 20 + "px");
                ElementCopy.trigger(evt);
                // console.log(evt);

                ElementCopy.mouseup(function(e)
                    ElementCopy.draggable( "destroy" );
                    ElementCopy.remove();
                );
            ); 
            
            $('#workspace').droppable(
                drop: function(evt) 
                    if (ElementCopy)
                        $('#workspace').append(ElementCopy);
                        $('#workspace .editor-pane').resizable(
                            containment: "parent"
                        )
                        .draggable(
                            containment: "parent"
                        );
                        // $('#workspace .editor-pane').addClass('ui-draggable-handle');
                    
                
            );

        </script>
    </body>
    </html>

【问题讨论】:

欢迎来到 Stack Overflow。我怀疑问题出在 mousedown 事件的逻辑范围内。我认为这是在以一种无法初始化可拖动和捕获事件的方式冒泡。因此,直到第二个 mousedown 事件才初始化可拖动对象。您是否有理由不只是将这些元素初始化为可拖动? 我需要能够构建一个可自定义的工作区,然后将其保存为模板以在不同的页面中可视化,所以这就像某种页面构建器,所以,如示例,我需要能够拖动元素,或者甚至不存在。 【参考方案1】:

考虑以下示例。

$(function() 
  $('#palette > .palette-item-container').draggable(
    containment: $("#editor"),
    helper: "clone",
    cursorAt: 
      left: -5,
      top: -5
    
  );

  $('#workspace').droppable(
    drop: function(evt, ui) 
      var elemCopy = ui.helper.clone().removeClass("ui-draggable ui-draggable-handle ui-draggable-dragging");
      elemCopy.attr("id", null).appendTo(this);
      elemCopy.draggable(
        containment: "parent"
      ).resizable(
        containment: "parent"
      );
    
  );
);
#editor 
  position: relative;
  height: 100%;
  width: 100%;
  background: lightcyan;


#elements 
  display: none;


#palette 
  height: 100%;
  width: 125px;
  float: left;
  background: lightgrey;


.editor-pane 
  height: 10%;
  width: 20%;
  float: left;
  background: lightyellow;
  position: absolute;


.editor-palette-item 
  width: 16px;
  height: 16px;


.palette-item-container 
  cursor: pointer;
  cursor: hand;
  padding: 16px;


#workspace 
  height: 100%;
  width: 70%;
  float: left;
  background: white;


body 
  width: 97%;
  height: 750px;
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<div id="editor" style="border: solid; ">
  <div id="palette">
    <div class="palette-item-container" elementId="element1">
      <div class="ui-icon ui-icon-alert"></div>
      Element1
    </div>
    <div class="palette-item-container" elementId="element2">
      <div class="ui-icon ui-icon-alert"></div>
      Element2
    </div>
    <div class="palette-item-container" elementId="element3">
      <div class="ui-icon ui-icon-alert"></div>
      Element3
    </div>
  </div>

  <div id="workspace">
    <!-- <div id="element2" class="editor-pane"></div> -->
  </div>

  <div id="elements">
    <div id="element1" class="editor-pane">element1 data</div>
    <div id="element2" class="editor-pane">element2 data</div>
    <div id="element3" class="editor-pane">element3 data</div>
  </div>
</div>

当你克隆一个元素时,默认情况下它不会克隆事件回调。因此,克隆的 Draggable Helper 将不可拖动。然而,它可能还剩下一些课程。通常最好的解决这一切的方法是 Droppable。

【讨论】:

问题是,在这段代码中,您从调色板本身克隆元素,但我不能这样做,因为在每个元素内部,都会有数据,数据太大或太乱而无法容纳在调色板上,所以调色板元素是元素的表示,而不是元素本身。此外,由于某种原因,此代码在第二次拖动后复制了元素:(​​

以上是关于在拖动另一个元素之前,可拖动的将不起作用的主要内容,如果未能解决你的问题,请参考以下文章

JQuery可拖动:使用助手时滚动不起作用:使用克隆

将可拖动对象放入可排序对象后,jQuery Click 事件不起作用

如果为空,则拖动到父 div 时,jQuery 可排序不起作用

jQuery 拖放模拟对最后一个可拖动对象不起作用

Angular2 可拖动指令,draggable="false" 不起作用

jquery - 如何让列表元素可排序并且也可拖动到另一个列表