ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript ドラッグ アンド ドロップ エフェクトの実装コード_JavaScript スキル

JavaScript ドラッグ アンド ドロップ エフェクトの実装コード_JavaScript スキル

WBOY
WBOYオリジナル
2016-05-16 18:36:031134ブラウズ

ページにドラッグ アンド ドロップ機能を追加する理由はたくさんありますが、最も簡単な理由はデータを再編成することです。たとえば、ユーザーが一連のページ要素を再編成できるようにしたい場合は、各要素の隣に入力コンポーネントまたは選択コンポーネントを配置して、要素のグループをドラッグ アンド ドロップすることが 1 つの解決策です。代替案。あるいは、Web サイト上にユーザーが移動できるナビゲーション ウィンドウを設けたい場合もあります。これらはすべて、ドラッグ アンド ドロップを使用する簡単な理由です。
Web ページにドラッグ アンド ドロップ効果を実装するのはそれほど複雑ではありません。まず、マウスの位置を知り、次にユーザーがいつ要素をクリックしたかを知り、ドラッグを開始する準備ができていることを知り、最後に要素を移動する必要があります。

マウスの動きをキャプチャする
最初のステップでは、マウスの座標を取得する必要があります。この機能は、関数を渡して document.onmousemove に割り当てることで実現できます。
コード

コードをコピー コードは次のとおりです。
document.onmousemove = MouseMove ;
関数 MouseMove(ev) {
ev = ev window.event;
var MouseCoords(ev);
関数(ev.pageX || ev.pageY) {
return {x:ev.pageX, y:ev.pageY};
}
return {
x:ev.clientX document.body. scrollLeft - document.body.clientLeft,
y:ev.clientY document.body.scrollTop - document.body.clientTop
}
}


最初に説明する必要があります。イベントオブジェクト。移動したり、マウスをクリックしたり、キーを押したりするたびに、イベントが発生します。 IE では、このイベントはグローバルであり、window.event に保存されます。Firefox およびその他のブラウザーの場合、このイベントはこのページ アクションを指す関数に渡されます。したがって、document.onmousemove にマウス移動関数をポイントさせ、マウス移動関数がイベント オブジェクトを取得します。
上記のコードでは、ev にはすべてのブラウザ環境のイベント オブジェクトが含まれています。 Firefox では、「||window.event」にはすでにイベントが含まれているため、無視されます。 IE では、ev の値は空であるため、その値を window.event に設定する必要があります。
この記事では、マウスの座標を複数回キャプチャする必要があるため、event という 1 つのパラメーターを持つ MouseCoords メソッドを作成しました。
IE と他のブラウザーの違いについては、改めて説明します。 Firefox およびその他のブラウザは、event.pageX およびevent.pageY を使用して、ドキュメントに対する相対的なマウス位置を表します。 500*500 のウィンドウがあり、マウスがウィンドウの中央にある場合、pageX と pageY の値は両方とも 250 になります。ウィンドウを 500 ピクセル下にスクロールすると、pageY の値は 750 になります。
対照的に、Microsoft の IE は、event.clientX と events.clientY を使用して、現在のドキュメントではなく、ウィンドウを基準としたマウスの位置を表します。同じ例で、500x500 のウィンドウの中央にマウスを置くと、clientX と clientY の値は両方とも 250 になります。ページを下にスクロールすると、 clientY は現在のドキュメントではなくウィンドウを基準にして測定されるため、依然として 250 です。したがって、マウスの位置では、ドキュメントのドキュメント本文領域のscrollLeft属性とscrollTop属性を導入する必要があります。最後に、IE のドキュメントは実際には位置 (0,0) にありません。その周囲には小さな (通常は 2 ピクセル) 境界線があり、document.body.clientLeft と document.body.clientTop にはこの境界線の幅も含まれています。これらはマウスの位置に導入する必要があります。
幸いなことに、mouseCoords 関数を使用できるようになったので、マウスの位置の取得について心配する必要はなくなりました。

マウスのクリックをキャプチャ
次に、マウスがいつクリックされたのか、いつマウスが放されたのかを知る必要があります。この手順を省略すると、マウスがこれらの要素の上を移動するたびに、これらの要素がドラッグされることになり、面倒で直感に反します。
ここでは、onmousedown と onmouseup という 2 つの関数が役に立ちます。以前は document.onmousemove が関数を指すようにしていたため、document.onmousedown と document.onmouseup の両方が関数を指すのは論理的であると思われます。 document.onmousedown に関数を指定すると、テキスト、画像、表などの要素をマウスでクリックしたときにこの関数が実行されます。ページ上の特定の要素のみをドラッグ アンド ドロップできるようにしたいので、次のメソッドでこれを実現できます:

Code



コードをコピーします
コードは次のとおりです: document.onmouseup = MouseUp; varragObject = null;
function makeClickable(object) {
object.onmousedown = function () {
dragObject = this;
}
}
function MouseUp(ev) {
dragObject =
}


これで、クリックした要素を含む変数ドラッグオブジェクトができました。マウスを放すと、dragObject は空に設定されるため、dragObject が空でない場合は、ドラッグ操作を実行する必要があります。

要素の移動
マウスの動きとクリックをキャプチャする方法がわかりました。次に行う必要があるのは、ドラッグする要素を移動することです。まず、要素をページ上の希望の場所に正確に移動するには、要素のスタイル シートの位置の値が絶対値である必要があります。つまり、要素の style.top または style.left を、要素を基準とした相対的な測定値で設定できます。通常、マウスの動きはすべてページの左上隅を基準とするためです。
item.style.position='absolute' を設定したら、要素を移動させるために要素の上端と左端の位置を変更する必要があります。

コード
コードをコピー コードは次のとおりです:

ドキュメント。 onmousemove = マウス移動 ;
document.onmouseup = マウスアップ;
var マウスオフセット = null ;
関数 getMouseOffset(target, ev) {
ev = ev ウィンドウ。イベント;
var docPos = getPosition(target);
var MousePos = MouseCoords(ev);
return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
}
function getPosition(e) {
var left = 0;
var top = 0;
while (e.offsetParent) {
left = e.offsetLeft; >top = e.offsetTop;
e = e.offsetLeft;
top = e.offsetTop;
関数
ev = ev window.event;
if (dragObject) {
dragObject .style.position = 'absolute';
dragObject.style.top = MousePos.y - MouseOffset.y;
dragObject.style.left = MousePos.x - MouseOffset.x; 🎜>}
}
function MouseUp() {
dragObject = null ;
}
function makeDraggable(item) {
if (!item) return ; onmousedown = function (ev) {
dragObject = this ;
mouseOffset(this, ev)
return false ;


これらのコードは前の例に基づいていることがわかります (前の記事を参照)。これらを組み合わせると、要素を自由に移動できるようになります。
要素をクリックすると、別の変数、mouseOffset が保存されます。 MouseOffset には、クリックした要素の位置情報が含まれているだけです。 20*20 ピクセルの画像があり、画像の中央をクリックすると、mouseOffset は {x:10, y:10} になるはずです。画像の左上隅をクリックすると、mouseOffset は {x:0, y:0} になるはずです。マウスを動かした後の位置情報に利用します。この値を保存しない場合、要素のどこをクリックしても、マウスに対する要素の相対的な位置は同じになります。
mouseOffset 関数は別の関数 getPosition を使用します。 getPosition の目的は、documentt ドキュメントを基準とした要素の座標位置を返すことです。単純に item.offsetLeft または item.style.left を読み取る場合、取得されるのは、ドキュメント document ではなく、その親要素に対する相対的な要素の位置です。このスクリプトでは、すべての要素がドキュメントに関連しているため、これが必要です。
ドキュメントに対する相対的な要素の位置を取得する作業を完了するために、getPosition はその親から開始し、ループしてその左と上の値を取得し、それらを蓄積して、要素間の距離を取得します。要素と左側に累積値。
この情報を取得してマウスを動かすと、mouseMove が実行を開始します。まず、 item.style.position 値が絶対値であることを確認する必要があります。次に、要素を任意の場所に移動すると、以前に記録した要素に対するマウスのオフセットからマウスの位置が減算されます。マウスを放すと、dragObject は null に設定され、mouseMove 関数は何も実行しなくなります。

要素の配置
前の例では、要素をドラッグ アンド ドロップするだけでこれにすでに対処しています。次に、要素をドロップするときは通常、他の目的があります。例として要素をゴミ箱にドラッグしたり、要素をページ上の特定の領域に位置合わせしたい場合があります。
残念ながら、ここで比較的大きな問題に遭遇します。移動している要素は常にマウスの真下にあるため、ページ上の他の要素に対してマウスオーバー、マウスダウン、マウスアップ、またはマウス操作を行うことはできません。要素をゴミ箱に移動すると、マウスは常にゴミ箱ではなく、移動した要素の上にあります。
それでは、この問題にどう対処すればよいでしょうか?ここにはいくつかの解決策があります。前述の MouseOffset の目的は、要素が常にマウスの下の正しい位置にあるようにすることです。これを無視して要素を常にマウスの右下に配置すると、要素によってマウスがドラッグされなくなります。隠されているので、問題は発生しません。しかし実際には、多くの場合、見た目を美しくするために、要素をマウスの下に置いておきます。
もう 1 つのオプションは、ドラッグしている要素を移動しないことです。マウスのスタイルを変更して、要素をどこかにドロップするまでドラッグしていることをユーザーに伝えることができます。これで問題は解決しましたが、以前の解決策と同じ、美観の問題が生じました。
私たちの最終的な解決策は、移動中の要素にも、移動の終了時の要素 (ゴミ箱など) にも影響しません。残念ながら、これは前の 2 つの解決策よりも困難です。これから行うことは、配置するターゲットのセットを取得することです。マウスを放したときに、各ターゲットに対する現在のマウスの位置を手動でチェックして、いずれかの位置でマウスが放されたかどうかを確認します。そうであれば、要素をターゲットに配置したことがわかります。

コード
コードをコピー コードは次のとおりです:

/*
前の例のすべてのコードが必要ですが、例外として、mouseUp 関数の
*/
vardropTargets = [];
function addDropTarget(dropTarget) {
dropTargets.push(dropTarget);
関数 MouseUp(ev) {
var MouseCoords(ev); i = 0 var targPos = getPosition(curTarget); 🎜>var targHeight = parseInt(curTarget.offsetHeight);
if (
(mousePos.x > targPos.x) &&
(mousePos. < (targPos.x targWidth)) &&
(mousePos. y > targPos.y) &&
(mousePos.y < (targPos.y targHeight))) {
//ragObject が curTarget にドロップされました! >dragObject = null
}



この例では、マウスが放されると、要素が配置される各ターゲットをループします。マウス ポインターがターゲット上にある場合、マウスの横座標が要素を配置するイベントが発生します。対象要素の左側の横座標(mousePos.x>targPos.x)が、対象要素の右側の横座標(mousePos.x
すべての関数を統合する
最後に、すべてのコード スニペットを使用して、完全なドラッグ アンド ドロップ関数スクリプトを作成します。最初に行う必要があるのは DOM 操作です。これにあまり詳しくない場合は、「JavaScript Primer on DOM Manipulation」を参照してください。
次のコードは、各要素をこれらのコンテナ内にドラッグできるようにコンテナとコンテナ グループを作成します。これは、この記事の 2 番目のデモに基づいて行われます。このコードを使用すると、要素の順序を並べ替えたり、ナビゲーション ウィンドウをページの左側または右側に移動したり、その他の考えられる機能を追加したりできます。
疑似コードを使用して段階的に説明しますが、実際のコードは読者がコメントを通じて確認できるようにしておきます。
1. ドキュメントが初めてロードされるとき、dragHelper という名前の DIV タグを作成します。要素の移動を開始すると、dragHelper は非表示の要素になり、移動できるようになります。実際の要素はドラッグされず、insertBefore と appendChild を使用して移動されるだけです。最初にdragHelperを非表示にします。
2. マウスダウン関数とマウスアップ関数を作成します。当初、これらの関数はすべて、マウス ボタンの状態が記録されることを前提としているため、iMouseDown 変数は、マウスが押されている場合は true、押されていない場合は false になります。
3. グローバル変数 DragDrops と関数 CreateDragContainer を作成します。 DragDrops には、関連するコンテナのセットが含まれています。 CreateDragContainer に渡された変数 (コンテナーを表す) はすべて新しいコレクションに編成され、要素がこれらのコンテナー間を自由に移動できるようになります。また、CreateDragContainer 関数は、setAttribute を通じて各コンテナ内の要素をバインドします。
4. コードで各要素が配置されているコレクションがわかったので、mouseMove 関数を見てみましょう。 MouseMove 関数は、まず、マウスの下のターゲット要素を表す変数 target を設定します。この要素がコレクション内にある場合は (getAttribute によって判断)、次の操作を続行します。 script ターゲット要素のクラス属性を変更するには、反転効果を作成します。
4.2. 次に、イベントが発生した場合に、マウスがクリックされたかどうかを確認します (コードが既に実行されているため):
4.2.1. 変数 curTarget を現在の要素に設定します。
4.2.2. 必要なときに値を取得できるように、ドキュメント内の要素の現在位置を記録します。
4.2.3. 現在の要素をドラッグヘルパーに複製し、要素の非表示のバックアップを移動できるようにします。
4.2.4.ragHelper にはドラッグされた要素の完全なバックアップがあるため、この要素は常にマウスの下にあるため、dragObj がコレクションに存在しないことをコードに知らせるために、dragObj 属性を削除する必要があります。
4.2.5. コレクション内の各要素の現在の位置、幅、高さをすぐに記録します。これを行う必要があるのは、要素が最初にドラッグされ始めるときに 1 回だけです。それ以外の場合は、マウスが移動するたびに、場合によっては 1 秒間に数百回も行う必要があります。
4.3. マウスがクリックされていない場合は、以前と同じターゲット要素があるか、またはターゲット要素が存在しないかのどちらかです。
5. 次に、curTarget 変数を確認します。 curTarget にはドラッグされたオブジェクトのみが含まれている必要があるため、存在する場合は要素をドラッグしていることになります:
5.1. 非表示の DIV をマウスに移動します。この要素は、この記事で前に作成した要素と同様にドラッグできます。
5.2. 次に、現在のコレクション内の各コンテナにマウスが存在するかどうかを確認します。
5.2.1. マウスがコンテナ内にある場合は、コンテナ内の各要素をチェックして、ドラッグしている要素がどこに属しているかを確認します。
5.2.2. 次に、ドラッグした要素をコンテナ内の別の要素の前、またはコンテナの最後の位置に配置します。
5.2.3. 最後に、要素が表示されていることを確認します。
6. 残っているのは、mouseUp イベントをキャプチャすることだけです:
6.1. まず、dragHelper を非表示にする必要があります。何もドラッグしていないため、これは必要ありません。
6.2. ドラッグされた要素が表示されている場合、それが属するコンテナーにすでに存在しており、すべての作業が完了しています。
6.3. ドラッグされた要素が表示されない場合は、元の場所に戻します。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。