鍍金池/ 問答/HTML/ Vue 百度首頁我的關(guān)注里拖動(dòng)div是怎么實(shí)現(xiàn)的?

Vue 百度首頁我的關(guān)注里拖動(dòng)div是怎么實(shí)現(xiàn)的?

圖片描述

這個(gè)是百度首頁的我的關(guān)注里面的功能,不知道是怎么做的,請(qǐng)教大神們。

圖片描述

現(xiàn)在點(diǎn)擊右側(cè)一個(gè)div,拖動(dòng)到左面

圖片描述

從右側(cè)拖動(dòng),會(huì)有一個(gè)虛線框,然后拖動(dòng)的div改變了css樣式

圖片描述

當(dāng)拖到中間偏左的時(shí)候,左側(cè)也會(huì)顯示虛線框,當(dāng)放手的時(shí)候,拖動(dòng)的div會(huì)??吭谧髠?cè)。
如果拖到中間偏右的話,當(dāng)放手的時(shí)候,拖動(dòng)的div會(huì)停靠在右側(cè)。

【如果我描述的不夠詳細(xì),各位可以打開百度首頁,在登錄百度賬號(hào)之后可以查看】
這個(gè)復(fù)雜的過程,請(qǐng)問各位大神們,是怎么實(shí)現(xiàn)的?

回答
編輯回答
不討囍

這和vue這種mvvm框架沒什么本質(zhì)關(guān)聯(lián),就是在瀏覽器提供的原生拖拽事件上,增加一些視圖層邏輯,這部分邏輯應(yīng)該是你想知道的東西吧?

首先簡單講你看到的元素其實(shí)是什么:

  • 虛框其實(shí)就是一個(gè)占位元素,一般叫做placeholder,它可能就是一個(gè)div,然后加一個(gè)虛框的樣式,僅此而已
  • 你拖拽的那個(gè)是一個(gè)鏡像元素,一般叫做mirror,它可能也是一個(gè)div或者別的什么的,然后加一個(gè)拖拽效果的樣式

首先先將這兩個(gè)元素放到頁面上,同時(shí)把它們隱藏。

之后就要利用瀏覽器的拖拽事件(drag, dragStart, dragOver之類的,這個(gè)詳細(xì)的去MDN上查)來抽象拖拽過程,以從右往左舉例:

  • 在右側(cè)拖拽事件開始時(shí),隱藏你要拖的那個(gè)元素,同時(shí)顯示mirror
  • 之后拖拽的過程,會(huì)響應(yīng)鼠標(biāo)移動(dòng)的事件,動(dòng)態(tài)的移動(dòng)mirror的位置
  • 之后懸浮到左邊的容器元素上了,會(huì)響應(yīng)dragOver事件,這時(shí)候顯示左框中的placeholder
  • 之后拖拽完成時(shí),會(huì)觸發(fā)drop相關(guān)的事件,隱藏mirror和placeholder,同時(shí)將真正的右側(cè)元素移動(dòng)到左邊

我這個(gè)描述是偏向dom層的,你用vue來做,可以把移動(dòng)元素的邏輯抽象到數(shù)據(jù)層來完成。

不過話說回來,這種拖拽其實(shí)是比較常用的交互,因此存在大量現(xiàn)成的工具庫,我給你推薦一個(gè)draggable。有興趣可以看看這些庫的源碼,基本和上面我所描述的差不多,唯一的區(qū)別在于,實(shí)現(xiàn)拖拽過程的事件可能不是利用drag/drop這類的,而是利用mouseup/mouseover/mousedown等鼠標(biāo)事件模擬的,但是大同小異。

同時(shí)關(guān)于拖拽的整個(gè)過程是一個(gè)event-driven的業(yè)務(wù)場(chǎng)景,因此使用一些響應(yīng)式的輔助手段會(huì)更好,比如rxjs,同時(shí)處理多個(gè)異步事件,我會(huì)經(jīng)常把自己寫懵逼。

2018年4月6日 04:46