我们如何使用drag克隆任何HTML元素然后将其放入另一列(仅在该列中不在其中)

问题描述 投票:1回答:1

我在HTML 5中进行拖放工作。有人建议我使用jquery-ui,因为他们已经实现了很多东西。

我现在只能在一列中拖放任何HTML元素,但我希望能够将任何HTML元素从一列克隆到另一列。我希望原始元素也保留在其原始列中。

这个概念在this example中显示。

在这个例子中,“test”div可以被克隆并丢弃到任何地方,但是我只能在“drop”列中删除它 - 它可以被删除在这个列的任何地方。

删除后,我还想调整它的大小,更改位置,在文件或数据库中保存大小,宽度,高度等属性。

javascript jquery html css jquery-ui
1个回答
0
投票

一些修复开始:

var b=parseInt($(this.width));

这失败了。我建议:

var b = parseInt($(this).width());

这将返回this的Width值,然后将其解析为Integer。您可能需要考虑parseFloat(),以防您有一个奇数大小的元素,其宽度为30.5像素。

你的拖鞋有很多不需要的东西。改为:

  $('.test').draggable({
    helper: "clone",
    revert: "invalid"
  }).click(function() {
    var b = parseInt($(this).width());
    $(this).css('width', b + 5);
  });

您需要在droppable中添加更多内容才能获得所需内容。

  $('#drop').droppable({
    accept: ".test",
    drop: function(e, u) {
      var a = u.helper.clone();
      console.log("INFO: Accepted: ", a.attr("class"));
      a.css("z-index", 1000);
      a.appendTo("#drop");
      a.attr('class', 'dropped').draggable({
        containment: "#drop"
      });
    }
  });

我将CSS移动到它自己的部分,这使您不必调整每个元素的CSS。

双击.dropped元素时,我还添加了Resize。

这是一切和一个工作的例子:https://jsfiddle.net/Twisty/u172wuer/

HTML

<div class="test red square"></div>
<div id="drop"></div>

CSS

.test {
  width: 50px;
  height: 50px;
  background-color: red;
}

#drop {
  width: 200px;
  height: 200px;
  background-color: green;
}

.dropped {
  width: 50px;
  height: 50px;
  background-color: blue;
}

jQuery的

$(document).ready(function() {
  $('.test').draggable({
    helper: "clone",
    revert: "invalid"
  }).click(function() {
    var b = parseInt($(this).width());
    $(this).css('width', b + 5);
  });
  $('#drop').droppable({
    accept: ".test",
    drop: function(e, u) {
      var a = u.helper.clone();
      console.log("INFO: Accepted: ", a.attr("class"));
      a.css("z-index", 1000);
      a.appendTo("#drop");
      a.attr('class', 'dropped').draggable({
        containment: "#drop"
      }).dblclick(function() {
        // Enabled Resize on element when double clicked
        $(this).resizable();
      });
    }
  });
  $(document).click(function() {
    if ($(".dropped").length) {
      // Disabled Resize on all elements when #drop
      $(".ui-resizable").resizable("destroy");
    }
  });
});

希望这是你所驾驶的,但你的帖子不太清楚。随意评论。

更新

根据您的意见,您正在寻找更先进的方法。像<button><input>这样的元素的问题在于它们本质上是你点击它们并且一个事件被绑定到那个元素。

为了能够实现这一点,我建议你用<div>包装元素,给你一些东西来移动元素,调整大小等等。在以下示例中,所有元素仍处于活动状态,因此在删除时它们处于活动状态。

工作示例:https://jsfiddle.net/5yd6uu45/20/

HTML

<div class="elements">
  <div class="new button-wrapper element ui-widget-content ui-corner-all" data-item-type="button">
    <span class="side-handle ui-icon ui-icon-grip-dotted-vertical"></span>
    <button class="" title="">New Button</button>
  </div>
  <div class="new textbox-wrapper element ui-widget-content ui-corner-all" data-item-type="input[type='text']">
    <span class="side-handle ui-icon ui-icon-grip-dotted-vertical"></span>
    <input type="text" class="" title="" placeholder="New Textbox" />
  </div>
  <div class="new label-wrapper element ui-widget-content ui-corner-all" data-item-type="label">
    <span class="side-handle ui-icon ui-icon-grip-dotted-vertical"></span>
    <label class="" title="">New Label</label>
  </div>
</div>
<div id="drop"></div>

<div id="dialog-settings" title="Edit Settings">
  <p class="validateTips"></p>
  <form>
    <fieldset>
      <label for="idValue">Element ID</label>
      <input type="text" name="idValue" id="idValue" class="text ui-widget-content ui-corner-all" data-attr-name="id" />
      <label for="titleValue">Element Title</label>
      <input type="text" name="titleValue" id="titleValue" class="text ui-widget-content ui-corner-all" data-attr-name="title" />
      <label for="titleValue">Element Class</label>
      <input type="text" name="classValue" id="classValue" class="text ui-widget-content ui-corner-all" data-attr-name="class" />
      <label for="innerText">Text</label>
      <input type="text" name="innerText" id="innerText" class="text ui-widget-content ui-corner-all" data-attr-name="text" />
      <label for="eventType">Event</label>
      <select id="eventType">
        <option></option>
        <option>onBlur</option>
        <option>onClick</option>
        <option>onChange</option>
        <option>onFocus</option>
      </select>
      <label for="eventValue">Script</label>
      <input type="text" name="eventValue" id="eventValue" class="text ui-widget-content ui-corner-all" />

      <!-- Allow form submission with keyboard without duplicating the dialog button -->
      <input type="submit" tabindex="-1" style="position:absolute; top:-1000px">
    </fieldset>
  </form>
</div>

CSS

.elements {
  margin: 3px;
  padding: 6px;
  border: 1px solid #ccc;
  border-radius: 6px;
  background: #666;
  position: relative;
}

.elements div.element {
  display: inline-block;
  padding: 3px;
  padding-right: 6px;
  margin: 0;
}

.side-handle {
  display: inline-block;
  width: 10px;
  height: 20px;
  margin-bottom: -5px;
  cursor: grab;
}

.top-handle {
  position: absolute;
  top: 0;
  left: 50%;
  margin-left: -8px;
  cursor: grab;
}

.top-settings {
  position: absolute;
  top: 0;
  left: 0;
  cursor: pointer;
}

.top-delete {
  position: absolute;
  top: 0;
  left: 100%;
  margin-left: -16px;
  cursor: pointer;
}

.form-wrapper form {
  display: inline-block;
  height: 19px;
  border: 1px dashed #222;
  padding: 1px 3px;
}

#drop {
  width: 500px;
  height: 340px;
  background-color: #ddd;
  border: 1px solid #aaa;
  border-radius: 12px;
  margin: 3px;
}

#drop div.element {
  display: block;
  padding: 3px;
  padding-top: 16px;
  margin: 0;
}

#drop div.element form,
#drop div.element button,
#drop div.element input,
#drop div.element label {
  width: 100%;
  height: 100%;
}

#dialog-settings {
  font-size: 62.5%;
}

#dialog-settings label,
#dialog-settings input {
  display: block;
}

#dialog-settings input.text {
  margin-bottom: 12px;
  width: 95%;
  padding: .4em;
}

#dialog-settings select {
  margin-bottom: 12px;
  width: 95%;
}

#dialog-settings fieldset {
  padding: 0;
  border: 0;
  margin-top: 25px;
}

.ui-dialog .ui-state-error {
  padding: .3em;
}

.validateTips {
  border: 1px solid transparent;
  padding: 0.3em;
}

jQuery的

var tmpElement;
$(document).ready(function() {
  $('.new').draggable({
    helper: "clone",
    revert: "invalid"
  });

  $('#drop').droppable({
    accept: ".new",
    drop: function(e, u) {
      var a = u.helper.clone();
      console.log("INFO: Accepted: ", a.data("item-type"));
      a.appendTo("#drop");
      makeId(a.find(a.data("item-type")));
      a.removeClass("new");
      a.find(".side-handle").remove();
      var handle, set, rem;
      handle = $("<span>", {
        title: "Double-click to resize",
        class: "top-handle ui-icon ui-icon-grip-dotted-horizontal"
      });
      set = $("<span>", {
          title: "Click to Edit settings",
          class: "top-settings ui-icon ui-icon-gear"
        })
        .click(function() {
          var $wrpr = $(this).parent();
          var elType = $wrpr.data("item-type");
          var $tElem = $wrpr.find(elType);
          var inText = $tElem.text().trim();
          var elId = $tElem.attr("id");
          var elTitle = $tElem.attr("title");
          var elClass = $tElem.attr("class");
          var elEvent = false,
            elScript = "";
          switch (true) {
            case $tElem.is("[onblur]"):
              elEvent = "onBlur";
              break;
            case $tElem.is("[onclick]"):
              elEvent = "onClick";
              break;
            case $tElem.is("[onchange]"):
              elEvent = "onChange";
              break;
            case $tElem.is("[onfocus]"):
              elEvent = "onFocus";
              break;
          }
          if (elEvent) {
            elScript = $tElem.attr(elEvent);
          }
          if (elType == "input[type='text']") {
            inText = $(this).parent().find(elType).attr("placeholder");
          }
          tmpElement = $(this).parent().find(elType);
          console.log("INFO: Editing " + tmpElement.prop("outerHTML"));
          $("#dialog-settings #idValue").val(elId);
          $("#dialog-settings #titleValue").val(elTitle);
          $("#dialog-settings #classValue").val(elClass);
          $("#dialog-settings #innerText").val(inText);
          if (elEvent) {
            $("#dialog-settings #eventType").val(elEvent);
            $("#dialog-settings #eventValue").val(elScript)
          }
          $("#dialog-settings").dialog("open");
        });
      rem = $("<span>", {
          title: "Click to Delete element",
          class: "top-delete ui-icon ui-icon-close"
        })
        .click(function() {
          $(this).parent().remove();
        });
      a.append(handle, set, rem);
      a.addClass('dropped').draggable({
        containment: "#drop"
      }).dblclick(function() {
        // Enabled Resize on element when double clicked
        var thisEl = $(this).data("item-type");
        $(this).resizable({
          alsoResize: ".dropped " + thisEl
        });
      });
    }
  });

  $("#dialog-settings").dialog({
    autoOpen: false,
    height: 425,
    width: 350,
    modal: true,
    buttons: {
      "Update": saveEl,
      Cancel: function() {
        $(this).dialog("close");
      }
    },
    close: function() {
      $("#dialog-settings form")[0].reset();
      $("#dialog-settings .text").removeClass("ui-state-error");
    },
    open: function() {
      console.log("INFO: Settings Dialog opened.");
    }
  });

  $("#dialog-settings form").submit(saveEl);

  function saveEl() {
    var target = tmpElement,
      data = {};
    $("#dialog-settings .text").removeClass("ui-state-error");
    $("#dialog-settings .text").each(function(k, v) {
      data[$(v).data("attr-name")] = $(v).val();
    });
    if (data.id == null || data.id == "undefined" || data.id == "") {
      var c = $("#drop " + target.parent().data("item-type")).length;
      data.id = target.parent().data("item-type") + "-" + c;
    }
    if (validId(data.id)) {
      target.attr({
        id: data.id,
        title: data.title,
        class: data.class
      });
      if ($("#eventType").val() != "") {
        target.attr($("#eventType").val(), $("#eventValue").val());
      } else {
        target.attr({
          onBlur: "",
          onClick: "",
          onChange: "",
          onFocus: ""
        });
      }
      if (target.parent().data("item-type") == "input[type='text']") {
        target.attr("placeholder", data.text);
      } else {
        target.text(data.text);
      }
      $("#dialog-settings").dialog("close");
      console.log("INFO: Element " + data.id + " updated.");
    } else {
      $("#idValue").addClass("ui-state-error");
      updateTips("ID must be unique.");
    }
    return false;
  }

  function validId(str) {
    var valid = true;
    $("#drop div").each(function(k, v) {
      var el = $(v).data("item-type");
      var target = $(v).find(el);
      if (target.find("[id='" + str + "']").length) {
        valid = false;
        console.log("ERROR: Invalid Element ID.");
      }
    });
    return valid;
  }

  function updateTips(t) {
    $(".validateTips").text(t)
      .addClass("ui-state-highlight");
    setTimeout(function() {
      $(".validateTips").removeClass("ui-state-highlight", 1500);
    })
  }

  function makeId(t, str) {
    var c = $("#drop " + $(t).parent().data("item-type")).length;
    if (str == "undefined" || str == "" || str == null) {
      console.log("INFO: Generating ID.");
      if ($(t).parent().data("item-type").indexOf("input") == 0) {
        $(t).attr("id", "input-" + c);
      } else {
        $(t).attr("id", $(t).parent().data("item-type") + "-" + c);
      }
    } else {
      console.log("INFO: ID was passed.");
      $(t).attr("id", str);
    }
    console.log("INFO: Assigned ID '" + $(t).attr("id") + "' to " + $(t).parent().data("item-type"));
  }

  $(document).click(function() {
    if ($(".dropped").length) {
      // Disabled Resize on all elements when #drop
      $(".ui-resizable").resizable("destroy");
    }
  });
});

如您所见,代码量明显增加。现在你也可以通过很多其他方式做到这一点。您还必须现在进入如何保存元素,所有属性和位置。因此,这可能比你想要的更多,它实际上甚至真的刮到了你正在试图完成的表面。

© www.soinside.com 2019 - 2024. All rights reserved.