寫在世界杯當(dāng)中...
好吧层亿,當(dāng)別人刷世界杯的時(shí)候桦卒,我還在刷拖拽的bug...
這個(gè)確實(shí)是給自己挖的坑
整理了一下拖拽坑的幾個(gè)思路
首先上個(gè)API
在拖動(dòng)目標(biāo)上觸發(fā)事件 (源元素):
ondragstart - 用戶開始拖動(dòng)元素時(shí)觸發(fā)
ondrag - 元素正在拖動(dòng)時(shí)觸發(fā)
ondragend - 用戶完成元素拖動(dòng)后觸發(fā)
釋放目標(biāo)時(shí)觸發(fā)的事件:
ondragenter - 當(dāng)被鼠標(biāo)拖動(dòng)的對(duì)象進(jìn)入其容器范圍內(nèi)時(shí)觸發(fā)此事件
ondragover - 當(dāng)某被拖動(dòng)的對(duì)象在另一對(duì)象容器范圍內(nèi)拖動(dòng)時(shí)觸發(fā)此事件
ondragleave - 當(dāng)被鼠標(biāo)拖動(dòng)的對(duì)象離開其容器范圍內(nèi)時(shí)觸發(fā)此事件
ondrop - 在一個(gè)拖動(dòng)過程中,釋放鼠標(biāo)鍵時(shí)觸發(fā)此事件
1匿又,該死的拖拽居然是350毫秒才執(zhí)行一次方灾?!requestanimationframe 60毫秒執(zhí)行一次才能感覺到流暢好不碌更。這個(gè)說真的還不如用setTimeout來模擬了裕偿。但是用mouseevent來模擬拖拽事件也確實(shí)太麻煩了,而且項(xiàng)目里面還有用到mouseevent的地方针贬。不過350毫秒的設(shè)計(jì)我想了一下击费,跟接下來的槽點(diǎn)估計(jì)有點(diǎn)關(guān)系。
這個(gè)果然是用來節(jié)流的桦他,用mouseMove來模擬拖拽的時(shí)候要節(jié)流蔫巩。不過我還是覺得這個(gè)要是能自己設(shè)置才最好。
2快压,drag事件沒有方向性可言圆仔。這意味著在猜測(cè)鼠標(biāo)移動(dòng)的方向上要排除一些手滑的噪點(diǎn),最好的方法是用線性回歸的方法去掉那些出問題的點(diǎn)蔫劣,這個(gè)方法有點(diǎn)難寫坪郭,回頭研究python的時(shí)候打算研究下。目前還是用去掉特別奇葩點(diǎn)的方法來猜測(cè)方向的脉幢。用的是兩次位置的差值來看趨勢(shì)的方法歪沃。(這里我覺得用350毫秒就是給我們確定方向才設(shè)計(jì)這么長時(shí)間的)
3嗦锐,最奇葩的點(diǎn)有哪些呢?首先是ondrag事件的最后一幀鼠標(biāo)位置要回到原點(diǎn)...這個(gè)事件還發(fā)生在ondragend的事情之前沪曙。也對(duì)奕污,ondrag事件執(zhí)行完了才執(zhí)行ondragend,但是這樣ondragend里面就拿不到最后的坐標(biāo)位置了液走。解決的思路有兩個(gè)碳默,第一種就是采用事件循環(huán),將ondrag最后一幀送進(jìn)setTimeout里面去讓它一萬年后再發(fā)生缘眶。第二種是發(fā)生鼠標(biāo)位置為(0,0)的時(shí)候就無視嘱根。后面這種方法要好一些。還有一個(gè)奇葩的點(diǎn)是在第一幀的時(shí)候巷懈,計(jì)算出來的鼠標(biāo)位置和實(shí)際的位置差了一點(diǎn)该抒。這個(gè)是控制對(duì)象的實(shí)際位置和鼠標(biāo)有一定的差距,一下子調(diào)整不到鼠標(biāo)的位置上來砸喻。我解決的方式是加個(gè)次數(shù)控制器柔逼,在大于3的時(shí)候,就是基本對(duì)象跟著鼠標(biāo)開始跑了以后才讓對(duì)象移動(dòng)割岛。一頭一尾,兩個(gè)最氣人的地方犯助。
4癣漆,最坑的地方。拖拽的時(shí)候會(huì)很貼心的給你把拖拽的對(duì)象轉(zhuǎn)成圖片跟著鼠標(biāo)走剂买。但是這個(gè)圖片默認(rèn)會(huì)加個(gè)透明度惠爽!這個(gè)透明度是無法去掉的,給了個(gè)API可以將這個(gè)圖片換走瞬哼,但是換走的圖片還是會(huì)加透明度婚肆。仔細(xì)的翻過全部的API了沒有辦法去掉這個(gè)透明,想要去掉透明度怎么辦坐慰?方法還是有的较性,用兩個(gè)對(duì)象,一個(gè)對(duì)象是透明的就是用來拖拽的结胀,另一個(gè)對(duì)象就是用來展示用的赞咙,兩個(gè)對(duì)象一起跟著對(duì)象跑。就是在我們展示的DOM結(jié)構(gòu)上貼上一個(gè)透明的拖拽層糟港。
5攀操,這些都是在react封裝的ondrag的方法上得出的結(jié)果,我覺得還是有必要在原生的情況下實(shí)驗(yàn)下秸抚,不能相信react封裝的方法和js原生的方法100%一樣速和。還是那個(gè)思路歹垫,框架來用的,不能盡信颠放。
最后提醒下自己:
沒事就不要在沒有redux的情況下玩什么兄弟之間的傳參排惨。坑到死慈迈。