黄坏坏 2022-02-18 23:32 采纳率: 0%
浏览 54
已结题

Flex布局下使用translate3移动的轮播图无法平缓过渡且移动端无法滑动

我打算写一个平滑过渡的轮播图,但是这里出现了一个小问题,从最后一个图片返回第一个图片的时候居然重头返回再进行过渡,并且在移动端时无法通过拖动来进行切换

HTML代码,滑动用的transform的translate3d实现的,用了Bootstrap5的框架

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rTTiRUKnSWaDu2FjhzWFl8/JuUZMlplyWE/djenb2LoKqkgLGfEGfSrL7XDLoB1M" crossorigin="anonymous">
<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;
    margin-right: -30px;
    cursor: grab;
    cursor: -webkit-grab;
    user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    -moz-user-select: none;
}
.slider-inner .slider-item{
    width: 50%;
    flex-shrink: 0;
    padding-right: 30px;
}
@media (max-width: 767.98px){
    .slider-outer .slider-inner{
        margin-right: 0;
    }
    .slider-inner .slider-item{
        width: 100%;
        padding-right: inherit;
    }
}
.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{
    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代码

/* 滑动图 */
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 isImgDrag = false;

//让第一张图片于首位
window.onload = function() {
    slideContainer.style.transform = "translate3d(-" + (slideIndex * sliderItemWidth) + "px, 0, 0)";
}
//滑动
function slideByDots() {
    slideContainer.style.transform = "translate3d(-" + (slideIndex * sliderItemWidth) + "px, 0, 0)";
    slideContainer.style.transitionDuration= ".3s";
    dotsContainer.querySelector(".active").classList.remove("active");
    dots[slideIndex-1].classList.add("active");
}
function slideByDrag(index, duration = ".3s") {
    currentOffset = index * sliderItemWidth;
    slideContainer.style.transform = "translate3d(-" + currentOffset + "px, 0, 0)";
    slideContainer.style.transitionDuration= duration;
    dotsContainer.querySelector(".active").classList.remove("active");
    //
    if(index > dots.length){
    index = 1;
    }
    dots[index - 1].classList.add("active");
}
//点击小点
for (let dot of dots) {
    dot.addEventListener("click", function(e) {
    slideIndex = parseInt(e.target.dataset.to) + 1;
    slideByDots();
    })
}
//鼠标拖动
slideContainer.onmousedown = function(e) {
    isMouseDown = true;
    moveDistant = e.clientX;
    currentOffset = slideIndex * sliderItemWidth;
}
slideContainer.onmousemove = function(e) {
    isImgDrag = true;
    if(isMouseDown){
    this.style.transform = "translate3d(-" +(currentOffset + moveDistant-e.clientX)+ "px, 0, 0)";
    }
}
slideContainer.onmouseup = function(e) {
    isMouseDown = false;
    isImgDrag = false;
    if(e.clientX - moveDistant <= 60){//next
    slideIndex++;
    if(slideIndex > sliderItemNum - 2){
        slideIndex = 1;
        slideContainer.style.transitionDuration = "0s";
        slideContainer.style.transform = "translate3d(-"+ (slideIndex-1)*sliderItemWidth +"px, 0, 0)";
    }
    slideByDrag(slideIndex);
    }else if (e.clientX - moveDistant >= 60) {//prev
    slideIndex--;
    if(slideIndex < 1){
        slideIndex = sliderItemNum - 2;
        slideContainer.style.transform = "translate3d(-"+ (slideIndex-1)*sliderItemWidth +"px, 0, 0)";
        slideContainer.style.transitionDuration = "0s";
    }
    slideByDrag(slideIndex);
    }else {
    slideByDrag(slideIndex);
    }
    
}
//禁止超链接拖拽和跳转
let slideLinks = slideContainer.querySelectorAll(".slider-item > a");
for ( let slideImg of slideLinks) {
    slideImg.ondragstart = function() {
    return false;
    }
}
for (let slideLink of slideLinks) {
    slideLink.addEventListener("click", function(e) {
    if(isImgDrag){
        e.preventDefault();
    }
    })
}
  • 写回答

2条回答 默认 最新

  • 黄坏坏 2022-02-20 14:26
    关注

    问题解决了,首先是无法平缓的从最后一个过渡到第一个的问题
    由于在设置了

    slideContainer.style.transform = "translate3d(-"+ (slideIndex-1)*sliderItemWidth +"px, 0, 0)";
    

    且之后的slide()里同样会有设置transform样式因此直接覆盖掉了,解决方法可以设置一个回调函数或者设置一个定时器,延迟10ms在执行就不会有这样的问题了

    之后就是移动端的不会像PC端可以滑动切换图片
    首先PC端的onmousedown、onmousemove和onmouseup在移动端并不可以共用,由于移动端使用的是触摸所以相对而言要使用ontouchstart、ontouchmove和ontouchend

    评论

报告相同问题?

问题事件

  • 系统已结题 2月26日
  • 修改了问题 2月19日
  • 修改了问题 2月19日
  • 创建了问题 2月18日

悬赏问题

  • ¥15 vs2019的js智能提示
  • ¥15 关于#开发语言#的问题:FDTD建模问题图中代码没有报错,但是模型却变透明了
  • ¥15 uniapp的h5项目写一个抽奖动画
  • ¥15 TeleScan不能修改bar
  • ¥100 请问我基于逐飞库写的这个有关于mp u6050传感器的函数,为什么输出的值是固定的?
  • ¥15 hadoop中启动hive报错如下怎么解决
  • ¥15 如何优化QWebEngineView 加载url的速度
  • ¥15 关于#hadoop#的问题,请各位专家解答!
  • ¥15 如何批量抓取网站信息
  • ¥15 Spring Boot离线人脸识别