javascript - 拖放排序不适用于动态元素

标签 javascript

目前,我的用户可以输入一个字符串,该字符串会被分割成单词,并且用户可以对这些单词重新排序。

当元素不是动态时,重新排序可以正常工作,但我添加到 DOM 中的元素无法拖放。

我已经仔细检查过,所有相同的属性都应用于动态创建的元素,就像应用于列表中已存在的元素的属性一样。

这是我的代码:

function generateWords() {

  var inputedString = document.getElementById("stringInput").value;

  var splitStringArray = inputedString.split(" ");

  for (var i = 0; i < splitStringArray.length; i++) {
    var listItem = document.createElement("li");
    var textNode = document.createTextNode(splitStringArray[i]);
    document.getElementById("columns").appendChild(listItem);

    var attrClass = document.createAttribute("class");
    attrClass.value = "column";

    listItem.setAttributeNode(attrClass);

    document.getElementById("columns").appendChild(listItem);

    var headerItem = document.createElement("header");
    var columns = document.getElementsByClassName("column");
    for (var j = 0; j < columns.length; j++) {
      headerItem.appendChild(textNode);
      columns[j].appendChild(headerItem);
    }

  }
}


function enableDragSort(listClass) {
  const sortableLists = document.getElementsByClassName(listClass);
  Array.prototype.map.call(sortableLists, (list) => {
    enableDragList(list)
  });
}

function enableDragList(list) {
  Array.prototype.map.call(list.children, (item) => {
    enableDragItem(item)
  });
}

function enableDragItem(item) {
  item.setAttribute('draggable', true)
  item.ondrag = handleDrag;
  item.ondragend = handleDrop;
}

function handleDrag(item) {
  const selectedItem = item.target,
    list = selectedItem.parentNode,
    x = event.clientX,
    y = event.clientY;

  selectedItem.classList.add('drag-sort-active');
  let swapItem = document.elementFromPoint(x, y) === null ? selectedItem : document.elementFromPoint(x, y);

  if (list === swapItem.parentNode) {
    swapItem = swapItem !== selectedItem.nextSibling ? swapItem : swapItem.nextSibling;
    list.insertBefore(selectedItem, swapItem);
  }
}

function handleDrop(item) {
  item.target.classList.remove('drag-sort-active');
}

(() => {
  enableDragSort('drag-sort-enable')
})();
#columns {
  list-style-type: none;
  margin: 20px;
  display: -webkit-inline-box;
}

.column {
  width: 162px;
  padding-bottom: 5px;
  padding-top: 5px;
  padding-right: 5px;
  text-align: center;
  cursor: move;
}

.column header {
  height: 20px;
  width: 150px;
  color: black;
  background-color: #ccc;
  padding: 5px;
  border-bottom: 1px solid #ddd;
  border-radius: 10px;
  border: 2px solid #666666;
}

.column:hover {
  background: red;
}
<!DOCTYPE html>
<html>

<body>

  <ul id="columns" class="drag-sort-enable">
    <li class="column">
      <header>Not dynamic</header>
    </li>
    <li class="column">
      <header>Also NOT dynamic</header>
    </li>
  </ul>

  <form>
    Enter String to generate words:<input type="text" id="stringInput" name="stringInput" /><br/>
  </form>


  <button onclick="generateWords()">Generate Words</button>

</body>

</html>

最佳答案

附加项目后,您应该在 generateWords() 内调用 enableDragItem(listItem):

function generateWords() {

  var inputedString = document.getElementById("stringInput").value;

  var splitStringArray = inputedString.split(" ");

  for (var i = 0; i < splitStringArray.length; i++) {
    var listItem = document.createElement("li");
    var textNode = document.createTextNode(splitStringArray[i]);
    document.getElementById("columns").appendChild(listItem);

    var attrClass = document.createAttribute("class");
    attrClass.value = "column";

    listItem.setAttributeNode(attrClass);
    
    document.getElementById("columns").appendChild(listItem);
    enableDragItem(listItem); // call it here
    var headerItem = document.createElement("header");
    var columns = document.getElementsByClassName("column");
    for (var j = 0; j < columns.length; j++) {
      headerItem.appendChild(textNode);
      columns[j].appendChild(headerItem);
    }

  }
}


function enableDragSort(listClass) {
  const sortableLists = document.getElementsByClassName(listClass);
  Array.prototype.map.call(sortableLists, (list) => {
    enableDragList(list)
  });
}

function enableDragList(list) {
  Array.prototype.map.call(list.children, (item) => {
    enableDragItem(item)
  });
}

function enableDragItem(item) {
  item.setAttribute('draggable', true)
  item.ondrag = handleDrag;
  item.ondragend = handleDrop;
}

function handleDrag(item) {
  const selectedItem = item.target,
    list = selectedItem.parentNode,
    x = event.clientX,
    y = event.clientY;

  selectedItem.classList.add('drag-sort-active');
  let swapItem = document.elementFromPoint(x, y) === null ? selectedItem : document.elementFromPoint(x, y);

  if (list === swapItem.parentNode) {
    swapItem = swapItem !== selectedItem.nextSibling ? swapItem : swapItem.nextSibling;
    list.insertBefore(selectedItem, swapItem);
  }
}

function handleDrop(item) {
  item.target.classList.remove('drag-sort-active');
}

(() => {
  enableDragSort('drag-sort-enable')
})();
#columns {
  list-style-type: none;
  margin: 20px;
  display: -webkit-inline-box;
}

.column {
  width: 162px;
  padding-bottom: 5px;
  padding-top: 5px;
  padding-right: 5px;
  text-align: center;
  cursor: move;
}

.column header {
  height: 20px;
  width: 150px;
  color: black;
  background-color: #ccc;
  padding: 5px;
  border-bottom: 1px solid #ddd;
  border-radius: 10px;
  border: 2px solid #666666;
}

.column:hover {
  background: red;
}
<ul id="columns" class="drag-sort-enable">
  <li class="column">
    <header>Not dynamic</header>
  </li>
  <li class="column">
    <header>Also NOT dynamic</header>
  </li>
</ul>

<form>
  Enter String to generate words:<input type="text" id="stringInput" name="stringInput" /><br/>
</form>


<button onclick="generateWords()">Generate Words</button>

关于javascript - 拖放排序不适用于动态元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57162465/

相关文章:

Javascript:在函数外获取 `this`

javascript - 使用 AJAX 初始化 Vue 数据

javascript - 无法获取一页中多个选项卡的总记录值

javascript - 预加载图库图像。 JavaScript(无 JQuery)

javascript - 使用标记从谷歌地图获取纬度/经度坐标

javascript - 单击时如何旋转选择框的插入符号图标?

javascript - 获取已在 OpenLayers 3 中单击的图层的要素属性

javascript - 如何使用样式将 iframe 中的克隆节点复制到其父节点?

添加到 ul 列表时 JavaScript 无限循环

javascript - Ajax 请求在 Tizen 模拟器中取消,但在浏览器中未取消