實例詳解如何給輪播圖做自適應的高度

藏色散人
發布: 2023-04-01 08:30:02
轉載
1914 人瀏覽過
這篇文章為大家帶來了關於前端的相關知識,其中主要介紹了怎麼給輪播圖做一個自適應的高度,感興趣的朋友下面一起來看一下吧,希望對大家有幫助。

不知道大家有沒有遇到這樣的需求或說看到類似的效果,就是清單進去詳情看輪播圖的時候,當手指滾動輪播圖時輪播的高度容器會自適應,這樣下面的內容就向上擠,滑動的過程會計算高度,釋放的時候也會滾到下一張,也會計算對應圖片的高度,然後做一個緩動的動畫效果。就像下面這張圖的樣子。

實例詳解如何給輪播圖做自適應的高度

可以看到上面的圖片內容文字,隨著輪播的滑動高度也在改變。費話不多說直接上代碼。

實作方法

可以透過監聽滑鼠mounse或手指的滑動touch事件來控制圖片,這裡本文只說一下輪播的功能實現思路,重點說的是怎麼實現高度的自適應。

直接開始正文,先看 html 程式碼結構。

html 結構

實例詳解如何給輪播圖做自適應的高度
實例詳解如何給輪播圖做自適應的高度
實例詳解如何給輪播圖做自適應的高度
这是一段内容
登入後複製

css 樣式

.container { width: 100%; overflow: hidden; }.wrapper { width: 100%; }.swiper { font-size: 0; white-space: nowrap; }.item { display: inline-block; width: 100%; vertical-align: top; // 一定要使用顶部对齐,不然会出现错位的情况 }.item img { width: 100%; height: auto; display: block; }.content { position: relative; z-index: 9; font-size: 14px; text-align: center; padding-top: 20px; background-color: #fff; height: 200px; }
登入後複製

值得注意的地方有幾點;

  1. #使用父級white-space時,子集元素設定display: inline-block會出現高度不同的排列錯位,解決方法就是加上一句vertical-align: top,具體什麼原因我也不細講了。
  2. 另外父級還要設定font-size: 0,如果沒加上的話,就會出現兩個子集有空隙出現,加上之後空隙就會去掉。
  3. img 圖片最好設定成高度自適應,寬度100%還要加上display: block,沒有的話底部就會出現間隙。

寫好上面的html容器部分和 樣式,下面就來看看js上是怎麼處理的。

Js 實作

開始之前我們先思考一下去怎麼實現這個輪播以及高度的自適應問題,分成幾個步驟;

  1. 滑鼠按下時,需要記錄目前的位置和一些其他初始化的訊息,並且在目前的父元素中加入對應的滑鼠事件。
  2. 滑鼠移動時,需要透過當前即時移動時點位和按下時點位的相減,得到移動的距離位置,然後再賦值給父元素設定其樣式transform位置,中間還做其他的邊界處理,當然還有高度的變化。
  3. 滑鼠釋放是,透過移動時記錄的距離資訊判斷是左滑還是右滑,拿到其對應的索引,透過索引就可以計算到滾動下一張的距離,釋放之後設定transition過渡動畫即可。

按照我們試想的思路,開始正文;

初始化資料

const data = { ele: null, width: 0, len: 0, proportion: .3, type: false, heights: [500, 250, 375], currentIndex: 0, startOffset: 0, clientX: 0, distanceX: 0, duration: 30, touching: false } const wrapper = data.ele = document.querySelector('.wrapper') const items = document.querySelectorAll('.item') data.width = wrapper.offsetWidth data.len = items.length - 1 wrapper.addEventListener('touchstart', onStart) wrapper.addEventListener('mousedown', onStart)
登入後複製

注意,這裡在做高度之前,我們需要等圖片載入完成後才能拿到每一個元素的高度,我這裡為了省懶就沒寫具體代碼,上面的heights對應的是每個圖片在渲染之後的高度,一般情況下最好讓後端傳回來頻寬高,這樣就不需要用onload再去處理這個。

滑鼠按下時

function onStart(event) { if (event.type === 'mousedown' && event.which !== 1) return if (event.type === 'touchstart' && event.touches.length > 1) return data.type = event.type === 'touchstart' const events = data.type ? event.touches[0] || event : event data.touching = true data.clientX = events.clientX data.startOffset = data.currentIndex * -data.width data.ele.style.transition = `none` window.addEventListener(data.type ? 'touchmove' : 'mousemove', onMove, { passive: false }) window.addEventListener(data.type ? 'touchend' : 'mouseup', onEnd, false) }
登入後複製

上面的程式碼裡面我做了PC和行動端的相容,跟計畫的一樣,儲存一下clientX座標和一個初始的座標startOffset這個由當前索引和父級寬度計算得到,場景是當從第二張圖片滾動到第三張圖片時,會把之前的第一張圖片的距離也要加上去,不然就計算錯誤,看下面滑動時的程式碼。

另外在做監聽移動的時候加上了passive: false是為了在行動端相容處理。

滑鼠移動時

function onMove(event) { event.preventDefault() if (!data.touching) return const events = data.type ? event.touches[0] || event : event data.distanceX = events.clientX - data.clientX let translatex = data.startOffset + data.distanceX if (translatex > 0) { translatex = translatex > 30 ? 30 : translatex } else { const d = -(data.len * data.width + 30) translatex = translatex < d ? d : translatex } data.ele.style.transform = `translate3d(${translatex}px, 0, 0)` data.ele.style.webkitTransform = `translate3d(${translatex}px, 0, 0)` }
登入後複製

做了一個邊界處理的,超了30 的距離就不讓繼續滑動了,加上之前儲存的startOffset的值,得到的就是具體移動的距離了。

滑鼠釋放時

function onEnd() { if (!data.touching) return data.touching = false // 通过计算 proportion 滑动的阈值拿到释放后的索引 if (Math.abs(data.distanceX) > data.width * data.proportion) { data.currentIndex -= data.distanceX / Math.abs(data.distanceX) } if (data.currentIndex < 0) { data.currentIndex = 0 } else if (data.currentIndex > data.len) { data.currentIndex = data.len } const translatex = data.currentIndex * -data.width data.ele.style.transition = 'all .3s ease' data.ele.style.transform = `translate3d(${translatex}px, 0, 0)` data.ele.style.webkitTransform = `translate3d(${translatex}px, 0, 0)` window.removeEventListener(data.type ? 'touchmove' : 'mousemove', onMove, { passive: false }) window.removeEventListener(data.type ? 'touchend' : 'mouseup', onEnd, false) }
登入後複製

透過計算proportion滑動的閾值拿到釋放後的索引,也就是超過父級寬度的三分之一時釋放就會捲動到下一張,拿到索引之後就可以設定需要移動的最終距離,記得加上transition做一個緩動效果,最後也別忘記移除事件的監聽。

至此上面的簡單的輪播效果就大功告成了,但是還缺少一點東西,就是本篇需要講的自適應高度,為了方便理解就單獨拿出來說一下。

高度自適應

在移動時就可以在裡面做相關的程式碼整理了,onMove函數裡加上以下程式碼,來獲取實時的高度。

const index = data.currentIndex const currentHeight = data.heights[index] // 判断手指滑动的方向拿到下一张图片的高度 let nextHeight = data.distanceX > 0 ? data.heights[index - 1] : data.heights[index + 1] let diffHeight = Math.abs((nextHeight - currentHeight) * (data.distanceX / data.width)) let realHeight = currentHeight + (nextHeight - currentHeight > 0 ? diffHeight : -diffHeight) data.ele.style.height = `${realHeight}px`
登入後複製

这里是移动时的高度变化,另外还需要在释放时也要处理,onEnd函数里加上以下代码。

// ... 因为上面已经拿到了下一张的索引 currentIndex const currentHeight = data.heights[data.currentIndex] data.ele.style.height = `${currentHeight}px`
登入後複製

因为上面已经拿到了下一张的索引currentIndex所以再滚动到下一张是就直接通过数据获取就可以了。

推荐学习:《 web前端开发视频教程

以上是實例詳解如何給輪播圖做自適應的高度的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:juejin.im
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!