HTML5および複数のオブジェクトのドラッグアンドドロップ

オブジェクトをHTML5にドラッグアンドドロップしても驚くことはありませんが、興味深いこと、つまり、HTML5のみを使用して複数のオブジェクトを美しくドラッグアンドドロップする方法についてお話しします。

ページには、タイプAの要素のセットがあり、1つまたはグループをタイプBの要素にドラッグできます。ユーザーは、1つまたは複数の要素をドラッグするかどうかを確認する必要があります。 1つの要素をドラッグするのは簡単です。単にdraggableプロパティをtrue設定するだけです。

ページを1つずつドラッグする準備ができています。 itemクラスの要素をdropzoneして、 dropzoneクラスの要素に転送できます(ボックスをクリックしてdropzoneます)。

Uいドラッグ&ドロップデモ

選択するには、要素をクリックする必要があり、選択した要素のみをドラッグアンドドロップできます。一度に複数の要素をドラッグアンドドロップできます。



ページ構造:

 <div class="items-container"> <div class="items"> <div class="item"><span>a</span></div> <div class="item"><span>b</span></div> <div class="item"><span>c</span></div> <div class="item"><span>d</span></div> <div class="item"><span>e</span></div> <div class="item"><span>f</span></div> <div class="item"><span>g</span></div> </div> </div> <div class="dropzone-container"> <div class="dropzone"></div> </div> 

コード:

 // jQuery     "" , ,     HTML5 //    jQuery,      dataTransfer. jQuery.event.props.push('dataTransfer'); //   . jQuery.event.props.push('pageX'); jQuery.event.props.push('pageY'); //   . $('.item') //   / ,   draggable. .on('click', function(e) { e.preventDefault(); $(this).toggleClass('selected'); this.draggable = $(this).hasClass('selected'); }) //      , .on('dragstart', function(e) { var html = '', //    , $selectedItems = $('.items .selected'); //  HTML  . $selectedItems.each(function() { html += this.outerHTML; }); //   HTML     . //       . e.dataTransfer.setData('text/html', html); return true; }) .on('dragend', function(e) { resetUI(); }); //  $('.dropzone') //     dragover .on('dragenter', function(e) { $(this).addClass('dragover'); }) //   dragover .on('dragleave', function(e) { $(this).removeClass('dragover'); }) .on('dragover', function(e) { //      drop,       dragover if (e.preventDefault) e.preventDefault(); return false; }) //  drop .on('drop', function(e) { //  HTML   var html = e.dataTransfer.getData('text/html'); //  HTML   $(this).append(html); resetUI(); return true; }); function resetUI() { $('.selected').removeClass('selected').attr('draggable', false); $('.dragover').removeClass('dragover'); } 

複数の要素を選択してドラッグしようとすると、このアクション中に視覚的にドラッグされるのは1つだけであることに気付きました。 今それを修正します!

従来の方法では、これは単純に行われます-マウスイベントをサブスクライブし、マウスの後ろに要素のグループをドラッグします。 HTML5の登場により、アニメーションの注意をブラウザの肩に移すことで、このルーチンの一部をなくすことができます。 1つの要素の場合と同じように機能します。

「正しい画像」を取得するためにいくつかの要素をドラッグするときにsetDragImageオブジェクトのsetDragImageメソッドを使用するには。

function setDragImage(image, x, y)
image-ドラッグ時に画像が使用される要素。
xyはオフセットです。

したがって、ドラッグを開始する前に、 e.dataTransfer.setData('text/html', html)をドラッグアンドドロップするためのデータを設定した後、 setDragImageメソッドに渡すための正しい画像要素を収集する必要があります。 まず、これに必要な変数を定義します。

 // ,   . var $draggedItem = $(e.currentTarget), draggedItemOffset = $draggedItem.offset(), // ,     . frame = getFrame($selectedItems), //  ,    . dx = e.pageX - draggedItemOffset.left + (draggedItemOffset.left - frame.lx), dy = e.pageY - draggedItemOffset.top + (draggedItemOffset.top - frame.ly), // ,     image  setDragImage. $image = $(document.createElement('div')); 

frameを使用して、必要なサイズと画像要素の座標を設定します。
 $image.css({ position: 'absolute', //   ,     dragstart. zIndex: -1, left: frame.lx, top: frame.ly, width: Math.abs(frame.lx - frame.rx), height: Math.abs(frame.ly - frame.ry) }); 

選択した要素のコピーを$image追加し$image
 $selectedItems.each(function(i, item) { var $item = $(item), $clone = $item.clone(), itemOffset = $item.offset(); //    $image. $clone.css({ position: 'absolute', left: itemOffset.left - frame.lx, top: itemOffset.top - frame.ly }); $image.append($clone); }); 

最終和音:
 //  $image  . $('body').append($image); //  $image     . e.dataTransfer.setDragImage($image.get(0), dx, dy); //  $image  1 .   , //   setDragImage      $image. window.setTimeout(function() { $image.remove(); }, 1); 

getFrameメソッドを使用して、選択した要素が収まる長方形を見つけます。
 function getFrame($items) { var offset = $items.first().offset(), frame = { lx: offset.left, ly: offset.top, rx: offset.left, ry: offset.top }; $items.each(function() { var $this = $(this), offset = $this.offset(), width = $this.width(), height = $this.height(); if (offset.left < frame.lx) frame.lx = offset.left; if (offset.top < frame.ly) frame.ly = offset.top; if (offset.left + width > frame.rx) frame.rx = offset.left + width; if (offset.top + height > frame.ry) frame.ry = offset.top + height; }); return frame; } 

美しいドラッグアンドドロップデモ
GitHubサンプルコード

Source: https://habr.com/ru/post/J187590/


All Articles