一、拖拽效果示例這是移動(dòng)端很常見的一個(gè)效果,可以按住拖來拖去,比如下面的起點(diǎn)中文網(wǎng)觸屏版:

這類效果用JS可以很容易實(shí)現(xiàn),無非就是多了一些計(jì)算,多考慮了一" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運(yùn)營 > 純 CSS 也能實(shí)現(xiàn)拖拽效果?

純 CSS 也能實(shí)現(xiàn)拖拽效果?

時(shí)間:2023-07-20 21:09:01 | 來源:網(wǎng)站運(yùn)營

時(shí)間:2023-07-20 21:09:01 來源:網(wǎng)站運(yùn)營

純 CSS 也能實(shí)現(xiàn)拖拽效果?:發(fā)揮你的想象,CSS也能實(shí)現(xiàn)拖拽效果。

一、拖拽效果示例

這是移動(dòng)端很常見的一個(gè)效果,可以按住拖來拖去,比如下面的起點(diǎn)中文網(wǎng)觸屏版:

這類效果用JS可以很容易實(shí)現(xiàn),無非就是多了一些計(jì)算,多考慮了一些臨界場景,然后代碼量也多了一些。不過,經(jīng)過我的一番腦洞,發(fā)現(xiàn)CSS也能幾乎實(shí)現(xiàn)這一效果,接著往下看。

二、CSS實(shí)現(xiàn)原理

在傳統(tǒng) web 中,頁面滾動(dòng)是一個(gè)很常見交互,操作上就是利用鼠標(biāo)滾輪或者直接拖動(dòng)滾動(dòng)條。但是,移動(dòng)端可不一樣,直接用手指拖動(dòng)頁面就可以滾動(dòng)了。通常頁面是要么垂直方向滾動(dòng),要么水平方向滾動(dòng),如果兩個(gè)方向都可以滾動(dòng)呢?例如

.dragbox{ width: 300px; height: 300px; overflow: auto}.dragcon{ width: 500px; height: 500px;}只需要內(nèi)部元素寬高都大于容器就實(shí)現(xiàn)兩個(gè)方向的滾動(dòng)了(記得設(shè)置overflow:auto),示意如下

一般情況下,鼠標(biāo)滾輪只能同時(shí)滾動(dòng)一個(gè)方向(按住Shift可以滾動(dòng)另一方向),但是移動(dòng)端可以直接拖著內(nèi)容任意滾動(dòng),如下所示

現(xiàn)在,在內(nèi)容中間添加一個(gè)元素,跟隨內(nèi)容區(qū)域一起滾動(dòng)

接下來,把后面的文本隱藏起來

是不是有點(diǎn)拖拽的味道了?原理就是這么簡單!

三、CSS實(shí)現(xiàn)細(xì)節(jié)

首先確定拖拽目標(biāo)與拖拽容器的尺寸關(guān)系,假設(shè)拖拽目標(biāo)的尺寸是w * h,那么很容易得出的尺寸關(guān)系為:內(nèi)部尺寸是容器的2倍減去拖拽目標(biāo)的尺寸

.dragbox{ width: 100%; height: 100%;}.dragcon{ width: calc(200% - w); height: calc(200% - h);}用一張動(dòng)圖描述如下(中間的橙色塊塊表示拖拽目標(biāo))

四、CSS實(shí)現(xiàn)布局

接下來需要把這個(gè)特性加入到頁面當(dāng)中,這里列舉了兩種布局

  1. fixed 定位
現(xiàn)在直接把剛才的布局添加到頁面上,并添加fixed定位

<body> ...頁面上的其他元素 <div class=“dragbox”> <div class=“dragcon”></div> <div class=“ball”></div> <!--拖拽元素--> </div></body>關(guān)鍵樣式如下

.dragbox{ position: fixed; left: 0; top: 0; right: 0; bottom: 0; overflow: auto}層級(jí)示意關(guān)系如下

這樣一來,dragbox肯定把頁面原有的部分遮擋了,所以還需要添加pointer-events: none;同時(shí)在拖拽時(shí)添加pointer-events: all

.dragbox{ /*...*/ pointer-events: none;}.ball{ /*...*/ pointer-events: all;}.dragbox.active{ /*...*/ pointer-events: all;}借助 JS 可以在按下時(shí)觸發(fā)外層容器滾動(dòng)

ball.addEventListener('touchstart',(ev)=>{ dragbox.classList.add('active');})document.addEventListener('touchend',()=>{ dragbox.classList.remove('active');})實(shí)際效果如下

完整代碼可訪問https://codepen.io/xboxyan/pen/PobwxBK(PC訪問請(qǐng)打開移動(dòng)端模式)

也可直接掃描以下二維碼

  1. absolute 定位 + 層級(jí)
前面一種布局由于fixed定位層級(jí)的影響,不得不借助 JS 來動(dòng)態(tài)改變?nèi)萜鞯臓顟B(tài),有沒有什么辦法可以實(shí)現(xiàn)既可以拖拽,又不影響原有頁面呢?下面來看這一種布局,用到了absolute定位

這里需要對(duì)原有頁面包裹一層div容器,如下

<body> <div class=“dragbox”> <div class=“dragcon”></div> <div class=“ball”></div> </div> <div class=“body”> <!--單獨(dú)用一層實(shí)現(xiàn)頁面滾動(dòng)--> ...頁面上的其他元素 </div></body>關(guān)鍵樣式如下

.dragbox{ position: absolute; width: 100%; height: 100%; overflow: auto;}.body{ position: relative; height: 100%; overflow: auto;}.ball{ position: relative; z-index: 10; /*拖拽目標(biāo)的層級(jí)設(shè)置高一點(diǎn)*/}現(xiàn)在層級(jí)關(guān)系就變成了這樣

這里原先頁面內(nèi)容在層級(jí)上處于dragbox拖拽目標(biāo)之間,所以在拖拽時(shí)也不會(huì)影響到原有頁面的滾動(dòng),無需任何 JS 處理

完整代碼可訪問https://codepen.io/xboxyan/pen/bGBNQxL(PC訪問請(qǐng)打開移動(dòng)端模式)

也可直接掃描以下二維碼

提示:上面兩種布局方式,第一種方式適應(yīng)性更好,不影響現(xiàn)有項(xiàng)目;第二種體驗(yàn)更好,但是會(huì)使用div作為頁面滾動(dòng)容器,會(huì)對(duì)頁面結(jié)構(gòu)做一定的改動(dòng),可以根據(jù)實(shí)際情況自行選擇。

五、CSS實(shí)現(xiàn)其他功能

  1. 吸附功能
很多時(shí)候,在拖拽結(jié)束時(shí)需要讓它自動(dòng)吸附在邊緣,就如同文章開頭的示意圖一樣。那么,通過吸附,可以聯(lián)想到什么屬性呢?

答案就是CSS Scroll Snap

<body> ...頁面上的其他元素 <div class=“dragbox”> <div class=“dragcon”>A</div> <div class=“dragcon”>B</div> <div class=“ball”></div> </div></body>下面是關(guān)鍵樣式

.dragbox{ ... scroll-snap-type: x mandatory;}.dragcon{ scroll-snap-align: start;}實(shí)際效果如下

完整代碼可訪問https://codepen.io/xboxyan/pen/XWNJyPw(PC訪問請(qǐng)打開移動(dòng)端模式)

也可直接掃描以下二維碼

  1. 設(shè)置初始位置
默認(rèn)情況下,拖拽目標(biāo)是唯有右下角的,如何位于左下角呢?很簡單,這里拖拽是滾動(dòng)容器實(shí)現(xiàn)的,所以只需要改變 scrollLeft 或者 scrollTop 即可

dragbox.scrollLeft = 999;dragbox.scrollTop = 999;除此之外,也可以采用純 HTML 方式實(shí)現(xiàn),利用元素的 autofocus 自動(dòng)聚焦到可視范圍的特性

<div class=“dragcon"> ... <button class="pos" autofocus></button> <!--添加一個(gè)自動(dòng)聚焦的元素--></div>比如你希望初始位置在左上角,那么添加一個(gè)右下角的自動(dòng)聚焦元素就可以了(當(dāng)然還需要設(shè)置透明度等隱藏起來)~

  1. 設(shè)置邊界
現(xiàn)在拖拽目標(biāo)的邊界是屏幕邊緣,有時(shí)候可能需要留一些間距,這種需要在 CSS 就很容易了,可以改變left/top/right/bottom、paddingborder ...很多方式

.dragbox{ left: 10px; top: 10px; right: 10px; bottom: 10px; /*rect: 10px;*/}.dragbox{ padding: 10px;}

六、說明和小結(jié)

關(guān)于兼容性本來以為是沒什么問題的,實(shí)測(cè)下來 ios 問題多多,主要是 safari 滾動(dòng)容器的問題。例如,有些低版本 ios 滾動(dòng)不順暢,需要添-webkit-overflow-scrolling:touh,才能實(shí)現(xiàn)平滑滾動(dòng)和自動(dòng)吸附,但是又會(huì)導(dǎo)致層級(jí)問題,有些文檔上描述設(shè)置該屬性會(huì)創(chuàng)建一個(gè)原生的滾動(dòng)容器,層級(jí)最高。還有第一種 fixed 布局,如果默認(rèn)情況下設(shè)置pointer-events: none,在touchstart之后設(shè)置成auto,這個(gè)在 ios 上滾動(dòng)竟然失效了,但是反轉(zhuǎn)過來就可以了(demo中已兼容ios)。

優(yōu)點(diǎn)嘛,繼承 CSS 的靈活性,幾乎零成本,容易復(fù)用,同時(shí)利用了原生滾動(dòng),也不會(huì)有卡頓。

不過也有少許局限,如果拖拽目標(biāo)的尺寸是不固定的,可能需要借助 JS 來獲取了。當(dāng)然相比較而言,這還是一個(gè)性價(jià)比極高的實(shí)現(xiàn)方式。

現(xiàn)在回頭看看,其實(shí)也沒有用到什么非常生僻的屬性(scroll-snap 可能算一個(gè),不過畢竟是輔助功能),主要還是常見的效果,然后通過聯(lián)想和發(fā)散,根據(jù)平日的積累,充分挖掘原生的能力,最終完成所需要的交互,然后就有了本文。

感謝閱讀,希望能對(duì)日后的工作有所啟發(fā)。




本文作者:嚴(yán)文彬
原創(chuàng)聲明:本文為閱文前端團(tuán)隊(duì) YFE 成員出品,請(qǐng)尊重原創(chuàng),轉(zhuǎn)載請(qǐng)聯(lián)系公眾號(hào) ( id: yuewen_YFE ) 獲取授權(quán),并注明作者、出處和鏈接。

關(guān)鍵詞:效果,實(shí)現(xiàn)

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉