ホームページ ウェブフロントエンド jsチュートリアル React.js_javascript スキルに基づいたネイティブ js ドラッグ アンド ドロップ効果の実装によって引き起こされる考え

React.js_javascript スキルに基づいたネイティブ js ドラッグ アンド ドロップ効果の実装によって引き起こされる考え

May 16, 2016 pm 03:07 PM
react.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 までご連絡ください。

ホット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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Reactの親コンポーネントで子コンポーネントのメソッドを呼び出す方法 Reactの親コンポーネントで子コンポーネントのメソッドを呼び出す方法 Dec 27, 2022 pm 07:01 PM

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

React ソースコードをデバッグするにはどうすればよいですか?複数のツールを使用したデバッグ方法の紹介 React ソースコードをデバッグするにはどうすればよいですか?複数のツールを使用したデバッグ方法の紹介 Mar 31, 2023 pm 06:54 PM

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

React のカスタムフックについての深い理解 React のカスタムフックについての深い理解 Apr 20, 2023 pm 06:22 PM

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

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. ステートでオブジェクト C を宣言し、オブジェクトに変更ボタンのスタイルを格納し、A を取得して C の "marginTop" をリセットします. それがキャンです。

7 つの優れた実用的な React コンポーネント ライブラリ (プレッシャーの下で共有) 7 つの優れた実用的な React コンポーネント ライブラリ (プレッシャーの下で共有) Nov 04, 2022 pm 08:00 PM

この記事では、日常の開発で頻繁に使用される、優れた実用的な React コンポーネント ライブラリを 7 つ紹介します。

[翻訳] カスタムフックを使用した React コンポーネントのリファクタリング [翻訳] カスタムフックを使用した React コンポーネントのリファクタリング Jan 17, 2023 pm 08:13 PM

React の関数コンポーネントについて人々が話し、関数コンポーネントは必然的に大きくなり、論理的により複雑になるという話をよく聞きます。結局のところ、コンポーネントを「関数」で記述したため、コンポーネントが拡張され、関数も拡張し続けることを受け入れる必要があります。

Vuex と Pinia の設計と実装の違いについて話しましょう Vuex と Pinia の設計と実装の違いについて話しましょう Dec 07, 2022 pm 06:24 PM

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

See all articles