亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

再次談論React.js實現(xiàn)原生js拖拽效果引起的一系列問題

 更新時間:2016年04月03日 11:56:25   作者:小蚊  
React 起源于 Facebook 的內(nèi)部項目,因為該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設 Instagram 的網(wǎng)站.本文給大家介紹React.js實現(xiàn)原生js拖拽效果,需要的朋友一起學習吧

React 起源于 Facebook 的內(nèi)部項目,因為該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設 Instagram 的網(wǎng)站。做出來以后,發(fā)現(xiàn)這套東西很好用,就在2013年5月開源了。由于 React 的設計思想極其獨特,屬于革命性創(chuàng)新,性能出眾,代碼邏輯卻非常簡單。所以,越來越多的人開始關(guān)注和使用,認為它可能是將來 Web 開發(fā)的主流工具。

前幾天寫的那個拖拽,自己留下的疑問。。。這次在熱心博友的提示下又修正了一些小小的bug,也加了拖拽的邊緣檢測部分。。。就再聊聊拖拽吧

一、不要直接操作dom元素

react中使用了虛擬dom的概念,目地就是要盡量避免直接操作dom元素,所以我們在對dom元素進行操作的時候需要注意,我之前為了獲取form的參數(shù)就直接用了var dragBox=document.getElementById('form')去找dom,但是其實記錄from的初始位置,可以在其子組件更新父組件參數(shù)的時候調(diào)用。即在MyFrom組件中獲取,如下代碼:

onChildChanged:function(newState){
/*以下為修改處*/
var computedStyle=document.defaultView.getComputedStyle(ReactDOM.findDOMNode(this.refs.dragBox),null);
newState.left=computedStyle.left;
newState.top=computedStyle.top;
/*以上為修改處*/
this.setState(newState);
},

這樣就可以直接在父組件中操作自己,而不是在子組件中調(diào)用。

二、onmousemove和onmouseup事件應該綁定到document上

拖拽事件中,當鼠標在DragArea中按下后,就應該檢測鼠標在document中移動的距離及何時彈起。否則直接綁定在form的話會有一個不雅的地方,就是拖動條拖動邊緣附近的時候,如果鼠標速度快一點會失效,鼠標再回來拖動條會自動吸上鼠標。因此利用react初始化階段的componentDidMount函數(shù),這個函數(shù)是組件被裝載后才會被調(diào)用,也就是說調(diào)用這個方法的時候,組件已經(jīng)被渲染到了頁面上,這個時候可以修改DOM。也就是說此時把相應事件再綁定到document上面,如下代碼:

componentDidMount:function(){
document.addEventListener('mousemove',(e)=>{this.move(e);},false);/*ES6新特性,箭頭函數(shù),需要依賴jsx編譯工具才能正確運行*/
document.addEventListener('mouseup',(e)=>{this.endDrag(e);},false);
},

這樣就可以消除那個小小的bug啦!

三、增加邊緣檢測

一般情況下的拖拽,我們都是不希望能夠拖出可視窗口之外的,因此這就需要檢測。檢測四個方向上的位置,即上、下、左、右。顯然,上的距離top和左邊left的距離必須要大于等于0,下邊和右的距離必須要小于視口大小減去from本身的元素寬高。

具體代碼:

move:function(event){
var e = event ? event : window.event;
var dBox=ReactDOM.findDOMNode(this.refs.dragBox);
if (this.state.flag) {
var nowX = e.clientX, nowY = e.clientY;
var disX = nowX - this.state.currentX, disY = nowY - this.state.currentY;
/*增加拖拽范圍檢測*/
var currentLeft=parseInt(this.state.left) + disX;
var currentTop=parseInt(this.state.top) + disY;
var docX=document.documentElement.clientWidth||document.body.clientWidth;
var docY=document.documentElement.clientHeight||document.body.clientHeight;
if(currentLeft<=250){//檢測屏幕左邊,因為我這里的初始居中是利用了負1/2的盒子寬度的margin,所以用250px判斷邊界
dBox.style.left=250+"px";
}else if(currentLeft>=(docX-dBox.offsetWidth+250)){ //檢測右邊
dBox.style.left=(docX-this.state.offsetX)+"px";
}else{
dBox.style.left =currentLeft+ "px";
}
if(currentTop<=200){ //檢測屏幕上邊,因為我這里的初始居中是利用了負1/2的盒子高度的margin,所以用200px判斷邊界 <br> dBox.style.top=200+"px"; <br> }else if(currentTop>=(docY-dBox.offsetHeight+200)){ //檢測下邊<br> dBox.style.top=(docY-this.state.offsetY)+"px";<br> }else{<br> dBox.style.top = currentTop + "px"; <br> }<br> }

PS:新的代碼已經(jīng)更新在我的github上面,大家可以研究一下。

ReactJS的背景和原理

在Web開發(fā)中,我們總需要將變化的數(shù)據(jù)實時反應到UI上,這時就需要對DOM進行操作。而復雜或頻繁的DOM操作通常是性能瓶頸產(chǎn)生的原因(如何進行高性能的復雜DOM操作通常是衡量一個前端開發(fā)人員技能的重要指標)。React為此引入了虛擬DOM(Virtual DOM)的機制:在瀏覽器端用Javascript實現(xiàn)了一套DOM API。基于React進行開發(fā)時所有的DOM構(gòu)造都是通過虛擬DOM進行,每當數(shù)據(jù)變化時,React都會重新構(gòu)建整個DOM樹,然后React將當前整個DOM樹和上一次的DOM樹進行對比,得到DOM結(jié)構(gòu)的區(qū)別,然后僅僅將需要變化的部分進行實際的瀏覽器DOM更新。而且React能夠批處理虛擬DOM的刷新,在一個事件循環(huán)(Event Loop)內(nèi)的兩次數(shù)據(jù)變化會被合并,例如你連續(xù)的先將節(jié)點內(nèi)容從A變成B,然后又從B變成A,React會認為UI不發(fā)生任何變化,而如果通過手動控制,這種邏輯通常是極其復雜的。盡管每一次都需要構(gòu)造完整的虛擬DOM樹,但是因為虛擬DOM是內(nèi)存數(shù)據(jù),性能是極高的,而對實際DOM進行操作的僅僅是Diff部分,因而能達到提高性能的目的。這樣,在保證性能的同時,開發(fā)者將不再需要關(guān)注某個數(shù)據(jù)的變化如何更新到一個或多個具體的DOM元素,而只需要關(guān)心在任意一個數(shù)據(jù)狀態(tài)下,整個界面是如何Render的。

如果你像在90年代那樣寫過服務器端Render的純Web頁面那么應該知道,服務器端所要做的就是根據(jù)數(shù)據(jù)Render出HTML送到瀏覽器端。如果這時因為用戶的一個點擊需要改變某個狀態(tài)文字,那么也是通過刷新整個頁面來完成的。服務器端并不需要知道是哪一小段HTML發(fā)生了變化,而只需要根據(jù)數(shù)據(jù)刷新整個頁面。換句話說,任何UI的變化都是通過整體刷新來完成的。而React將這種開發(fā)模式以高性能的方式帶到了前端,每做一點界面的更新,你都可以認為刷新了整個頁面。至于如何進行局部更新以保證性能,則是React框架要完成的事情。

借用Facebook介紹React的視頻中聊天應用的例子,當一條新的消息過來時,傳統(tǒng)開發(fā)的思路如上圖,你的開發(fā)過程需要知道哪條數(shù)據(jù)過來了,如何將新的DOM結(jié)點添加到當前DOM樹上;而基于React的開發(fā)思路如下圖,你永遠只需要關(guān)心數(shù)據(jù)整體,兩次數(shù)據(jù)之間的UI如何變化,則完全交給框架去做??梢钥吹?,使用React大大降低了邏輯復雜性,意味著開發(fā)難度降低,可能產(chǎn)生Bug的機會也更少。

相關(guān)文章

  • ReactJS?應用兼容ios9對標ie11解決方案

    ReactJS?應用兼容ios9對標ie11解決方案

    這篇文章主要為大家介紹了ReactJS?應用兼容ios9對標ie11解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • React組件設計模式之組合組件應用實例分析

    React組件設計模式之組合組件應用實例分析

    這篇文章主要介紹了React組件設計模式之組合組件,結(jié)合實例形式分析了React組件設計模式中組合組件相關(guān)概念、原理、應用場景與操作注意事項,需要的朋友可以參考下
    2020-04-04
  • react源碼層探究setState作用

    react源碼層探究setState作用

    寫react的時候,踩了幾次坑發(fā)現(xiàn)setstate之后state不會立刻更新,于是判定setstate就是異步的方法,但是直到有一天,我想立刻拿到更新的state去傳參另一個方法的時候,才問自己,為什么setstate是異步的?準確地說,在React內(nèi)部機制能檢測到的地方,setState就是異步的
    2022-10-10
  • 如何利用React實現(xiàn)圖片識別App

    如何利用React實現(xiàn)圖片識別App

    圖片識別這個功能在很多app中都有,下面這篇文章主要給大家介紹了關(guān)于如何利用React實現(xiàn)圖片識別App的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-01-01
  • 關(guān)于react+antd樣式不生效問題的解決方式

    關(guān)于react+antd樣式不生效問題的解決方式

    最近本人在使用Antd開發(fā)時遇到些問題,所以下面這篇文章主要給大家介紹了關(guān)于react+antd樣式不生效問題的解決方式,文中通過圖文以及實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • react antd如何防止一份數(shù)據(jù)多次提交

    react antd如何防止一份數(shù)據(jù)多次提交

    這篇文章主要介紹了react antd如何防止一份數(shù)據(jù)多次提交問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 淺談React + Webpack 構(gòu)建打包優(yōu)化

    淺談React + Webpack 構(gòu)建打包優(yōu)化

    本篇文章主要介紹了淺談React + Webpack 構(gòu)建打包優(yōu)化,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • ReactQuery?渲染優(yōu)化示例詳解

    ReactQuery?渲染優(yōu)化示例詳解

    這篇文章主要為大家介紹了ReactQuery?渲染優(yōu)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • react ant Design手動設置表單的值操作

    react ant Design手動設置表單的值操作

    這篇文章主要介紹了react ant Design手動設置表單的值操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • React報錯Too many re-renders解決

    React報錯Too many re-renders解決

    這篇文章主要為大家介紹了React報錯Too many re-renders解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12

最新評論