欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于React.js實現(xiàn)原生js拖拽效果引發(fā)的思考

 更新時間:2021年09月23日 14:37:21   作者:小蚊  
這篇文章主要為大家詳細介紹了基于React.js實現(xiàn)原生js拖拽效果,繼而引發(fā)的一系列思考,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、起因&思路

一直想寫一個原生js拖拽效果,又加上近來學react學得比較嗨。所以就用react來實現(xiàn)這個拖拽效果。

首先,其實拖拽效果的思路是很簡單的。主要就是三個步驟:

1.onmousedown的時候,啟動可拖拽事件,記錄被拖拽元素的原始坐標參數(shù)。

2.onmousemove的時候,實時記錄鼠標移動的距離,結(jié)合被拖拽元素第一階段的坐標參數(shù),計算并設(shè)置新的坐標值。

3.onmouseup的時候,關(guān)閉可拖拽事件,記錄新的坐標值。

注意:這里主要是通過絕對定位的top和left來確定元素的位置的,因此被拖拽元素的css一定要設(shè)置絕對定位。

二、輔助工具

輔助工具主要就是是開發(fā)過程變得高效,而且酷炫的。在這個demo中,要給大家推薦一個gulp+browser-sync的開發(fā)工具,gulp有很多功能,在這個demo中g(shù)ulp的作用主要是可以設(shè)置實時編譯react中的jsx文件,當然如果你寫css用的是sass,也可以設(shè)置實時編譯sass。用browser-sync這個呢,主要就是可以自動實時刷新頁面,我們平時做頁面,看效果的時候,通常都是通過F5來刷新瀏覽器,然后看到頁面的。但是用了這個插件,你寫完代碼的時候,只要按下,ctrl+s保存,新的效果就會自動在瀏覽器中刷新,然后看得到了。

用法詳解:

安裝:

1.在node的環(huán)境下,安裝gulp,這里就不詳說了,具體過程可參考我的博文《react.js入門必須知道的那些事》

2.安裝gulp-livereload,在命令行或者git bash ,輸入npm install --save-dev gulp-livereload

3.安裝gulp-watch,在命令行或者git bash ,輸入npm install --save-dev gulp-watch

4.安裝browser-sync,在命令行或者git bash ,輸入npm install --save-dev browser-sync

配置及解釋如圖:

三、定義組件構(gòu)建頁面

備注:這里的代碼說明均在react相關(guān)模塊安裝好的情況下,安裝過程見我的博文《react.js入門必須知道的那些事》.

效果圖:

組件拆分思路:

我當時覺得組件拆分得細一點好,所以我把input、button分別做成了一個組件:

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;

由于input有很多都是需要指定的,這種情況下,如果像我這樣定義需要傳太多參數(shù),而且其實登陸的input大多都是固定且沒必要復用的,所以這樣其實不大好。這里的input直接寫比較好。

寫好之后的父組件:

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>
  );

備注:因為demo中需要獲取真實的dom節(jié)點,所以定義了ref。

再加上css樣式,頁面就完成啦!最后,重點來啦!??!

四、父子組件間通信實現(xiàn)拖拽

說明:由于我要實現(xiàn)的效果是,鼠標按住子組件DragArea的時候,拖動的是整個form,所以啟動拖拽的是DragArea,而響應的是form。所以,一開始必須把父組件的一些狀態(tài)屬性傳給子組件,然后鼠標在DragArea按下的的時候,必須通過子組件DragArea找到父組件的原始坐標參數(shù),然后更新父組件里面的狀態(tài)屬性,并且告訴父組件可以進行拖拽了。父組件給子組件傳參就是直接傳遞的。而子組件給父組件傳參需要通過事件。所以在父組件中定義這么一個函數(shù):

onChildChanged:function(newState){ //因為參數(shù)過多,所以把參數(shù)放到對象里面,通過對象來傳
  this.setState(newState);
},

而子組件需要綁定這個函數(shù),如上面的代碼:callbackParent={this.onChildChanged}

在子組件中,響應的函數(shù)為:

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>
}

這樣,在子組件中就啟動了拖拽開關(guān),并且已經(jīng)更新了from的相關(guān)參數(shù),from的兩外兩個事件,move和endDrag分別為:

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
  });
}

至此,拖拽實現(xiàn)!

五、反思回顧

 1.理論上來說,拖拽效果可以在任意元素中實現(xiàn),拖拽的思路都是一致的,所以理論上來說,拖拽各個過程的函數(shù)可以抽離出來,做成一個Mixin,然后可以反復調(diào)用。我一開始的思路就是這樣,但是在傳參、響應、綁定元素上面總是出錯。查找了一下資料,沒找到react與拖拽的簡單寫法資料,只有一些react的專用插件,而且是用ES6的寫法,由于現(xiàn)在的水平還沒能看懂。所以暫時放棄了這種寫法。希望有相關(guān)想法的大神們和我交流一下。

2.文中子組件獲取from的參數(shù)時,用了var dragBox=document.getElementById('form');去找dom,這樣好像違反了react的一些理念。但是我還不是很熟悉該怎么從子組件獲取父組件的dom。我試過在父組件定義refs=this.refs.dragBox。然后傳給子組件,但是不知道為什么瀏覽器一直報錯說這個不是dom節(jié)點。求大神指教。

3.拖拽事件的一般寫法,是在document上面定義mousemove和mouseup事件,但是這兩個事件都關(guān)聯(lián)到from的參數(shù),這樣的話,如果我在react中定義在document,就跟蹤不了相關(guān)參數(shù)。所以我就定義在了from上面。是不是有更好的方法呢?求分享!

4.革命尚未成功,同志仍需努力!

 本demo已上傳至:https://github.com/LuckyWinty/dragDemo

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助。

相關(guān)文章

  • react中如何使用監(jiān)聽

    react中如何使用監(jiān)聽

    在 React 中,您可以使用?addEventListener?函數(shù)來監(jiān)聽事件,本文通過實例代碼給大家介紹react中如何使用監(jiān)聽,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • React星星評分組件的實現(xiàn)

    React星星評分組件的實現(xiàn)

    評分插件在購物的應用中經(jīng)常可以看得到,但是用著別人的總是沒有自己寫的順手,本文就使用React實現(xiàn)星星評分組件,感興趣的可以了解一下
    2021-06-06
  • React實現(xiàn)文件分片上傳和下載的方法詳解

    React實現(xiàn)文件分片上傳和下載的方法詳解

    在當今的前端開發(fā)中,處理文件流操作已經(jīng)成為一個常見的需求,無論是上傳、下載、讀取、展示還是其他的文件處理操作,都需要高效且可靠地處理二進制數(shù)據(jù),本文將深入探討如何使用 React 實現(xiàn)文件分片上傳和下載,并介紹相關(guān)的基本概念和技術(shù),需要的朋友可以參考下
    2023-08-08
  • React.js入門實例教程之創(chuàng)建hello world 的5種方式

    React.js入門實例教程之創(chuàng)建hello world 的5種方式

    React 是近期非常熱門的一個前端開發(fā)框架。應用非常廣泛,接下來通過本文給大家介紹React.js入門實例教程之創(chuàng)建hello world 的5種方式 ,需要的朋友參考下吧
    2016-05-05
  • 深入研究React中setState源碼

    深入研究React中setState源碼

    這篇文章主要介紹了深入研究React中setState源碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • React懶加載實現(xiàn)原理深入分析

    React懶加載實現(xiàn)原理深入分析

    懶加載意思是不會預加載,而是需要使用某段代碼,某個組件或者某張圖片時,才加載他們(延遲加載),這篇文章主要介紹了React懶加載實現(xiàn)原理
    2022-11-11
  • React Native 真機斷點調(diào)試+跨域資源加載出錯問題的解決方法

    React Native 真機斷點調(diào)試+跨域資源加載出錯問題的解決方法

    下面小編就為大家分享一篇React Native 真機斷點調(diào)試+跨域資源加載出錯問題的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • React onClick/onChange傳參(bind綁定)問題

    React onClick/onChange傳參(bind綁定)問題

    這篇文章主要介紹了React onClick/onChange傳參(bind綁定)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 詳解React 和 Redux的關(guān)系

    詳解React 和 Redux的關(guān)系

    這篇文章主要為大家介紹了React 和 Redux的關(guān)系,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • React如何實現(xiàn)瀏覽器打印部分內(nèi)容詳析

    React如何實現(xiàn)瀏覽器打印部分內(nèi)容詳析

    這篇文章主要給大家介紹了關(guān)于利用React如何實現(xiàn)瀏覽器打印部分內(nèi)容的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用React具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-05-05

最新評論