我在普通javascript(没有jQuery)中构建分类法管理器,其中一部分要求可以拖动节点(LI元素)并将其转换为另一个LI上的子元素。我创建了一个" Child" UL动态地和占位符LI并且将一组嵌套的事件监听器附加到UL以便处理" drop"部分。可悲的是," dragover"工作正常并且正在开火,但是"掉落"事件不是。我错过了什么?
我已粘贴下面的代码,但相当多!我在codepen here中有完整的源代码。
TaxonomyManager.prototype.attachDragDropEventListeners = function () {
var manager = this;
[].forEach.call(this._nodes, function(item) {
item.draggable = true;
item.addEventListener('dragstart', dragStartHandler, false);
item.addEventListener('dragover', dragOverHandler, false);
item.addEventListener('dragleave', dragLeaveHandler, false);
item.addEventListener('drop', dropHandler, false);
item.addEventListener('dragend', dragEndHandler, false);
manager._dragSource = null;
function dragStartHandler(e) {
manager._dragSource = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
function dragOverHandler(e) {
if (e.preventDefault) {
e.preventDefault(); // Necessary. Allows us to drop.
}
removeNewSubTaxonomyPlaceholder();
if ((this.children.length === 0) && (manager._dragSource !== this)) {
var ul = document.createElement('UL');
ul.classList.add('new-sub-taxonomy');
ul.draggable = true;
ul.addEventListener('dragstart', dragStartHandler, false);
ul.addEventListener('dragover', dragOverPlaceholderHandler, false);
ul.addEventListener('dragleave', dragLeaveHandler, false);
ul.addEventListener('drop', dropPlaceholderHandler, false);
ul.addEventListener('dragend', dragEndHandler, false);
var li = document.createElement("LI");
li.classList.add('new-sub-taxonomy-placeholder');
var liText = document.createTextNode("Drop here");
li.appendChild(liText);
ul.appendChild(li);
this.appendChild(ul);
}
e.dataTransfer.dropEffect = 'move';
return false;
}
function dragLeaveHandler(e) {
return false;
}
function dropHandler(e) {
if (e.stopPropagation) {
e.stopPropagation(); // stops the browser from redirecting.
}
if (manager._dragSource !== this) {
var temp = document.createElement("li");
manager._dragSource.parentNode.insertBefore(temp, manager._dragSource);
this.parentNode.insertBefore(manager._dragSource, this);
temp.parentNode.insertBefore(this, temp);
temp.parentNode.removeChild(temp);
}
return false;
}
function dragEndHandler(e) {
removeNewSubTaxonomyPlaceholder();
return false;
}
function dragOverPlaceholderHandler(e) {
if (e.preventDefault) {
e.preventDefault(); // Necessary. Allows us to drop.
}
console.log('this fires');
e.dataTransfer.dropEffect = 'move';
return false;
}
function dropPlaceholderHandler(e) {
console.log('this does not fire');
if (e.stopPropagation) {
e.stopPropagation(); // stops the browser from redirecting.
}
manager.addLeaf(manager._dragSource.firstChild, this.parentNode.parentNode.dataset.id);
manager.renderTree();
return false;
}
function removeNewSubTaxonomyPlaceholder() {
var placeholder = document.querySelector('.new-sub-taxonomy');
if (placeholder) {
placeholder.parentNode.removeChild(placeholder);
}
}
});
};
答案 0 :(得分:1)
看看这个:GITHUB link
Jquery JS链接: https://github.com/ilikenwf/nestedSortable/blob/2.0alpha/jquery.mjs.nestedSortable.js
使用过的功能的一些自定义详细信息
disableParentChange(2.0) 将此设置为true可锁定项目的父项。它们只能在当前的父容器中重新排序。
doNotClear(2.0) 如果您不希望删除空列表,请将此项设置为true。默认值:false
expandOnHover(2.0) 在展开折叠节点之前等待多长时间(以毫秒为单位)(仅在isTree:true时有用)。默认值:700
isAllowed(功能) 您可以指定自定义函数以验证是否允许放置位置。默认值:function(占位符,placeholderParent,currentItem){return true; }
isTree(2.0) 如果要使用新树功能,请将此属性设置为true。默认值:false
答案 1 :(得分:1)
基本上问题是我需要向连接的父节点和子节点上的e.stopPropagation()
和e.preventDefault()
事件处理程序添加更多dragover
和drop
语句对那些事件。
我想这就是你在凌晨3点编码所得到的!