これで、クリックした要素を含む変数ドラッグオブジェクトができました。マウスを放すと、dragObject は空に設定されるため、dragObject が空でない場合は、ドラッグ操作を実行する必要があります。
マウスの動きとクリックをキャプチャする方法がわかりました。次に行う必要があるのは、ドラッグする要素を移動することです。まず、要素をページ上の希望の場所に正確に移動するには、要素のスタイル シートの位置の値が絶対値である必要があります。つまり、要素の style.top または style.left を、要素を基準とした相対的な測定値で設定できます。通常、マウスの動きはすべてページの左上隅を基準とするためです。
ドキュメント。 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. ドラッグされた要素が表示されない場合は、元の場所に戻します。