ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript はドラッグ可能なツリーを実装します

JavaScript はドラッグ可能なツリーを実装します

WBOY
WBOYオリジナル
2023-05-12 10:17:37568ブラウズ

Web アプリケーションの使用が増えるにつれて、Web ページと対話するためのより効率的な方法を設計する必要性がますます高まっています。その 1 つは、JavaScript を使用してドラッグ可能なツリー (ドラッグ アンド ドロップ ツリー) を実装することです。この記事では、JavaScript を使用してドラッグ可能なツリーを作成する方法を紹介し、実装プロセスと関連する技術的な詳細を詳しく説明します。

1. 達成すべき目標

この記事で説明するドラッグ可能なツリーとは、ツリー構造のノードを含む Web ページ上の構造を指し、それらをドラッグ アンド ドロップできます。上下関係を再編成します。このようなツリーを実装するには、次の 2 つの主要な側面を完了する必要があります。

  1. ツリー構造の実装

まず、ページ内にツリー構造のノードを作成し、レベルとノード間の関連性を決定する必要があります。これらの内容は JSON を使用して表現できます。たとえば、ツリーの構造を次の JSON 形式で保存できます:

{
    name: "节点A",
    children: [{
        name: "子节点A1",
        children: []
    }, {
        name: "子节点A2",
        children: [{
            name: "子节点A2-1",
            children: []
        }]
    }]
}

ツリー構造としてレンダリングすると、次のようになります:

- 节点A
  |- 子节点A1
  |- 子节点A2
     |- 子节点A2-1
  1. ドラッグ アンド アンド ドロップの実装ドロップ機能

ノードをドラッグ アンド ドロップするには、JavaScript テクニックを使用する必要があります。ドラッグ アンド ドロップ API に関しては、一般的に次の 3 つのカテゴリが含まれます。

  • ドラッグ可能な要素
  • ターゲット要素の配置
  • データのドラッグ

これらの API を使用すると、ノードのドラッグ アンド ドロップ機能を簡単に実装できます。

2. 技術的な詳細

目標を理解した後、実装の詳細について詳しく説明します。実装する手順は次のとおりです。

  1. ツリー構造の構築

最初にノード要素を作成し、通常は ul および li 要素レベルを使用して HTML に追加する必要があります。 。 成し遂げる。各ノードには li 要素が必要であり、さらに多くの li 要素を子ノード ul にネストする必要があります。ツリー構造を JSON データに関連付けるには、data-* 属性を使用して、対応する li 要素に JSON データを格納します。

<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>
  1. ノードへのドラッグ イベントの追加

各ノードに、mousedown、dragstart、dragover、dragleave、drop、dragend などのドラッグ イベントを追加する必要があります。このうち、mousedown イベントとragstart イベントはドラッグを開始する前に処理する必要があり、その後の処理はそれぞれ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);
});
  1. ドラッグ イベントの処理関数の実装

ドラッグ イベントの処理関数はやや複雑で、各ステップの操作を慎重に設計する必要があります。各ステップの手順は次のとおりです。

  • mousedown: ドラッグが開始される要素を記録し、isDragged を true に設定します。
  • dragstart: データ送信タイプと送信するデータを設定します。また、isDraggedの状態に基づいてドラッグ操作が可能かどうかを判断する必要がある。データ送信タイプを設定するには、setData() メソッドを使用できます。
function onDragStart(event) {
    if (!isDragged) {
        draggedItem = event.currentTarget.parentNode;
        event.dataTransfer.setData('text/plain', event.currentTarget.dataset.name);
        isDragged = true;
    }
}
  • dragover: デフォルトのイベントを防止し、現在の要素に isOver 属性を追加します。この属性は、現在の要素が他の要素の上に配置され、配置可能であることを示します。デフォルトのイベントは、event.preventDefault() メソッドを通じて防止できます。
function onDragOver(event) {
    event.preventDefault();
    if (!event.currentTarget.dataset.isOver) {
        event.currentTarget.parentNode.classList.add('over');
        event.currentTarget.dataset.isOver = true;
    }
}
  • dragleave: 現在の要素の over 属性を削除し、要素上にマウスが置かれていないことを示します。
function onDragLeave(event) {
    if (event.currentTarget.dataset.isOver) {
        event.currentTarget.parentNode.classList.remove('over');
        event.currentTarget.dataset.isOver = false;
    }
}
  • drop: 現在の要素に over 属性があるかどうかに基づいて、配置操作を実行できるかどうかを判断します。動作しない場合は直接終了し、動作する場合は配置操作を実行してツリー構造を調整します。
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);
    }
}
  • dragend: ドラッグ操作の終了イベントを実装します。このイベントでは、isDragged の値をリセットし、属性全体を削除します。
function onDragEnd(event) {
    event.currentTarget.parentNode.classList.remove('over');
    event.currentTarget.dataset.isOver = false;
    isDragged = false;
}

3. 完全なコード

最後に、上記の Javascript コードを統合して、完全なドラッグ可能なツリーを表示します。このコードを直接使用し、テキスト エディターにコピーし、HTML ファイルとして保存して、ブラウザーで実行できます。




    
    可拖动的树
    


<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>

上記のコード実装により、ドラッグ可能なツリー構造を作成できました。Web ページでは、ユーザーはドラッグ アンド ドロップで簡単にツリー構造を調整できます。同時に、実装プロセスにおけるさまざまな技術的な詳細も詳細に紹介されており、JavaScript を学習している開発者にとって非常に役立つ実践事例であることは間違いありません。

以上がJavaScript はドラッグ可能なツリーを実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。