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



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

当元素不是动态的时,重新排序可以正常工作,但我添加到 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>

最新更新