メインコンテンツへ移動

HTML5 ドラッグ&ドロップ(Drag & Drop)

無料2015-07-02#HTML#H5拖放#文件拖放上传#Drag API

ネイティブ JS でドラッグ&ドロップを実装するには、イベントを独自にカプセル化し互換性処理を行う必要があり、機能が弱くパフォーマンス問題も存在します。h5 仕様がサポートするドラッグ&ドロップ機能は強力で(ファイルドラッグ&ドロップをサポート)、使用方便です

一. 属性の設定

draggable="true"

href 属性を持つ a タグと img タグはデフォルトでドラッグ&ドロップ可能ですが、他のタグはこの属性を設定する必要があります

二. イベント

  • drag : 要素がドラッグされている時にドラッグ要素によって頻繁にトリガーされるイベント(数百ミリ秒ごとにトリガーされます)

  • dragstart : ドラッグ開始時にドラッグ要素によってトリガーされるイベント

  • dragend : ドラッグ終了時にドラッグ要素によってトリガーされるイベント

  • dragover : ドラッグ要素がドロップエリアに入った時にドロップ要素によって頻繁にトリガーされるイベント(数百ミリ秒ごとにトリガーされます)

  • dragenter : ドラッグ要素がドロップエリアに入った時にドロップ要素によってトリガーされるイベント

  • dragleave : ドラッグ要素がドロップエリアを離れた時にドロップ要素によってトリガーされるイベント

  • drop : ドラッグ要素がドロップエリアにドロップされた時にドロップ要素によってトリガーされるイベント

注意:drag と dragover は継続的にトリガーされます

ファイルをブラウザにドラッグ&ドロップする際、dragover と drop イベントハンドラで preventDefault する必要があります。他のソフトウェアやファイルから何かをドラッグして持ち込む場合、特に画像のときは、デフォルトの動作がブラウザを現在のページからドラッグ要素が指すリソースにリダイレクトするためです。実際にテストした結果、2 つのイベントハンドラ両方でデフォルト動作を阻止する必要があります

注意:dragstart イベントトリガー後、他の要素の mousemove、mouseover、mouseenter、mouseleave、mouseout イベントはトリガーされなくなります

イベントトリガー順序:

dragstart -> drag -> dragenter -> dragover -> dragleave -> drop -> dragend

イベントオブジェクト:

DragEvent、[object MouseEvent] オブジェクトから継承されており、実際には {DataTransfer} dataTransfer 属性が追加されただけです

イベントオブジェクトの重要な属性:

effectAllowed と dropEffect の主な役割は、ドラッグ操作中のマウスポインタのタイプを設定してユーザーに後続で実行可能な操作を提示することです。二次的な役割は、drop イベントのトリガー有無を制御することです。禁止のポインタスタイルが表示されている場合、ターゲット要素の drop イベントはトリガーされません。

注意:effectAllowed は dragstart でのみ設定可能で、dropEffect は dragover でのみ設定可能です

詳細情報は HTML5 魔法堂:Drag & Drop API の完全理解 を参照してください

三. 互換性

findmebyip によると drag は全ブラウザ互換とのことですが、実際には IE は最も早く drag を実装しましたが、[IE10-] のサポート度は非常に低く、無視できます(選択されたテキストに対してのみ有効で、img 要素、a[href] 要素、input[type=text]/textarea 要素のみで、draggable="true" の設定は不要ですが、ファイルドラッグ&ドロップはサポートしていません)。

四. データ転送

データ転送には event.dataTransfer オブジェクトを使用し、このオブジェクトは setData(type, data); と getData(type); メソッドを提供してデータの保存と取得を行います。

そして dragstart イベントハンドラでsetData('text/plain', data)(IE10 は text/plain のみサポート)、drop イベントハンドラで getData('text') します

注意:タイプが存在しない場合は data リストの末尾に追加され、既に存在する場合は既存の内容を置き換えます。したがって、IE10 を考慮しない場合、setData(key, value); と同等です

五. ファイルドラッグ&ドロップ

dropArea.ondragover = function(e) {
    e.preventDefault();
}
dropArea.ondrop = function(e) {
    e.preventDefault();
    
    var files = e.dataTransfer.files;
    if (files && files.length > 0) {
        // ファイル情報を出力
        var str = '';
        for(var i = 0; i < files.length; i++) {
            var file = files[i];

            // 画像のオンラインプレビューも、まず画像をサーバーにアップロードする必要があります。クライアントファイルの URL を取得できないためです

            // ファイルをアップロードするには file オブジェクトを xhr で送信するだけです
            // var formData = new FormData();
            // formData.append('myfile', file);
            // xhr.send(formData);
            console.log(file);
        }

        console.log('receive a file');
    }
}

ファイルドラッグ&ドロップアップロードでは注意すべき点が多く、次のブログ記事でいくつかの一般的な実装方法を詳しく紹介します

参考資料

コメント

コメントはまだありません

コメントを書く