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
以上がこの記事の全内容です。皆様の学習のお役に立てれば幸いです。

调用方法:1、类组件中的调用可以利用React.createRef()、ref的函数式声明或props自定义onRef属性来实现;2、函数组件、Hook组件中的调用可以利用useImperativeHandle或forwardRef抛出子组件ref来实现。

怎么调试React源码?下面本篇文章带大家聊聊多种工具下的调试React源码的方法,介绍一下在贡献者、create-react-app、vite项目中如何debugger React的真实源码,希望对大家有所帮助!

React 自定义 Hook 是一种将组件逻辑封装在可重用函数中的方式,它们提供了一种在不编写类的情况下复用状态逻辑的方式。本文将详细介绍如何自定义封装 hook。

React为什么不将Vite作为构建应用的首选?下面本篇文章就来带大家聊聊React不将Vite作为默认推荐的原因,希望对大家有所帮助!

react设置div高度的方法:1、通过css方式实现div高度;2、在state中声明一个对象C,并在该对象中存放更换按钮的样式,然后获取A并重新设置C中的“marginTop”即可。

我时常会听到人们谈起React函数组件,提到函数组件会不可避免的变得体积更大,逻辑更复杂。毕竟,我们把组件写在了“一个函数”里,因此你不得不接受组件会膨胀导致这个函数会不断膨胀。

在进行前端项目开发时,状态管理始终是一个绕不开的话题,Vue 与 React 框架本身提供了一部分能力去解决这个问题。但是在开发大型应用时往往有其他考虑,比如需要更规范更完善的操作日志、集成在开发者工具中的时间旅行能力、服务端渲染等。本文以 Vue 框架为例,介绍 Vuex 与 Pinia 这两种状态管理工具在设计与实现上的区别。


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

Dreamweaver Mac版
ビジュアル Web 開発ツール

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

ホットトピック



