🚀 JavaScriptのわずか16行で強力なドラッグアンドドロップの実装


ドラッグアンドドロップは、ユーザーのためのプロセスの大部分を簡素化することができるアプリケーションで非常に便利なツールです.また、我々はあなたがアプリケーションを使用するときにだけ非常に簡単な実装を必要とするときにあなたのアプリケーションをblomat可能性があります他のライブラリに委任する共通のタスクですDrag and Drop Web API . 今日は、どのようにそれを行うことができますをお見せしましょう!

何を作っている
これが基本的な実装です.
それはJavaScriptのわずか16行で作られた!
そして、いくつかのラインで我々は多くのボーナス機能を追加することができます!ここではいくつかの機能とデモです!
それを再生すると、私たちができることがわかります
  • 特定の場所にのみ要素をドロップする
  • スタイルを削除します
  • ドラッグされた要素のオリジナルのコピーを作成する
  • (少しトリッキーで)もスタイルをドラッグ!
  • すべてのコードのわずか30行で!
    それはほとんどすべてのデスクトップブラウザ上の部分的なサポートのすべての方法をバックにIEこれは動作するのに十分なはずですが、いくつかのモバイルブラウザでは動作しません.
    ここで最新のcaniuseデータを見ることができます.

    この非常に基本的な機能のためのライブラリを扱うことは私にとって痛みでした、そして、あなたに私が私がここでプロセスを文書化すると思ったトラブルを保存するために!

    HTML構造

    場所
    いくつかのドロップターゲットを右にそれらに何かをドラッグできるようにする必要がありますか?通常のdivでこれらを追加できます:
    <div class='drop'></div>
    <div class='drop'></div>
    <div class='drop'></div>
    <div class='drop'></div>
    
    

    Note: I'll be referring to the places we can drop into as drop targets in this post


    あなたがそれらの多くを追加することができますどこにでも、要素がある限りdrop 我々はクラスにドロップすることができます.
    また、それらのためのいくつかの基本的なスタイルを追加することができます素敵に見える.
    * {
        box-sizing: border-box;
        font-family: sans-serif;
    }
    
    .drop {
        width: 220px;
        height: 45px;
        background: #2563EB;
        margin-bottom: 10px;
        padding: 10px;
        border-radius: 3px;
    }
    
    

    ドラッグする要素
    要素がdraggableであるために、我々は、よく、要素を必要とする!我々は、我々が前に作ったドロップターゲットの1つに要素を置くことができます.こんな風に見える
    <div class='drop'>
        <div id='drag' draggable='true' ondragstart='event.dataTransfer.setData('text/plain', null)'>
            Drag me!
        </div>
    </div>
    <div class='drop'></div>
    <div class='drop'></div>
    <div class='drop'></div>
    
    
    設定方法draggable 属性をtrueに設定します.すべてのドラッグ可能な要素を持っている必要がありますdraggable 属性を設定することができます.
    また、すべての要素はdraggable 属性が設定されます.我々は、その要素を聞くことによって、その要素がdragstart HTMLのイベント.そこに設定null 共有するデータがないので、データ型を設定していますtext/plain .
    また、いくつかの基本的なスタイルを追加することができます良い見て.
    #drag {
        width: 200px;
        height: 25px;
        border-radius: 3px;
        background: black;
        color: white;
        display: grid;
        align-items: center;
        justify-content: center;
    }
    
    
    要素がある限りdraggable 属性セットtrue ドロップターゲットにはdrop クラスは、以下のコードはどこでも

    最小限の実装
    我々のドラッグアンドドロップ機能のために、我々は3つの異なるイベントリスナーが必要です.他のすべてはボーナスです.
    まず、我々はドラッグしている要素を格納する必要があります.これを聞くことによってdragstart イベント.
    let dragged;
    
    document.addEventListener('dragstart', event => {
        dragged = event.target;
    }, false)
    
    
    要素がドラッグされるたびに、これはドラッグされた要素を変数に格納します.
    次に、ドロップイベントを聞くことができます.
    document.addEventListener('drop', event => {
        // Prevent default behaviour (sometimes opening a link)
        event.preventDefault();
    
        if (event.target.className === 'drop') {
            dragged.parentNode.removeChild(dragged);
            event.target.appendChild(dragged);
        }
    }, false)
    
    
    要素をドロップするたびに、要素がドロップターゲットである場合drop ドラッグターゲットをドロップターゲットに追加します.
    我々はほとんど終わっています、しかし、我々はこの仕事をするもう一つのことをする必要があります.
    デフォルトでは、ドラッグする要素は何もしないので、デフォルトの動作を防ぐためにevent.preventDefault ドロップターゲットをドラッグするたびに.
    これはonelinerで実現するのが簡単です.
    document.addEventListener('dragover', event => event.preventDefault(), false);
    
    
    それだ!16行で我々は機能ドラッグアンドドロップを持っている!
    アクションのビデオです


    機能追加
    このドラッグアンドドロップが動作しても、それは非常に良いです.それは非常に“自然”とは思えません.幸いにも、いくつかの行のコードでは、我々はこのドラッグアンドドロップも良いことができます!

    オリジナルのドラッグ要素のスタイリング
    要素をドラッグするたびに、要素の元のコピーはスタイルを変更しません.これらのドラッグされた要素に別のスタイルを追加することができれば、それは、それらがドラッグされていることを示すためにそれらを透明にするようになります.
    これは非常に簡単です.ちょっとスタイルを加えてくださいdragstart イベントリスナー.
    document.addEventListener('dragstart', event => {
        // ...
    
        event.target.style.opacity = 0.5;
        // add more styles as you like...
    
        // ...
    });
    
    
    しかし、我々はまた、ドラッグを終了するとスタイルをリセットする必要があります.我々は聞くことによってそれを行うことができますdragend :
    document.addeventListener('dragend', event => event.target.style.opacity = '', false)
    
    

    ドロップターゲットのスタイリング
    また、ドロップターゲットを聞くことによってdragenter イベント
    document.addEventListener('dragenter', event => {
        if (event.target.className === 'drop') event.target.style.background = '#2c41cc';
    }, false)
    
    
    もう一度、要素を離れるとスタイルをリセットする必要があります.我々は聞くことによってそれを行うことができますdragleave :
    document.addEventListener('dragleave', event => {
        if (event.target.className === 'drop') event.target.style.background = '';
    }, false)
    
    
    また、イベントをドロップするとスタイルをリセットする必要があります.我々は、編集することができますdrop これを達成するイベント.
    document.addEventListener('drop', event => {
        // ...
    
        if (event.target.className === 'drop') {
            event.target.style.background = '';
        //...
    })
    
    

    ドラッグしたコピーのスタイル
    少しのトリックで、我々はスタイルもドラッグしてコピーすることができます!多分、我々はそれを少しより自然にするために要素を少し回転させることができます.
    我々は、元のコピーをスタイリングし、すぐにこれらのスタイルを元に戻すことによってこれを行うことができますdragstart ユーザーがそれを見ないようにイベント.
    listen('dragstart', event => {
        // ...
    
        event.target.style.transform = 'rotate(-2deg)';
        setTimeout(() => event.target.style.transform = '', 1);
    })
    
    
    今ドラッグしたコピーは、我々がそれをドラッグしているときに回転するように表示されます!
    今、完全に機能ドラッグアンドドロップの実装を持っている!
    アクションのビデオです

    Here's a Gist with all the source code for reference

    結論
    我々は非常に一般的にライブラリに委任し、驚くほど小さなコードで自分自身を実装するタスクを取った.
    閉じるこの動画はお気に入りから削除されています.あなたは毎回ライブラリを必要としない.
    あなた自身のドラッグアンドドロップを実装しようとしたことがありますか?コメントの共有!