As Web applications are increasingly used, we increasingly need to design more efficient methods for interaction with web pages. One of them is to use JavaScript to implement a draggable tree (Drag & Drop Tree). This article will introduce how to use JavaScript to create a draggable tree, detailing the implementation process and related technical details.
1. Goals to be achieved
The draggable tree described in this article refers to a structure on the web page, which contains nodes of the tree structure, and we can drag and drop them. Reorganize their hierarchical relationships. To implement such a tree, the following two key aspects need to be completed.
First we need to create nodes for the tree structure in the page and determine the levels and associations between the nodes. These contents can be represented using JSON. For example, we can store the structure of the tree in the following JSON format:
{ name: "节点A", children: [{ name: "子节点A1", children: [] }, { name: "子节点A2", children: [{ name: "子节点A2-1", children: [] }] }] }
When rendered as a tree structure, it should look like this:
- 节点A |- 子节点A1 |- 子节点A2 |- 子节点A2-1
Making nodes drag-and-drop requires the use of some JavaScript techniques. Regarding the drag and drop API, generally speaking, it involves three categories:
Using these APIs, we can easily implement the drag-and-drop function of nodes.
2. Technical details
After understanding our goals, let’s now discuss the implementation details in detail. The following are the steps to implement:
We need to create node elements first and add them to HTML, usually using ul and li element levels. accomplish. For each node, a li element is required, and more li elements must be nested in the child node ul. In order to associate the tree structure with JSON data, you can use the data-* attributes to store the JSON data in the corresponding li element.
<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>
We need to add drag events for each node, including mousedown, dragstart, dragover, dragleave, drop and dragend. Among them, mousedown and dragstart events need to be processed before dragging starts, and subsequent processing is dragover, dragleave, drop and dragend respectively. The handling functions of these drag and drop events can be completed through event listeners.
// 获取所有节点并添加事件监听器 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); });
The processing function of the drag event is somewhat complicated, and each step of the operation needs to be carefully designed. The following are instructions for each step:
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; }
3. Complete code
Finally, we integrate the above Javascript code to display a complete draggable tree. You can use this code directly, copy it into a text editor, save it as an html file and run it in the browser.
可拖动的树 <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>
Through the above code implementation, we successfully created a draggable tree structure. In the web page, users can easily adjust the tree structure by dragging and dropping. At the same time, we also introduced in detail various technical details during the implementation process. This is undoubtedly a very useful practical case for developers who are learning JavaScript.
The above is the detailed content of JavaScript implements draggable tree. For more information, please follow other related articles on the PHP Chinese website!