1. はじめにドラッグ アンド ドロップによる並べ替えは、誰にとっても馴染みのある操作です。通常の作業では、ニーズに合わせて 2. 実装{ マージン: 0; パディング: 0; ボックスのサイズ: 境界線ボックス; } .グリッド{ ディスプレイ: フレックス; flex-wrap: ラップ; マージン: 0 -15px -15px 0; タッチアクション: なし; ユーザー選択: なし; } .グリッドアイテム{ 幅: 90ピクセル; 高さ: 90px; 行の高さ: 88px; テキスト配置: 中央; マージン: 0 15px 15px 0; 背景: #FFF; 境界線: 1px 実線 #d6d6d6; リストスタイル: なし; } 。アクティブ { 背景: #c8ebfb; } .clone-grid-item { 位置: 固定; 左: 0; 上: 0; zインデックス: 1; 幅: 90ピクセル; 高さ: 90px; 行の高さ: 88px; テキスト配置: 中央; 背景: #FFF; 境界線: 1px 実線 #d6d6d6; 不透明度: 0.8; リストスタイル: なし; } <ul class="grid"> <li class="grid-item">項目1</li> <li class="grid-item">項目2</li> <li class="grid-item">項目3</li> <li class="grid-item">項目4</li> <li class="grid-item">項目5</li> <li class="grid-item">項目6</li> <li class="grid-item">項目7</li> <li class="grid-item">項目8</li> <li class="grid-item">項目9</li> <li class="grid-item">アイテム10</li> </ul> ES6 クラスの記述を使用する: クラス Draggable { コンストラクタ(オプション) { this.parent = options.element; // 親要素 this.cloneElementClassName = options.cloneElementClassName; // 複製要素のクラス名 this.isPointerdown = false; this.diff = { x: 0, y: 0 }; // 最後の移動に対する差異 this.drag = { element: null, index: 0, lastIndex: 0 }; // 要素をドラッグ this.drop = { element: null, index: 0, lastIndex: 0 }; // 要素を解放 this.clone = { element: null, x: 0, y: 0 }; this.lastPointermove = { x: 0, y: 0 }; this.rectList = []; // ドラッグアイテムのgetBoundingClientRect()メソッドによって取得されたデータを保存するために使用されます。this.init(); } 初期化() { this.getRect(); このイベントリスナーをバインドします。 } // 要素の位置情報を取得する getRect() { this.rectList.length = 0; for (this.parent.children の定数項目) { this.rectList.push(item.getBoundingClientRect()); } } ハンドルポインタダウン(e) { // マウスクリックの場合は左ボタンにのみ反応します if (e.pointerType === 'mouse' && e.button !== 0) { 戻る; } if (e.target === this.parent) { 戻る; } this.isPointerdown = true; this.parent.setPointerCapture(e.pointerId); this.lastPointermove.x = e.clientX; this.lastPointermove.y = e.clientY; this.drag.element = e.target; this.drag.element.classList.add('active'); this.clone.element = this.drag.element.cloneNode(true); this.clone.element.className = this.cloneElementClassName; this.clone.element.style.transition = 'なし'; const i = [].indexOf.call(this.parent.children, this.drag.element); this.clone.x = this.rectList[i].left; this.clone.y = this.rectList[i].top; this.drag.index = i; this.drag.lastIndex = i; this.clone.element.style.transform = 'translate3d(' + this.clone.x + 'px, ' + this.clone.y + 'px, 0)'; document.body.appendChild(this.clone.element); } ハンドルポインタ移動(e) { if (this.isPointerdown) { this.diff.x = e.clientX - this.lastPointermove.x; this.diff.y = e.clientY - this.lastPointermove.y; this.lastPointermove.x = e.clientX; this.lastPointermove.y = e.clientY; this.clone.x += this.diff.x; this.clone.y += this.diff.y; this.clone.element.style.transform = 'translate3d(' + this.clone.x + 'px, ' + this.clone.y + 'px, 0)'; (i = 0 とします; i < this.rectList.length; i++) { // 衝突検出 if (e.clientX > this.rectList[i].left && e.clientX < this.rectList[i].right && e.clientY > this.rectList[i].top && e.clientY < this.rectList[i].bottom) { this.drop.element = this.parent.children[i]; this.drop.lastIndex = i; if (this.drag.element !== this.drop.element) { if (this.drag.index < i) { this.parent.insertBefore(this.drag.element、this.drop.element.nextElementSibling); this.drop.index = i - 1; } それ以外 { this.parent.insertBefore(this.drag.element、this.drop.element); this.drop.index = i + 1; } this.drag.index = i; 定数dragRect = this.rectList[this.drag.index]; 定数 lastDragRect = this.rectList[this.drag.lastIndex]; 定数 dropRect = this.rectList[this.drop.index]; 定数 lastDropRect = this.rectList[this.drop.lastIndex]; this.drag.lastIndex = i; this.drag.element.style.transition = 'なし'; this.drop.element.style.transition = 'なし'; this.drag.element.style.transform = 'translate3d(' + (lastDragRect.left - dragRect.left) + 'px, ' + (lastDragRect.top - dragRect.top) + 'px, 0)'; this.drop.element.style.transform = 'translate3d(' + (lastDropRect.left - dropRect.left) + 'px, ' + (lastDropRect.top - dropRect.top) + 'px, 0)'; this.drag.element.offsetLeft; // 再描画をトリガーします this.drag.element.style.transition = 'transform 150ms'; this.drop.element.style.transition = '150ms で変換'; this.drag.element.style.transform = 'translate3d(0px, 0px, 0px)'; this.drop.element.style.transform = 'translate3d(0px, 0px, 0px)'; } 壊す; } } } } ハンドルポインタアップ(e) { if (this.isPointerdown) { this.isPointerdown = false; this.drag.element.classList.remove('active'); this.clone.element.remove(); } } ハンドルポインタキャンセル(e) { if (this.isPointerdown) { this.isPointerdown = false; this.drag.element.classList.remove('active'); this.clone.element.remove(); } } バインドイベントリスナー() { this.handlePointerdown = this.handlePointerdown.bind(this); this.handlePointermove = this.handlePointermove.bind(this); this.handlePointerup = this.handlePointerup.bind(this); this.handlePointercancel = this.handlePointercancel.bind(this); this.getRect = this.getRect.bind(this); this.parent.addEventListener('pointerdown', this.handlePointerdown); this.parent.addEventListener('pointermove', this.handlePointermove); this.parent.addEventListener('pointerup', this.handlePointerup); this.parent.addEventListener('pointercancel', this.handlePointercancel); window.addEventListener('スクロール'、this.getRect); window.addEventListener('resize', this.getRect); window.addEventListener('orientationchange', this.getRect); } アンバインドイベントリスナー() { this.parent.removeEventListener('pointerdown', this.handlePointerdown); this.parent.removeEventListener('pointermove', this.handlePointermove); this.parent.removeEventListener('pointerup', this.handlePointerup); this.parent.removeEventListener('pointercancel', this.handlePointercancel); window.removeEventListener('scroll', this.getRect); ウィンドウのサイズ変更イベント リスナーを削除します。 window.removeEventListener('orientationchange', this.getRect); } } // 新しい Draggable をインスタンス化します({ 要素: document.querySelector('.grid'), cloneElementClassName: 'clone-grid-item' }); デモ: jsdemo.codeman.top/html/dragga… 3. HTML ドラッグ アンド ドロップ API を使用しないのはなぜですか?ネイティブ 4. まとめドラッグアンドドロップによる並べ替えの基本機能は実装されていますが、まだ欠点が多くあります。ネストされたドラッグ、リスト間でのドラッグ、一番下までドラッグしたときの自動スクロールなどの機能は実装されていません。 ドラッグアンドドロップソートをjsで実装する詳細に関するこの記事はこれで終わりです。ドラッグアンドドロップソートをjsで実装することに関するより関連性の高いコンテンツについては、123WORDPRESS.COMで以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。 以下もご興味があるかもしれません:
|
外国のウェブサイトを開くと文字化けした文字が表示されることが多く、また、英語以外の外国のウェブサイト...
Docker を実行するには root 権限が必要です。非 root ユーザーに docker コマ...
1. インストール1. MySQLをダウンロードするダウンロードアドレス: リンクアドレスブラウザで...
目次1. データベース設計2. フロントエンドページ3. 完全なデモフロントエンド開発では、カスケー...
序文開発プロセスにおいて、変数の定義は非常に頻繁かつ基本的なタスクです。変数の使用シナリオと範囲に応...
Nginx は現在、最も人気のあるロード バランサーの 1 つです。インターネット トラフィックの...
1. iframe の定義と使用法iframe 要素は、別のドキュメントを含むインライン フレーム...
これは、W3C 組織が HTML4 に対して提示したスタイル推奨事項です。残念ながら、ブラウザが独自...
名前タグの名前を指定します。形式 <input type="text" n...
導入Kubernetes を使い始めるのに丸一日を費やしたことはありませんか?最近登場したいくつかの...
1. 実験環境シリアルナンバープロジェクトソフトウェアとバージョン1オペレーティング·システムCen...
この記事では、JavaScript Canvasで三目並べゲームを実装するための具体的なコードを参考...
MySQL の mysql 5.7.18 zip バージョンは、クリックして次のステップをクリックし...
目次ジェネリック型での条件型の使用ツールタイプ脱出ポッド矢印関数で条件型を使用する型推論による条件型...
プロジェクトシナリオ: Dark Horse Vueプロジェクト管理の実践、製品分類の取得、拡張バー...