React.js_javascript スキルに基づいたネイティブ js ドラッグ アンド ドロップ効果の実装によって引き起こされる考え
1. 原因と考え方
私はネイティブの JS ドラッグ アンド ドロップ エフェクトを書きたいとずっと思っていて、最近は楽しく React を学習しています。そこで、このドラッグ アンド ドロップ効果を実現するために React を使用しました。
まず第一に、ドラッグ効果のアイデアは実際には非常に単純です。主に次の 3 つのステップがあります:
1. マウスダウン時に、ドラッグ可能なイベントを開始し、ドラッグされた要素の元の座標パラメータを記録します。
2. onmousemove の場合、マウスの移動距離をリアルタイムで記録し、ドラッグされた要素の最初のステージの座標パラメーターに基づいて新しい座標値を計算して設定します。
3. onmouseup 中に、ドラッグ可能なイベントを閉じて、新しい座標値を記録します。
注: 要素の位置は主に上と左の絶対位置によって決定されるため、ドラッグされた要素の CSS は絶対位置に設定する必要があります。
2. 補助ツール
補助ツールは主に、開発プロセスを効率的かつクールなものにします。このデモでは、gulp+browser-sync 開発ツールを皆さんにお勧めします。このデモでは、gulp の主な機能は、もちろん、react での jsx ファイルのリアルタイム コンパイルを設定することです。 , cssを書くとsassですが、sassのリアルタイムコンパイルの設定もできます。ブラウザ同期を使用する主な目的は、ページをリアルタイムで自動的に更新することです。通常、ページを作成して効果を確認するときは、F5 キーを押してブラウザを更新してからページを表示します。しかし、このプラグインを使用すると、コードの記述が完了したら、Ctrl+S を押して保存するだけで、新しいエフェクトがブラウザで自動的に更新され、表示できるようになります。
使用方法の詳細な説明:
インストール:
1. gulp をノード環境にインストールします。具体的なプロセスについては、私のブログ投稿「React.js を始めるために知っておくべきこと」を参照してください。
2. gulp-livereload をインストールするには、コマンドラインまたは git bash で「npm install --save-dev gulp-livereload」と入力します。
3. コマンドラインまたは git bash で「npm install --save-dev gulp-watch」と入力して gulp-watch をインストールします4. browser-sync をインストールするには、コマンドラインまたは git bash で「npm install --save-dev browser-sync」と入力します
構成と説明は図のとおりです。
3. コンポーネント構築ページの定義
注: ここでのコードの説明はすべて、react 関連モジュールがインストールされた後のものです。インストール プロセスについては、私のブログ投稿「react.js を始めるために知っておくべきこと」を参照してください。レンダリング:
コンポーネントをより小さな部分に分割した方が良いと考えたので、入力とボタンをそれぞれ 1 つのコンポーネントにしました。
var React=require('react'); var MyInput=React.createClass({ render:function(){ return ( <div className="form-group"> <label htmlFor={this.props.labelId} className="col-sm-2 control-label{this.props.labelTip</label> <div className="col-sm-10"> <input name={this.props.name} type={this.props.type} onChange={this.props.onChange} className="form-control" id={this.props.labelId} placeholder={this.props.placeholder}/> </div> </div> ); } }); module.exports=MyInput;
var React=require('react'); var Button=React.createClass({ render:function(){ return ( <button type={this.props.type} className="loginButton">{this.props.ButtonTip}</button> ); } }) module.exports=Button;
記述後の親コンポーネント:
render:function(){ return ( <form className="form-horizontal" id="form" ref="dragBox" onSubmit={this.submitHandler} onMouseMove={this.move} onMouseUp={this.endDrag}> <DragArea callbackParent={this.onChildChanged} /> <div id="form-wrap"> <MyInput name="username" labelId={"userId"} labelTip={"用户名"} type={"text"} placeholder={"请输入用户名"} value={this.state.username} onChange={this.handleChange}/> <MyInput name="password" labelId={"pw"} labelTip={"密码"} type={"password"} placeholder={"请输入密码"} value={this.state.password} onChange={this.handleChange}/> <div className="form-group"> <div className="col-sm-offset-2 col-sm-10"> <div className="checkbox"> <label> <input name="checked" type="checkbox" checked={this.state.checked} onChange={this.handleChange} /> 记住我 </label> </div> </div> </div> <MyButton type={"submit"} ButtonTip={"登陆"}/> </div> </form> );
CSS スタイルを追加するとページが完成します。いよいよ、ここからが本題です! ! !
4. ドラッグ アンド ドロップを実装するための親コンポーネントと子コンポーネント間の通信
注: 達成したい効果は、サブコンポーネント DragArea でマウスを押すとフォーム全体がドラッグされることなので、DragArea がドラッグを開始し、フォームが応答します。したがって、親コンポーネントの一部の状態プロパティを最初に子コンポーネントに渡す必要があります。その後、DragArea 上でマウスが押されたときに、親コンポーネントの元の座標パラメータが子コンポーネント DragArea を介して検出される必要があります。親コンポーネントの状態プロパティを更新する必要があり、ドラッグが利用可能であることを親コンポーネントに伝えます。親コンポーネントから子コンポーネントに渡されるパラメータは直接渡されます。子コンポーネントは、親コンポーネントにパラメータを渡すためにイベントを渡す必要があります。したがって、親コンポーネントでそのような関数を定義します。
onChildChanged:function(newState){ //因为参数过多,所以把参数放到对象里面,通过对象来传 this.setState(newState); },
子コンポーネントの応答関数は次のとおりです:
startDrag:function(e){ var dragBox=document.getElementById('form'); var newState={}; var event=e||window.event; event.preventDefault(); var computedStyle=document.defaultView.getComputedStyle(dragBox,null); newState.left=computedStyle.left; newState.top=computedStyle.top; newState.currentX=event.clientX; newState.currentY=event.clientY; newState.flag=true; <span style="color: #0000ff;"> this.props.callbackParent(newState);</span> }
move:function(event){ var e = event ? event : window.event; //兼容IE的写法 if (this.state.flag) { var nowX = e.clientX, nowY = e.clientY; var disX = nowX - this.state.currentX, disY = nowY - this.state.currentY; ReactDOM.findDOMNode(this.refs.dragBox).style.left = parseInt(this.state.left) + disX + "px"; ReactDOM.findDOMNode(this.refs.dragBox).style.top = parseInt(this.state.top) + disY + "px"; } }, endDrag:function(){ var computedStyle=document.defaultView.getComputedStyle(ReactDOM.findDOMNode(this.refs.dragBox),null); this.setState({ left:computedStyle.left, top:computedStyle.top, flag:false }); }
この時点で、ドラッグ アンド ドロップが実装されました。
5. 振り返りとレビュー
1. 理論的には、ドラッグ効果はどの要素でも実現でき、ドラッグの考え方は同じなので、理論的には、各ドラッグプロセスの機能を抽出して Mixin にすることができます。繰り返し呼び出すことができます。これが私の最初のアイデアでしたが、パラメーターを渡したり、応答したり、要素をバインドしたりするときにいつも間違いを犯していました。調べてみてもreactやドラッグアンドドロップなどの簡単な記述方法はReact用の特殊なプラグインがいくつかあるだけで、私の現状では理解できませんでした。レベル。ということで、この書き方は一旦やめました。関連するアイデアをお持ちの専門家が私と共有できることを願っています。
2. 記事内のサブコンポーネントは、パラメータを取得するときに varragBox=document.getElementById('form'); を使用して dom を見つけます。これは、react のいくつかの概念に違反しているようです。しかし、子コンポーネントから親コンポーネントのdomを取得する方法がよくわかりません。親コンポーネントで refs=this.refs.dragBox を定義してみました。次に、それがサブコンポーネントに渡されますが、なぜブラウザがこれが dom ノードではないというエラーを報告し続けるのかわかりません。神に導きを求めてください。
3. ドラッグイベントを記述する一般的な方法は、ドキュメント上でmousemoveイベントとmouseupイベントを定義することですが、この場合、これら2つのイベントをreact内のドキュメント内で定義すると、関連するイベントのパラメータを追跡できません。そこで、から定義しました。もっと良い方法はありますか?シェアしてください!
4. 革命はまだ成功していません、同志たちはまだ努力する必要があります!
このデモは次の場所にアップロードされました: https://github.com/LuckyWinty/dragDemo
以上がこの記事の全内容です。皆様の学習のお役に立てれば幸いです。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック

呼び出しメソッド: 1. クラス コンポーネントの呼び出しは、React.createRef()、ref または props のカスタム onRef 属性の関数宣言を使用して実装できます; 2. 関数コンポーネントおよびフック コンポーネントの呼び出しは、useImperativeHandle または forwardRef を使用して実装できます。子コンポーネントの ref が実装されています。

React ソースコードをデバッグするにはどうすればよいですか?次の記事では、さまざまなツールで React のソース コードをデバッグする方法について説明し、コントリビューター、create-react-app、vite プロジェクトで React の実際のソース コードをデバッグする方法を紹介します。

React カスタム フックは、コンポーネント ロジックを再利用可能な関数にカプセル化する方法であり、クラスを作成せずに状態ロジックを再利用する方法を提供します。この記事では、カプセル化フックをカスタマイズする方法を詳しく紹介します。

React はなぜ Vite をアプリケーション構築の第一の選択肢として使用しないのでしょうか?次の記事では、React が Vite をデフォルトの推奨事項として推奨しない理由について説明します。

React で div の高さを設定する方法: 1. CSS を通じて div の高さを実装します; 2. ステートでオブジェクト C を宣言し、オブジェクトに変更ボタンのスタイルを格納し、A を取得して C の "marginTop" をリセットします. それがキャンです。

この記事では、日常の開発で頻繁に使用される、優れた実用的な React コンポーネント ライブラリを 7 つ紹介します。
![[翻訳] カスタムフックを使用した React コンポーネントのリファクタリング](https://img.php.cn/upload/article/000/000/024/63c690a1b11d0794.jpg?x-oss-process=image/resize,m_fill,h_207,w_330)
React の関数コンポーネントについて人々が話し、関数コンポーネントは必然的に大きくなり、論理的により複雑になるという話をよく聞きます。結局のところ、コンポーネントを「関数」で記述したため、コンポーネントが拡張され、関数も拡張し続けることを受け入れる必要があります。

フロントエンド プロジェクトを開発する場合、状態管理は常に避けられないトピックですが、Vue および React フレームワーク自体が、この問題を解決するための機能をいくつか提供しています。ただし、大規模なアプリケーションを開発する場合は、より標準化された完全な操作ログ、開発者ツールに統合されたタイムトラベル機能、サーバー側レンダリングなどの必要性など、他の考慮事項も多くあります。この記事では、Vue フレームワークを例として、2 つの状態管理ツールである Vuex と Pinia の設計と実装の違いを紹介します。
