Ich weiß nicht, ob Sie auf einen solchen Bedarf gestoßen sind oder einen ähnlichen Effekt gesehen haben. Das heißt, wenn Sie die Liste aufrufen und das Karussellbild im Detail betrachten, passt sich der Höhenbehälter des Karussells an, wenn Ihr Finger durch das Karussellbild scrollt , so dass der folgende Inhalt Drücken Sie ihn einfach nach oben, die Höhe wird während des Schiebevorgangs berechnet und beim Loslassen wird zum nächsten Bild gescrollt. Außerdem wird die Höhe des entsprechenden Bildes berechnet und dann ein langsamer Animationseffekt erstellt . Genau wie das Bild unten.
Sie können den Bildinhalt und den Text oben sehen und die Höhe des Karussells ändert sich, wenn das Karussell gleitet. Kommen wir ohne weitere Umschweife direkt zum Code.
Implementierungsmethode
Sie können das Bild steuern, indem Sie auf das mounse
-Ereignis mit der Maus oder das touch
-Ereignis mit dem Finger hören. In diesem Artikel geht es nur um die Implementierungsideen Bei der Karussellfunktion geht es darum, ein hohes Maß an Anpassungsfähigkeit zu erreichen. mounse
或者手指的滑动 touch
事件来控制图片,这里本文只说一下轮播的功能实现思路,重点说的是怎么实现高度的自适应。
直接开始正文,先看 html 代码结构。
html 结构
<div> <div> <div> <div> <img alt="Detailliertes Beispiel für die Anpassung der Höhe des Karusselldiagramms" > </div> <div> <img alt="Detailliertes Beispiel für die Anpassung der Höhe des Karusselldiagramms" > </div> <div> <img alt="Detailliertes Beispiel für die Anpassung der Höhe des Karusselldiagramms" > </div> </div> </div> <div>这是一段内容</div> </div>
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; }
值得注意的地方有几点;
white-space
时,子集元素设置 display: inline-block
会出现高度不同的排列错位,解决办法就是加上一句 vertical-align: top
,具体什么原因我也不细讲了。font-size: 0
,如果没加上的话,就会出现两个子集有空隙出现,加上之后空隙就会去掉。100%
还要加上 display: block
,没有的话底部就会出现间隙。写好上面的 html
容器部分和 样式,下面就看一下 js
上是怎么处理的。
Js 实现
开始之前我们先思考一下去怎么实现这个轮播以及高度的自适应问题,分为几步操作;
transform
位置,中间还做其他的边界处理,当然还有高度的变化。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`
// ... 因为上面已经拿到了下一张的索引 currentIndex const currentHeight = data.heights[data.currentIndex] data.ele.style.height = `${currentHeight}px`
white-space
werden Teilmengenelemente eingestellt code>display: inline-block führt zu einer Fehlausrichtung mit unterschiedlichen Höhen. Die Lösung besteht darin, vertical-align: top
hinzuzufügen. Auf die spezifischen Gründe werde ich nicht näher eingehen. font-size: 0
festlegen. Wenn es nicht hinzugefügt wird, entsteht eine Lücke zwischen den beiden Teilmengen wird entfernt. 100 %
und display: block
. Andernfalls wird dies der Fall sein unten eine Lücke sein. html
-Containerteil und -Stil geschrieben haben, schauen wir uns an, wie js
verarbeitet wird. 🎜🎜🎜Js Implementierung🎜🎜🎜Bevor wir beginnen, überlegen wir zunächst, wie wir dieses Karussell- und Höhenanpassungsproblem implementieren können, das in mehrere Schritte unterteilt ist. 🎜transform
fest, andere Grenzverarbeitungen werden ebenfalls in der Mitte durchgeführt, und natürlich gibt es Höhenänderungen. heights
entsprechen der Höhe jedes Bildes nach dem Rendern Im Allgemeinen ist es das Beste. Dadurch kann das Backend eine hohe Bandbreite zurückgeben, sodass keine Notwendigkeit besteht, onload
zu verwenden, um dies zu verarbeiten. 🎜clientX</ gespeichert. code > Koordinaten und eine Anfangskoordinate <code>startOffset
Dies wird aus dem aktuellen Index und der übergeordneten Breite berechnet. Das Szenario besteht darin, dass beim Scrollen vom zweiten Bild zum dritten Bild das vorherige erste Bild sein muss hinzugefügt werden, sonst ist die Berechnung falsch. Siehe den Schiebecode unten. 🎜🎜Zusätzlich wird passive: false
bei der Bewegungsüberwachung zum Zweck der Kompatibilität auf der mobilen Seite hinzugefügt. 🎜startOffset überschreitet
Der erhaltene Wert ist die spezifische zurückgelegte Distanz. 🎜Proportion
-Gleitschwellenwerts erhalten wir den Index nach dem Loslassen, der dreimal höher ist Beim Loslassen wird zum nächsten gescrollt. Nachdem Sie den Index erhalten haben, können Sie den transition
hinzufügen, um einen Beschleunigungseffekt zu erzielen Vergessen Sie am Ende der Überwachung, das Ereignis zu entfernen. 🎜🎜Jetzt ist der obige einfache Karusselleffekt abgeschlossen, aber eines fehlt noch, nämlich die adaptive Höhe, über die wir in diesem Artikel sprechen müssen. Um das Verständnis zu erleichtern, werde ich separat darauf eingehen. 🎜🎜🎜Höhenadaptiv🎜🎜🎜Sie können den entsprechenden Code darin organisieren, wenn Sie sich bewegen. Fügen Sie den folgenden Code zur Funktion onMove
hinzu, um die Echtzeithöhe zu erhalten. 🎜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
所以再滚动到下一张是就直接通过数据获取就可以了。
Das obige ist der detaillierte Inhalt vonDetailliertes Beispiel für die Anpassung der Höhe des Karusselldiagramms. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!