0
点赞
收藏
分享

微信扫一扫

制作可以鼠标滑动的轮播图,支持移动端(利用Bootstrap5布置其样式)

最近一直在研究Bootstrap5的前端开发,看bootstrap例子的时候发现了一个好的模型,所以就手痒给自己写了一个

PC端

移动端

先简单的介绍一些吧,支持移动端和PC端的拖动且由最后一张图切到第一张图的时候是平滑过渡,不会在掉头过渡

OK,下面那直接放代码,切记如果要直接用的话注意要在头部加一个Bootstrap5的CSS代码引入

<div class="slider">
				<div class="slider-indicators">
					<button class="active" data-to="0" tabindex="-1"></button>
					<button data-to="1" tabindex="-1"></button>
					<button data-to="2" tabindex="-1"></button>
				</div>
				<div class="slider-outer">
					<div class="slider-inner">
						<div class="slider-item">
							<a href="">
								<img src="https://around.createx.studio/img/demo/food-blog/videos/03.jpg" loading="lazy">
								<span>Gallery video caption</span>
							</a>
						</div>
						<div class="slider-item">
							<a href="">
								<img src="https://around.createx.studio/img/demo/food-blog/videos/01.jpg" loading="lazy">
								<span>Gallery video caption</span>
							</a>
						</div>
						<div class="slider-item">
							<a href="">
								<img src="https://around.createx.studio/img/demo/food-blog/videos/02.jpg" loading="lazy">
								<span>Gallery video caption</span>
							</a>
						</div>
						<div class="slider-item">
							<a href="#">
								<img src="https://around.createx.studio/img/demo/food-blog/videos/03.jpg" loading="lazy">
								<span>Gallery video caption</span>
							</a>
						</div>
						<div class="slider-item">
							<a href="#">
								<img src="https://around.createx.studio/img/demo/food-blog/videos/01.jpg" loading="lazy">
								<span>Gallery video caption</span>
							</a>
            </div>
        </div>
    </div>
</div>

CSS代码

.slider{
	position: relative;
}
.slider .slider-indicators{
	position: absolute;
	top: 100%;
	width: 100%;
	padding-top: 1rem;
	text-align: center;
	white-space: nowrap;
}
[data-to] {
	display: inline-block;
	position: relative;
	width: .75rem;
	height: .75rem;
	margin: 0 .25rem;
	padding: 0;
	border: 0;
	background: none;
	outline: none;
}
[data-to].active:before{
	opacity: 0;
}
[data-to]:before {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: .375rem;
	height: .375rem;
	margin-top: -.1875rem;
	margin-left: -.1875rem;
	border-radius: 50%;
	background-color: var(--bs-indigo);
	transition: .2s ease-in-out;
}
[data-to]:after {
	content: '';
	position: absolute;
	top: 0;
	left: 0;
	width: .75rem;
	height: .75rem;
	border: .125rem solid var(--bs-indigo);
	border-radius: 50%;
	opacity: 0;
	transform: scale(.5);
	transition: .2s ease-in-out;
}
[data-to].active:after {
	opacity: 1;
	transform: scale(1);
}
.slider .slider-outer{
	position: relative;
	overflow: hidden;
}
.slider-outer .slider-inner{
	display: flex;
	cursor: grab;
	cursor: -webkit-grab;
	user-select: none;
	-webkit-user-select: none;
	-ms-user-select: none;
	-moz-user-select: none;
	transform: translate3d(-50%, 0, 0);
}
.slider-inner .slider-item{
	width: 50%;
	flex-shrink: 0;
	padding-right: 30px;
}
@media (max-width: 767.98px){
	.slider-outer .slider-inner{
		transform: translate3d(-100%, 0, 0);
		margin-right: -16px;
	}
	.slider-inner .slider-item{
		width: 100%;
		padding-right: 16px;
	}
}
.slider-item a{
	display: block;
	position: relative;
	width: 100%;
	border-radius: 1rem;
	overflow: hidden;
}
.slider-item a:before {
	content: '';
	display: block;
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background-color: rgba(55,56,78,.55);
	opacity: 0;
	transition: opacity .3s ease-in-out;
}
.slider-item a:hover:before{
	opacity: 1;
}
.slider-item a > img{
	display: block;
	width: 100%;
}
.slider-item a > span {
	display: block;
	position: absolute;
	left: 0;
	bottom: 0;
	width: 100%;
	padding: 1rem .5rem;
	color: white;
	font-size: .875rem;
	text-align: center;
	opacity: 0;
	transform: translateY(0.5rem);
	transition: .3s ease-in-out;
}
.slider-item a:hover > span{
	transform: none;
	opacity: 1;
}

JS代码,代码也就100来行,所以就没有封装

/* 滑动图 */
var dotsContainer = document.getElementsByClassName("slider-indicators")[0];
var dots = dotsContainer.getElementsByTagName("button");
var slideContainer = document.querySelector(".slider-inner");
var sliderItem = slideContainer.querySelectorAll(".slider-item");
var sliderItemNum = sliderItem.length;
var sliderItemWidth = sliderItem[0].offsetWidth;

let slideIndex = 1, moveDistant = 0, currentOffset;
let isMouseDown = false;
let isSlideDrag = false;

//小点被点击
for (let dot of dots) {
    dot.onclick = function(e) {
	slideIndex = Number(e.target.dataset.to) + 1;
	slide();
    }
}
//PC端——拖动移动图片
slideContainer.parentNode.onmousedown = function(e) {
    isMouseDown = true;
    moveDistant = e.clientX;
    currentOffset = slideIndex * sliderItemWidth;
}
slideContainer.parentNode.onmousemove= function(e) {
    if(isMouseDown){
	isSlideDrag = true;
	slideContainer.style.transform = "translate3d(-"+ (currentOffset+moveDistant-e.clientX) +"px, 0, 0)";
    }
}
slideContainer.parentNode.onmouseup = function(e) {
    isMouseDown = false;
    isSlideDrag = false;
    if(e.clientX - moveDistant < -60){//next
	slideIndex++;
	if(slideIndex > sliderItemNum - 2){
	    slideIndex = 1;
	    slideContainer.style.transform = "translate3d(0, 0, 0)";
	    slideContainer.style.transition = "0s";
	    setTimeout(slide, 15);
	    return;
	}
	slide();
    }else if (e.clientX - moveDistant > 60) {//prev
	slideIndex--;
	if(slideIndex == 0){
	    dotsContainer.querySelector("button.active").classList.remove("active");
	    dots[sliderItemNum - 3].classList.add("active");
	    slideContainer.style.transform = "translate3d(-"+(slideIndex*sliderItemWidth)+"px, 0, 0)";
	    slideContainer.style.transition = "all .3s";
	    return;
	}else if (slideIndex < 0) {
	    slideIndex = sliderItemNum - 3;
	    slideContainer.style.transform = "translate3d(-"+((slideIndex+1)*sliderItemWidth)+"px, 0, 0)";
	    slideContainer.style.transition = "0s";
	    setTimeout(slide, 15);
	    return;
	}
	slide();
    }else {
	slide();
    }
}
//滑动效果
function slide() {
    dotsContainer.querySelector("button.active").classList.remove("active");
    dots[slideIndex - 1].classList.add("active");
    slideContainer.style.transform = "translate3d(-"+ (slideIndex*sliderItemWidth) +"px, 0, 0)";
    slideContainer.style.transition = "all .3s";
}
//避免超链接影响拖动
let slideLinks = slideContainer.querySelectorAll(".slider-item > a");
for (let slideLink of slideLinks) {
    slideLink.ondragstart = function(e) {
	e.preventDefault();
    }
    slideLink.onclick = function() {
	if(isSlideDrag){
	    e.preventDefault();
	}
    }
}

//移动端拖动
slideContainer.parentNode.ontouchstart = function(e) {
    isMouseDown = true;
    moveDistant = e.touches[0].clientX;
    currentOffset = slideIndex * sliderItemWidth;
}
slideContainer.parentNode.ontouchmove= function(e) {
    if(isMouseDown){
	e.preventDefault();
	isSlideDrag = true;
	slideContainer.style.transform = "translate3d(-"+ (currentOffset+moveDistant-e.touches[0].clientX) +"px, 0, 0)";
    }
}
slideContainer.parentNode.ontouchend = function(e) {
    isMouseDown = false;
    isSlideDrag = false;
    if(e.changedTouches[0].clientX - moveDistant < -60){//next
	slideIndex++;
	if(slideIndex > sliderItemNum - 2){
	    slideIndex = 1;
	    slideContainer.style.transform = "translate3d(0, 0, 0)";
	    slideContainer.style.transition = "0s";
	    setTimeout(slide, 15);
	    return;
	}
	slide();
    }else if (e.changedTouches[0].clientX - moveDistant > 60) {//prev
	slideIndex--;
	if(slideIndex == 0){
	    dotsContainer.querySelector("button.active").classList.remove("active");
	    dots[sliderItemNum - 3].classList.add("active");
	    slideContainer.style.transform = "translate3d(-"+(slideIndex*sliderItemWidth)+"px, 0, 0)";
	    slideContainer.style.transition = "all .3s";
	    return;
	}else if (slideIndex < 0) {
	    slideIndex = sliderItemNum - 3;
	    slideContainer.style.transform = "translate3d(-"+((slideIndex+1)*sliderItemWidth)+"px, 0, 0)";
	    slideContainer.style.transition = "0s";
	    setTimeout(slide, 15);
	    return;
	}
	slide();
    }else {
	slide();
    }
}
举报

相关推荐

0 条评论