ここでは主にカルーセルとシームレススクロールの実装アイデアについて説明し、最も単純なカルーセルを使用します。
シンプルなカルーセルのおおよその構造は次のとおりです。中央に絵があり、両側の矢印を使用して絵を切り替えることができ、下の小さな点も絵を切り替えることができます。
1. シンプルなカルーセル効果
まず HTML 構造を構築します
ここでは左右の矢印に svg アイコンを使用しています
<div class="container">
<div class="carousel">
<div class="item"><a href=""><img src="./3.jpg" alt=""></a></div>
<div class="item"><a href=""><img src="./2.jpg" alt=""></a></div>
<div class="item"><a href=""><img src="./1.jpg" alt=""></a></div>
</div>
<div class="left">
<svg t="1693569521007" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="4000" width="20" height="20">
<path
d="M729.6 931.2l-416-425.6 416-416c9.6-9.6 9.6-25.6 0-35.2-9.6-9.6-25.6-9.6-35.2 0l-432 435.2c-9.6 9.6-9.6 25.6 0 35.2l432 441.6c9.6 9.6 25.6 9.6 35.2 0C739.2 956.8 739.2 940.8 729.6 931.2z"
p-id="4001"></path>
</svg>
</div>
<div class="right">
<svg t="1693569535119" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="4245" width="16" height="16">
<path
d="M761.6 489.6l-432-435.2c-9.6-9.6-25.6-9.6-35.2 0-9.6 9.6-9.6 25.6 0 35.2l416 416-416 425.6c-9.6 9.6-9.6 25.6 0 35.2s25.6 9.6 35.2 0l432-441.6C771.2 515.2 771.2 499.2 761.6 489.6z"
p-id="4246"></path>
</svg>
</div>
<div class="indicator">
<span class="active"></span>
<span></span>
<span></span>
</div>
</div>
そしてCSSスタイル
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 700px;
height: 400px;
margin: 10px auto;
overflow: hidden;
position: relative;
}
.container .carousel {
width: 100%;
height: 100%;
display: flex;
}
.container .carousel .item img {
width: 700px;
height: 400px;
}
.container .indicator {
height: 30px;
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
}
.container .indicator span {
border: 1px solid #fff;
width: 20px;
height: 20px;
border-radius: 50%;
display: inline-block;
}
.container .indicator span.active {
background-color: pink;
}
.container .left {
position: absolute;
left: 10px;
top: 50%;
}
.container .right {
position: absolute;
right: 10px;
top: 50%;
}
CSS のキー コードは overflow:hidden です。ここで開いたフレックス エラスティック ボックスです。これを使用して余分な画像を非表示にし、円要素の 1 つに active を追加します。
以下はjsコードです
まずすべての dom 要素を取得する必要があります
var doms = {
carousel: document.querySelector('.carousel'),
indicator: document.querySelectorAll('.indicator span'),
left: document.querySelector('.left'),
right: document.querySelector('.right')
}
最も重要なことはカルーセルの機能です
var curIndex = 0 //用于记录当前是第几个元素
function moveTo(index) {
//加上动画效果
doms.carousel.style.transition = 'transform .5s'
doms.carousel.style.transform = `translateX(-${index}00%)`
//去除效果
var active = document.querySelector('.indicator span.active')
active.classList.remove('active')
//选中当前效果
doms.indicator[index].classList.add('active')
curIndex = index
}
ここでは、transform の translationX (-100%) を使用してカルーセルの切り替えを実現するか、margin-left を使用して制御します。
次に、タイマーを追加して自動回転を制御できます。
//添加图片自动轮播
let timer = setInterval(() => {
if (curIndex === doms.indicator.length - 1) {
moveTo(0)
} else (
moveTo(curIndex + 1)
)
}, 2000)
対応するクリック イベントを下の小さな円と左右の矢印に追加することもできます。
//添加点击事件
doms.indicator.forEach((item, index) => {
item.addEventListener('click', () => {
moveTo(index)
})
})
//添加点击事件
doms.left.addEventListener('click', () => {
moveTo(curIndex-1)
})
doms.right.addEventListener('click', () => {
moveTo(curIndex+1)
})
これまでのところ、単純なカルーセル マップの基本機能は実現されていますが、完全ではなく、手ぶれ補正やシームレスなスクロール効果が必要になります。
2. シームレススクロールと手ぶれ補正
シームレスなスクロールのアイデアは、クローン作成の機能を使用し、アニメーション効果を変更して実現することです。
このように、最後のものをコピーして先頭に置きますが、まだ 1.jpg と表示されており、最初のコピーを最後に置きます
最後または最初のアニメーションに切り替えるときは、まず過剰なアニメーションをオフにしてから、すぐに過剰なアニメーションをオンにして次のアニメーションに切り替えます。これにより、速度が非常に速いため目にはそれを認識できません。
まずはクローン作成です
//克隆图片,实现无缝滚动
function clone() {
var first = doms.carousel.firstElementChild.cloneNode(true);
//复制最后一张
var last = doms.carousel.lastElementChild.cloneNode(true);
//插入到最后
doms.carousel.appendChild(first);
//插入到最前
doms.carousel.insertBefore(last, doms.carousel.firstElementChild)
//将复制的第一张的位置调整
last.style.position = 'absolute';
last.style.transform = `translateX(-100%)`
}
clone()
クローン作成の鍵は、クローンの最初の写真の位置を変更することです。
次に、右矢印のシームレスなスクロールを実現します
//实现右边的无缝滚动
var count = doms.indicator.length
function rightMove() {
//首先去除动画效果
if (curIndex === count - 1) {
doms.carousel.style.transform = `translateX(100%)`;
doms.carousel.style.transition = 'none';
//强制渲染,否则可能不会执行
doms.carousel.clientHeight;
moveTo(0)
} else {
moveTo(curIndex + 1)
}
}
右側を実装すると、左側は非常に単純になります
//实现左边的无缝滚动
function leftMove() {
if (curIndex === 0) {
doms.carousel.style.transform = `translateX(-${count}00%)`;
doms.carousel.style.transition = 'none';
//强制渲染
doms.carousel.clientHeight;
moveTo(count - 1)
} else {
moveTo(curIndex - 1)
}
}
それなら、彼が右に回転できるようにタイマーを変更する必要があります。」
//添加图片自动轮播
let timer = setInterval(() => {
rightMove()
}, 2000)
実際、私の非常に簡単な手ぶれ補正は、タイマーをオフにし、クリック タスクが完了した後にタイマーをオンにすることです。
//添加点击事件
doms.indicator.forEach((item, index) => {
item.addEventListener('click', () => {
//关闭定时器
clearInterval(timer)
moveTo(index)
//执行完后开启定时器
timer = setInterval(() => {
rightMove()
}, 2000)
})
})
左右矢印のクリックイベント
//添加点击事件
doms.left.addEventListener('click', () => {
//关闭定时器
clearInterval(timer)
leftMove()
//开启定时器
timer = setInterval(() => {
rightMove()
}, 2000)
})
doms.right.addEventListener('click', () => {
//关闭定时器
clearInterval(timer)
rightMove()
//开启定时器
timer = setInterval(() => {
rightMove()
}, 2000)
})
この時点で、単純なカルーセル画像効果が実現されます。
コード全体:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 700px;
height: 400px;
margin: 10px auto;
overflow: hidden;
position: relative;
}
.container .carousel {
width: 100%;
height: 100%;
display: flex;
/* transition: .5s; */
}
.container .carousel .item img {
width: 700px;
height: 400px;
}
.container .indicator {
height: 30px;
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
}
.container .indicator span {
/* background-color: #fff; */
border: 1px solid #fff;
width: 20px;
height: 20px;
border-radius: 50%;
display: inline-block;
}
.container .indicator span.active {
background-color: pink;
}
.container .left {
position: absolute;
left: 10px;
top: 50%;
}
.container .right {
position: absolute;
right: 10px;
top: 50%;
}
</style>
</head>
<body>
<div class="container">
<div class="carousel">
<div class="item"><a href=""><img src="./3.jpg" alt=""></a></div>
<div class="item"><a href=""><img src="./2.jpg" alt=""></a></div>
<div class="item"><a href=""><img src="./1.jpg" alt=""></a></div>
</div>
<div class="left">
<svg t="1693569521007" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="4000" width="20" height="20">
<path
d="M729.6 931.2l-416-425.6 416-416c9.6-9.6 9.6-25.6 0-35.2-9.6-9.6-25.6-9.6-35.2 0l-432 435.2c-9.6 9.6-9.6 25.6 0 35.2l432 441.6c9.6 9.6 25.6 9.6 35.2 0C739.2 956.8 739.2 940.8 729.6 931.2z"
p-id="4001"></path>
</svg>
</div>
<div class="right">
<svg t="1693569535119" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="4245" width="16" height="16">
<path
d="M761.6 489.6l-432-435.2c-9.6-9.6-25.6-9.6-35.2 0-9.6 9.6-9.6 25.6 0 35.2l416 416-416 425.6c-9.6 9.6-9.6 25.6 0 35.2s25.6 9.6 35.2 0l432-441.6C771.2 515.2 771.2 499.2 761.6 489.6z"
p-id="4246"></path>
</svg>
</div>
<div class="indicator">
<span class="active"></span>
<span></span>
<span></span>
</div>
</div>
</body>
<script>
var doms = {
carousel: document.querySelector('.carousel'),
indicator: document.querySelectorAll('.indicator span'),
left: document.querySelector('.left'),
right: document.querySelector('.right')
}
var curIndex = 0
function moveTo(index) {
//加上动画效果
doms.carousel.style.transition = 'transform .5s'
doms.carousel.style.transform = `translateX(-${index}00%)`
//去除效果
var active = document.querySelector('.indicator span.active')
active.classList.remove('active')
//选中当前效果
doms.indicator[index].classList.add('active')
curIndex = index
}
//添加点击事件
doms.indicator.forEach((item, index) => {
item.addEventListener('click', () => {
//关闭定时器
clearInterval(timer)
moveTo(index)
//执行完后开启定时器
timer = setInterval(() => {
rightMove()
}, 2000)
})
})
//添加图片自动轮播
let timer = setInterval(() => {
rightMove()
}, 2000)
//克隆图片,实现无缝滚动
function clone() {
var first = doms.carousel.firstElementChild.cloneNode(true);
//复制最后一张
var last = doms.carousel.lastElementChild.cloneNode(true);
//插入到最后
doms.carousel.appendChild(first);
//插入到最前
doms.carousel.insertBefore(last, doms.carousel.firstElementChild)
//将复制的第一张的位置调整
last.style.position = 'absolute';
last.style.transform = `translateX(-100%)`
}
clone()
//实现右边的无缝滚动
var count = doms.indicator.length
function rightMove() {
//首先去除动画效果
if (curIndex === count - 1) {
doms.carousel.style.transform = `translateX(100%)`;
doms.carousel.style.transition = 'none';
//强制渲染
doms.carousel.clientHeight;
moveTo(0)
} else {
moveTo(curIndex + 1)
}
}
//实现左边的无缝滚动
function leftMove() {
if (curIndex === 0) {
doms.carousel.style.transform = `translateX(-${count}00%)`;
doms.carousel.style.transition = 'none';
//强制渲染
doms.carousel.clientHeight;
moveTo(count - 1)
} else {
moveTo(curIndex - 1)
}
}
//添加点击事件
doms.left.addEventListener('click', () => {
//关闭定时器
clearInterval(timer)
leftMove()
//开启定时器
timer = setInterval(() => {
rightMove()
}, 2000)
})
doms.right.addEventListener('click', () => {
//关闭定时器
clearInterval(timer)
rightMove()
//开启定时器
timer = setInterval(() => {
rightMove()
}, 2000)
})
</script>
</html>