随着web应用程序越来越多地被应用,我们愈加需要能够为网页的交互设计更高效的方法。其中之一就是使用javascript实现可拖动的树(drag & drop tree)。本文将介绍如何使用javascript创建可拖动的树,详细介绍实现的过程及其相关技术细节。
一、实现的目标
本文所描述的可拖动的树,是指网页上的一个结构,其中包含树形结构的节点,而我们可以通过拖拽来重新组织它们的层次关系。实现这样的树,需要完成以下两个关键方面。
首先我们需要在页面中为树形结构创建节点,并确定节点之间的层次和关联。这些内容可以使用JSON来表示。例如,我们可以以下列JSON格式存储树的结构:
{
name: "节点A",
children: [{
name: "子节点A1",
children: []
}, {
name: "子节点A2",
children: [{
name: "子节点A2-1",
children: []
}]
}]
}将其呈现为树状结构时,应该是这样的:
立即学习“Java免费学习笔记(深入)”;
- 节点A
|- 子节点A1
|- 子节点A2
|- 子节点A2-1让节点可以拖放需要使用一些JavaScript技术。有关拖放的API,常规来说涉及到三种类:
使用这些API,我们可以轻松实现节点的拖拽功能。
二、技术细节
了解了我们的目标后,现在我们来详细讨论实现细节。下面是实现的步骤:
我们需要先创建节点元素,并添加它们到HTML中,通常使用ul和li元素层次来实现。对于每一个节点,都需要一个li元素,而且要在子节点ul中嵌套更多的li元素。为了将树形结构和JSON数据关联,可以使用data-*属性,将JSON数据存储在相应的li元素中。
<ul id="tree">
<li data-name="节点A">
<div class="node">节点A</div>
<ul>
<li data-name="子节点A1">
<div class="node">子节点A1</div>
</li>
<li data-name="子节点A2">
<div class="node">子节点A2</div>
<ul>
<li data-name="子节点A2-1">
<div class="node">子节点A2-1</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>我们需要为每一个节点添加拖拽事件,包括mousedown、dragstart、dragover、dragleave、drop和dragend。其中,mousedown和dragstart事件需要在拖拽开始前处理,和后续处理分别依次为dragover、dragleave、drop和dragend。这些拖拽事件的处理函数可以通过事件监听器来完成。
// 获取所有节点并添加事件监听器
const nodes = document.querySelectorAll('.node');
nodes.forEach((node) => {
node.addEventListener('mousedown', onMouseDown);
node.addEventListener('dragstart', onDragStart);
node.addEventListener('dragover', onDragOver);
node.addEventListener('dragleave', onDragLeave);
node.addEventListener('drop', onDrop);
node.addEventListener('dragend', onDragEnd);
});拖拽事件的处理函数有些复杂,需要仔细设计每一个步骤的操作。以下是每一个步骤的说明:
function onDragStart(event) {
if (!isDragged) {
draggedItem = event.currentTarget.parentNode;
event.dataTransfer.setData('text/plain', event.currentTarget.dataset.name);
isDragged = true;
}
}function onDragOver(event) {
event.preventDefault();
if (!event.currentTarget.dataset.isOver) {
event.currentTarget.parentNode.classList.add('over');
event.currentTarget.dataset.isOver = true;
}
}function onDragLeave(event) {
if (event.currentTarget.dataset.isOver) {
event.currentTarget.parentNode.classList.remove('over');
event.currentTarget.dataset.isOver = false;
}
}function onDrop(event) {
event.preventDefault();
if (event.currentTarget.dataset.isOver) {
const droppedItem = event.currentTarget.parentNode;
const parent = draggedItem.parentNode;
parent.removeChild(draggedItem);
event.currentTarget.parentNode.insertBefore(draggedItem, droppedItem.nextSibling);
}
}function onDragEnd(event) {
event.currentTarget.parentNode.classList.remove('over');
event.currentTarget.dataset.isOver = false;
isDragged = false;
}三、完整代码
最后,我们将以上的Javascript代码整合在一起,展示一个完整的可拖动的树。可以直接使用该代码,将其复制到文本编辑器中,保存为html文件即可在浏览器中运行。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>可拖动的树</title>
<style>
.over {
border-top: 5px solid blue !important;
}
</style>
</head>
<body>
<ul id="tree">
<li data-name="节点A">
<div class="node">节点A</div>
<ul>
<li data-name="子节点A1">
<div class="node">子节点A1</div>
</li>
<li data-name="子节点A2">
<div class="node">子节点A2</div>
<ul>
<li data-name="子节点A2-1">
<div class="node">子节点A2-1</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<script>
let draggedItem = null;
let isDragged = false;
const nodes = document.querySelectorAll('.node');
nodes.forEach((node) => {
node.addEventListener('mousedown', onMouseDown);
node.addEventListener('dragstart', onDragStart);
node.addEventListener('dragover', onDragOver);
node.addEventListener('dragleave', onDragLeave);
node.addEventListener('drop', onDrop);
node.addEventListener('dragend', onDragEnd);
});
function onMouseDown(event) {
event.preventDefault();
}
function onDragStart(event) {
if (!isDragged) {
draggedItem = event.currentTarget.parentNode;
event.dataTransfer.setData('text/plain', event.currentTarget.dataset.name);
isDragged = true;
}
}
function onDragOver(event) {
event.preventDefault();
if (!event.currentTarget.dataset.isOver) {
event.currentTarget.parentNode.classList.add('over');
event.currentTarget.dataset.isOver = true;
}
}
function onDragLeave(event) {
if (event.currentTarget.dataset.isOver) {
event.currentTarget.parentNode.classList.remove('over');
event.currentTarget.dataset.isOver = false;
}
}
function onDrop(event) {
event.preventDefault();
if (event.currentTarget.dataset.isOver) {
const droppedItem = event.currentTarget.parentNode;
const parent = draggedItem.parentNode;
parent.removeChild(draggedItem);
event.currentTarget.parentNode.insertBefore(draggedItem, droppedItem.nextSibling);
}
}
function onDragEnd(event) {
event.currentTarget.parentNode.classList.remove('over');
event.currentTarget.dataset.isOver = false;
isDragged = false;
}
</script>
</body>
</html>通过以上的代码实现,我们成功创建了一个可拖动的树型结构,在网页中用户可以通过轻松拖拽操作来调整树状结构。同时,我们还详细介绍了实现的过程中各种技术细节,对于正在学习JavaScript的开发者来说,这无疑是一个非常有用的实践案例。
以上就是javascript实现可拖动的树的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号