序文ソースコードは合計で 100 行強しかありません。これを読めば、react-dnd などの成熟した react ドラッグ ライブラリの実装アイデアを大まかに理解でき、これらのライブラリをすぐに使い始めることができます。 フックを使用した場合の一般的な効果は次のとおりです。 私たちの目標は、useDrag フックと useDrop フックを実装することです。これにより、要素を簡単にドラッグ可能にすることができ、以下に示すように、ドラッグの各ライフサイクルでメッセージの配信をカスタマイズできます (ちなみに、ドラッグによってトリガーされるいくつかのイベントを導入します)。
使い方+ソースコード解説 クラスHelloはReact.Component<any, any>を拡張します。 コンストラクタ(props: any) { スーパー(小道具) this.state = {} } 与える() { 戻る ( <ドラッグアンドドロップ> <ドラッグ要素 /> <ドロップ要素 /> </ドラッグアンドドロップ> ) } } ReactDOM.render(<Hello />, window.document.getElementById("root")) 前述の通り、DragAndDrop コンポーネントの機能は、現在ドラッグされている要素がどの DOM であるかなどのメッセージを、useDrag と useDrop を使用するすべてのコンポーネントに渡すことですが、必要に応じて他の情報を追加することもできます。その実装を見てみましょう。 DragAndDropManager を React.createContext に追加します。 const DragAndDrop = ({ children }) => ( <DragAndDropContext.Provider 値 = {{ DragAndDropManager: new DragAndDropManager() }}> {子供たち} </ドラッグアンドドロップコンテキスト.プロバイダー> ) メッセージパッシングは react の Context API を使用して実装されていることがわかります。この DragAndDropManager に注目してください。実装を見てみましょう。 デフォルトクラスDragAndDropManagerをエクスポートします。 コンストラクタ() { this.active = null this.subscriptions = [] this.id = -1 } setActive(アクティブプロパティ) { this.active = アクティブプロパティ this.subscriptions.forEach((サブスクリプション) => subscription.callback()) } subscribe(コールバック) { this.id += 1 this.subscriptions.push({ 折り返し電話、 id: this.id, }) this.idを返す } 登録解除(id) { this.subscriptions = this.subscriptions.filter((sub) => sub.id !== id) } } setActive の機能は、現在ドラッグされている要素を記録することです。これは useDrag で使用されます。useDrag のフックの実装を見ると、setActive メソッドを呼び出してドラッグされた DOM 要素を渡すだけで、現在ドラッグされている要素がわかることがわかります。 さらに、イベントをサブスクライブするための API subscribe も追加しました。まだ使用していないため、この例では無視してかまいません。サブスクリプション イベントを追加できることだけ知っておいてください。 次に、useDrag の使い方を見てみましょう。DragElement の実装は次のとおりです。 関数DragElement() { 定数入力 = useRef(null) const hanleDrag = useDrag({ 参照: 入力、 collection: {}, // ここでドロップ要素に渡したいメッセージを入力できます。このメッセージは後でドロップ要素にパラメータとして渡されます}) 戻る ( <div ref={入力}> <h1 role="button" onClick={handleDrag}> ドラッグ要素 </div> ) } 非常にシンプルなuseDragの実装を見てみましょう。 デフォルト関数 useDrag(props) をエクスポートします。 const { DragAndDropManager } = useContext(DragAndDropContext) 定数handleDragStart = (e) => { DragAndDropManager.setActive(props.collection) e.dataTransfer !== 未定義の場合 { e.dataTransfer.effectAllowed = "移動" e.dataTransfer.dropEffect = "移動" e.dataTransfer.setData("text/plain", "drag") // Firefox の修正 } (props.onDragStart)の場合{ props.onDragStart(DragAndDropManager.active) } } 使用効果(() => { もしprops.refがそうであれば、戻り値は()=>{} 定数{ 参照: { 現在の }, } = 小道具 if (現在) { current.setAttribute("ドラッグ可能", true) current.addEventListener("dragstart", handleDragStart) } 戻り値 () => { current.removeEventListener("dragstart", handleDragStart) } }, [props.ref.current]) handleDragStart を返す } useDrag が行うことは非常にシンプルです。
このうち、useDrop の使用と DropElement の実装は次のとおりです。 関数 DropElement(props: any): any { 定数入力 = useRef(null) ドロップを使用します({ 参照: 入力、 // e は、dragOver イベントが発生したときにドラッグされている要素のイベント オブジェクトを表します // collection はストアに保存されているデータです // showAfter は、マウスが要素をドラッグしているときに、ドロップされた要素の上をマウスが通過するかどうかを示します (上は上半分、下は下半分) onDragOver: (e, コレクション, showAfter) => { // 上半分を通過すると、ドロップ要素の上部の境界線が赤くなります if (!showAfter) { input.current.style = "border-bottom: none;border-top: 1px の赤一色" } それ以外 { // 下半分を通過すると、ドロップ要素の上部の境界線は赤になります input.current.style = "border-top: none; border-bottom: 1px solid red" } }, // ドロップ要素上でマウスを離すと、スタイルがクリアされます onDrop: () => { 入力.現在のスタイル = "" }, // ドロップ要素を離れるとスタイルはクリアされます onDragLeave: () => { 入力.現在のスタイル = "" }, }) 戻る ( <div> <h1 ref={input}>要素をドロップ</h1> </div> ) } 最後に、useDropの実装を見てみましょう。 デフォルト関数 useDrop(props) をエクスポートします。 // 最も外側のストアのデータを取得します。const { DragAndDropManager } = useContext(DragAndDropContext) 定数handleDragOver = (e) => { // e はドラッグ イベント オブジェクトです e.preventDefault() // 下の getBoundingClientRect の図を参照してください const overElementHeight = e.currentTarget.getBoundingClientRect().height / 2 定数 overElementTopOffset = e.currentTarget.getBoundingClientRect().top // clientYはマウスからブラウザページの表示領域の上部までの距離です。const mousePositionY = e.clientY // mousePositionY - overElementTopOffset は、要素内のマウスから要素の border-top までの距離です。const showAfter = mousePositionY - overElementTopOffset > overElementHeight (props.onDragOver)の場合{ props.onDragOver(e, DragAndDropManager.active, showAfter) } } // ドロップイベント const handledDop = (e: React.DragEvent) => { e.preventDefault() (props.onDrop)の場合{ props.onDrop(DragAndDropManager.active) } } // dragLeave イベント const handlerragLeave = (e: React.DragEvent) => { e.preventDefault() (props.onDragLeave)の場合{ props.onDragLeave(DragAndDropManager.active) } } // イベントを登録します。メモリリークを避けるために、コンポーネントを破棄するときにはイベントの登録を解除する必要があることに注意してください。useEffect(() => { もしprops.refがそうであれば、戻り値は()=>{} 定数{ 参照: { 現在の }, } = 小道具 if (現在) { current.addEventListener("dragover", handleDragOver) current.addEventListener("ドロップ"、handledDop) current.addEventListener("dragleave", 処理済みragLeave) } 戻り値 () => { current.removeEventListener("dragover", handleDragOver) current.removeEventListener("drop", 処理されたDop) current.removeEventListener("dragleave", 処理済みragLeave) } }, [props.ref.current]) } GetBoundingClientRect API ダイアグラム: rectObject = object.getBoundingClientRect(); rectObject.top: 要素の上端からウィンドウの上端までの距離。 rectObject.right: 要素の右側からウィンドウの左側までの距離。 rectObject.bottom: 要素の下部からウィンドウの上部までの距離。 rectObject.left: 要素の左側からウィンドウの左側までの距離。 これで、100 行を超えるコードで React ドラッグ アンド ドロップ フックを実装する方法に関するこの記事は終了です。React ドラッグ アンド ドロップ フックに関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: mysql5.7 でユーザーの初期パスワードを変更する方法
>>: Linux カーネル デバイス ドライバー システム コールに関する注意事項
序文CentOS 環境変数設定ファイル システムは階層型システムであり、他のマルチユーザー アプリケ...
Ubuntu仮想マシンでのシリアル通信にcutecomを使用する1. cutecomをインストールす...
目次1. ソースコード1.1 モノレポ1.2 タイプスクリプト2. パフォーマンス2.1 ソースコー...
この記事では、MySQL の ROUND 関数を使用した丸め操作の落とし穴を例を使って説明します。ご...
目次MySQL 制約操作1. 非ヌル制約2. ユニーク制約3. 主キー制約4. 外部キー制約5. カ...
この記事の例では、星を消すためのJSの具体的なコードを参考までに共有しています。具体的な内容は次のと...
この記事の例では、すべてのチェックボックスの選択を実現するためのJavaScriptの具体的なコード...
序文MySQL スロー クエリ ログは、日常業務でよく遭遇する機能です。MySQL スロー クエリ ...
超初心者の私は、MySQL を学び始めたばかりで、インストール プロセス中に多くの問題に遭遇しました...
序文名前付きスロットは、スロット内の「name」属性を使用して要素にバインドされます。知らせ: 1....
目次Dockerとは展開する1. イメージをプルする2. 画像を表示する3. コンテナを実行する4....
1. フローティング方式を使用する効果画像: コードは次のとおりです: (.content の高さは...
目次01 レプリカセットアーキテクチャ02 MySQL Shellの紹介とインストール03 My...
まずpostcss-pxtoremをインストールします: npm install postcss-p...
序文仕事では、Linux 環境で操作する必要があることがよくあります。ここでは、win10 システム...