検索
ホームページウェブフロントエンドjsチュートリアル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>
  );
注: デモでは実際の dom ノードを取得する必要があるため、ref が定義されています。

CSS スタイルを追加するとページが完成します。いよいよ、ここからが本題です! ! !

4. ドラッグ アンド ドロップを実装するための親コンポーネントと子コンポーネント間の通信

注: 達成したい効果は、サブコンポーネント DragArea でマウスを押すとフォーム全体がドラッグされることなので、DragArea がドラッグを開始し、フォームが応答します。したがって、親コンポーネントの一部の状態プロパティを最初に子コンポーネントに渡す必要があります。その後、DragArea 上でマウスが押されたときに、親コンポーネントの元の座標パラメータが子コンポーネント DragArea を介して検出される必要があります。親コンポーネントの状態プロパティを更新する必要があり、ドラッグが利用可能であることを親コンポーネントに伝えます。親コンポーネントから子コンポーネントに渡されるパラメータは直接渡されます。子コンポーネントは、親コンポーネントにパラメータを渡すためにイベントを渡す必要があります。したがって、親コンポーネントでそのような関数を定義します。

onChildChanged:function(newState){ //因为参数过多,所以把参数放到对象里面,通过对象来传
  this.setState(newState);
},
サブコンポーネントは、上記のコードのように、この関数をバインドする必要があります: callbackParent={this.onChildChanged}

子コンポーネントの応答関数は次のとおりです:

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>
}
このようにして、サブコンポーネントでドラッグ スイッチがアクティブになり、from の関連する 2 つのイベント、move および endDrag が更新されます。

move:function(event){
  var e = event &#63; 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

以上がこの記事の全内容です。皆様の学習のお役に立てれば幸いです。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
React父组件怎么调用子组件的方法React父组件怎么调用子组件的方法Dec 27, 2022 pm 07:01 PM

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

怎么调试React源码?多种工具下的调试方法介绍怎么调试React源码?多种工具下的调试方法介绍Mar 31, 2023 pm 06:54 PM

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

深入理解React的自定义Hook深入理解React的自定义HookApr 20, 2023 pm 06:22 PM

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

React为什么不将Vite作为构建应用的首选React为什么不将Vite作为构建应用的首选Feb 03, 2023 pm 06:41 PM

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

react怎么设置div高度react怎么设置div高度Jan 06, 2023 am 10:19 AM

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

7 个很棒且实用的React 组件库(压箱底分享)7 个很棒且实用的React 组件库(压箱底分享)Nov 04, 2022 pm 08:00 PM

本篇文章给大家整理分享7 个很棒且实用的React 组件库,日常开发中经常会用到的,快来收藏试试吧!

【翻译】使用自定义hooks对React组件进行重构【翻译】使用自定义hooks对React组件进行重构Jan 17, 2023 pm 08:13 PM

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

聊聊Vuex与Pinia在设计与实现上的区别聊聊Vuex与Pinia在设计与实现上的区别Dec 07, 2022 pm 06:24 PM

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

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

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

EditPlus 中国語クラック版

EditPlus 中国語クラック版

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