Slide image vanish before making the transition.

huangapple go评论74阅读模式
英文:

Slide image vanish before making the transition

问题

I have an image slider with 4 images. To navigate between them there are 2 ways: 2 buttons in the corners of the slider and a small slider indicator to choose an image represented as dots in the bottom of the slider.

每个滑块都有一个 transition 属性,持续时间为 0.6秒,如下所示:

.carousel-inner > .item {
    background-size: cover;
    background-repeat: no-repeat;
    height: 470px;
    position: relative;
    display: none;
    -webkit-transition: .6s ease-in-out left;
    transition: .6s ease-in-out left;
}

What I would like to do is navigate between these images smoothly with a transition effect, so if I choose an image that is located after the selected one both will move to the left and if the image is in the is before the selected one both the imager move to the right.

我想要实现的效果是平滑地在这些图像之间导航,如果我选择的图像在当前选定的图像之后,它们将一起向左移动,如果图像在当前选定的图像之前,它们将一起向右移动。

The effect that I am looking for is precisely like this one.

我正在寻找的效果与这个非常相似。

英文:

I have an image slider with 4 images. To navigate between them there are 2 ways: 2 buttons in the corners of the slider and a small slider indicator to choose an image represented as dots in the bottom of the slider.

Each slider has a transition property of 0.6s as follows :

.carousel-inner > .item {
    background-size: cover;
    background-repeat: no-repeat;
    height: 470px;
    position: relative;
    display: none;
    -webkit-transition: .6s ease-in-out left;
    transition: .6s ease-in-out left;
}

What I would like to do is navigate between these images smoothly with a transition effect, so if I choose an image that is located after the selected one both will move to the left and if the image is in the is before the selected one both the imager move to the right.

The effect that I am looking for is precisely like this one.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let slideIndex = 1;

console.log(&quot;fdsf&quot;);

function showSlide(n) {
    let slides = document.querySelectorAll(&quot;.carousel-inner &gt; .item&quot;);
    let dots = document.querySelectorAll(&quot;.carousel-indicators li&quot;);
    dots[slideIndex - 1].classList.remove(&quot;active&quot;);

    if (n &gt; slides.length) {
        slideIndex = 1;
    } else if (n &lt; 1) {
        slideIndex = slides.length;
    } else {
        slideIndex = n;
    }

    const activeSlide = document.querySelector(&quot;.carousel-inner &gt; .item.active&quot;);

    activeSlide.classList.add(&quot;left&quot;);
    activeSlide.classList.remove(&quot;active&quot;);

    slides[slideIndex - 1].style.left = &quot;100%&quot;;

    slides[slideIndex - 1].classList.add(&quot;active&quot;);
    slides[slideIndex - 1].classList.add(&quot;left&quot;);

    slides[slideIndex - 1].classList.add(&quot;next&quot;);
    slides[slideIndex - 1].classList.add(&quot;left&quot;);

    activeSlide.classList.remove(&quot;active&quot;);
    activeSlide.classList.remove(&quot;left&quot;);

    slides[slideIndex - 1].classList.remove(&quot;next&quot;);
    slides[slideIndex - 1].classList.add(&quot;active&quot;);
    slides[slideIndex - 1].classList.remove(&quot;left&quot;);

    dots[slideIndex - 1].classList.add(&quot;active&quot;);
}


$(&quot;.carousel-indicators li&quot;).on(&quot;click&quot;, function () {
    showSlide(parseInt(this.getAttribute(&quot;data-slide-to&quot;)) + 1)
})

<!-- language: lang-css -->

.carousel {
    position: relative;
}

@media screen and (min-width: 768px) {
    .carousel-indicators {
        bottom: 20px;
    }
}

.carousel-indicators {
    position: absolute;
    bottom: 10px;
    left: 50%;
    z-index: 15;
    width: 60%;
    padding-left: 0;
    margin-left: -30%;
    text-align: center;
    list-style: none;
}

ul, ol {
    margin-top: 0;
    margin-bottom: 10px;
}

.carousel-indicators li {
    display: inline-block;
    width: 10px;
    height: 10px;
    margin: 1px;
    text-indent: -999px;
    cursor: pointer;
    background-color: #000 ;
    background-color: rgba(0, 0, 0, 0);
    border: 1px solid #fff;
    border-radius: 10px;
}

.carousel-indicators .active {
    width: 12px;
    height: 12px;
    margin: 0;
    background-color: #fff;
}

.carousel-inner {
    position: relative;
    width: 100%;
    overflow: hidden;
}

.carousel-inner &gt; .item.slide1 {
    background-position: center 10%;
}

.carousel-inner &gt; .item {
    background-size: cover;
    background-repeat: no-repeat;
    height: 470px;
    position: relative;
    display: none;
    -webkit-transition: .6s ease-in-out left;
    transition: .6s ease-in-out left;
}

.carousel-inner &gt; .next, .carousel-inner &gt; .prev {
    position: absolute;
    top: 0;
    width: 100%
}

.carousel-inner &gt; .next {
    left: 100%
}

.carousel-inner &gt; .prev {
    left: -100%
}

.carousel-inner &gt; .next.left, .carousel-inner &gt; .prev.right {
    left: 0
}

.carousel-inner &gt; .active.left {
    left: -100%
}

.carousel-inner &gt; .active.right {
    left: 100%
}

.carousel-inner &gt; .active {
    left: 0;
}

.carousel-inner &gt; .active, .carousel-inner &gt; .next, .carousel-inner &gt; .prev {
    display: block;
}

.carousel-control.left {
    background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001)));
    background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0), color-stop(rgba(0, 0, 0, 0.0001) 100%));
    background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%);
    background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%);
    background-repeat: repeat-x;
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=&#39;#80000000&#39;, endColorstr=&#39;#00000000&#39;, GradientType=1);
}

.carousel-control.right {
    right: 0;
    left: auto;
    background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5)));
    background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0), color-stop(rgba(0, 0, 0, 0.5) 100%));
    background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%);
    background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%);
    background-repeat: repeat-x;
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=&#39;#00000000&#39;, endColorstr=&#39;#80000000&#39;, GradientType=1);
}

.carousel-control {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 15%;
    font-size: 20px;
    color: #fff;
    text-align: center;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
    opacity: .5;
    filter: alpha(opacity=50);
}

.carousel-control .icon-prev, .carousel-control .glyphicon-chevron-left {
    left: 50%;
}

.carousel-control .icon-prev, .carousel-control .icon-next, .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right {
    position: absolute;
    top: 50%;
    z-index: 5;
    display: inline-block;
}

.glyphicon-chevron-left::before {
    content: url(../images/icons/left-arrow.png);
    border-radius: 50%;
    border: 1px solid white;
    display: block;
    width: 100%;
    height: 100%;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}


.carousel-control .icon-next, .carousel-control .glyphicon-chevron-right {
    right: 50%;
}

.carousel-control .icon-prev, .carousel-control .icon-next, .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right {
    position: absolute;
    top: 50%;
    z-index: 5;
    display: inline-block;
}

.glyphicon:empty {
    width: 1em;
}

.glyphicon-chevron-right::before {
    content: url(../images/icons/right-arrow.png);
    border-radius: 50%;
    border: 1px solid white;
    display: block;
    width: 100%;
    height: 100%;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}

<!-- language: lang-html -->

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;script src=&quot;https://code.jquery.com/jquery-3.7.0.min.js&quot; integrity=&quot;sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;myCarousel&quot; class=&quot;carousel slide&quot; data-ride=&quot;carousel&quot;&gt;
      &lt;ol class=&quot;carousel-indicators&quot;&gt;
        &lt;li data-target=&quot;#myCarousel&quot; data-slide-to=&quot;0&quot; class=&quot;active&quot;&gt;&lt;/li&gt;
        &lt;li data-target=&quot;#myCarousel&quot; data-slide-to=&quot;1&quot; class=&quot;&quot;&gt;&lt;/li&gt;
        &lt;li data-target=&quot;#myCarousel&quot; data-slide-to=&quot;2&quot; class=&quot;&quot;&gt;&lt;/li&gt;
        &lt;li data-target=&quot;#myCarousel&quot; data-slide-to=&quot;3&quot; class=&quot;&quot;&gt;&lt;/li&gt;
      &lt;/ol&gt;

      &lt;div class=&quot;carousel-inner&quot;&gt;
        &lt;div
          class=&quot;item slide1 active&quot;
          style=&quot;
            background-image: url(https://upload.wikimedia.org/wikipedia/commons/1/15/Cat_August_2010-4.jpg);
            background-size: cover;
            background-repeat: no-repeat;
          &quot;
        &gt;
          &lt;div id=&quot;page-header-tagline&quot; class=&quot;tagline1&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;

        &lt;div
          class=&quot;item slide2&quot;
          style=&quot;
            background-image: url(https://static.toiimg.com/thumb/msid-67586673,width-1070,height-580,imgsize-3918697,resizemode-6,overlay-toi_sw,pt-32,y_pad-40/photo.jpg);
            background-size: cover;
            background-repeat: no-repeat;
          &quot;
        &gt;
          &lt;div id=&quot;page-header-tagline&quot; class=&quot;tagline2&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;

        &lt;div
          class=&quot;item slide3&quot;
          style=&quot;
            background-image: url(https://upload.wikimedia.org/wikipedia/commons/1/15/Cat_August_2010-4.jpg);
            background-size: cover;
            background-repeat: no-repeat;
          &quot;
        &gt;
          &lt;div id=&quot;page-header-tagline&quot; class=&quot;tagline3&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;

        &lt;div
          class=&quot;item slide4&quot;
          style=&quot;
            background-image: url(https://static.toiimg.com/thumb/msid-67586673,width-1070,height-580,imgsize-3918697,resizemode-6,overlay-toi_sw,pt-32,y_pad-40/photo.jpg);
            background-size: cover;
            background-repeat: no-repeat;
          &quot;
        &gt;
          &lt;div id=&quot;page-header-tagline&quot; class=&quot;tagline4&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;a class=&quot;carousel-control left&quot; href=&quot;#myCarousel&quot; data-slide=&quot;prev&quot;&gt;
        &lt;span class=&quot;glyphicon glyphicon-chevron-left&quot;&gt;&lt;/span&gt;
      &lt;/a&gt;

      &lt;a class=&quot;carousel-control right&quot; href=&quot;#myCarousel&quot; data-slide=&quot;next&quot;&gt;
        &lt;span class=&quot;glyphicon glyphicon-chevron-right&quot;&gt;&lt;/span&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

答案1

得分: 1

使用requestAnimationFrame而不是setTimeout。更具体地说,使用双重requestAnimationFrame,这使我们可以等待浏览器绘制下一帧并在发生后执行操作。这样,您不必猜测等待display: block被浏览器绘制的时间。

对于第二个超时,也是如此,但在那里您希望在过渡完成后执行某些操作。您可以通过侦听transitionend事件来更精确地实现这一点。并且为了确保事件仅在每次幻灯片更改时侦听一次,将{ once: true }作为选项参数添加到addEventListener

我在滑块上添加了一个标志isAnimating,表示滑块正在移动,并且在动画完成之前不应执行任何操作。

以下是代码部分的翻译:

let slideIndex = 1;
let isAnimating = false;

function afterNextRepaint(callback) {
  if (typeof callback !== 'function') {
    return;
  }

  requestAnimationFrame(() => {
    requestAnimationFrame(() => {
      callback();
    });
  });
}

function showSlide(n) {
  if (isAnimating || slideIndex === n) {
    return;
  }

  let slides = document.querySelectorAll(".carousel-inner > .item");
  let dots = document.querySelectorAll(".carousel-indicators li");
  dots[slideIndex - 1].classList.remove("active");

  if (n > slides.length) {
    slideIndex = 1;
  } else if (n < 1) {
    slideIndex = slides.length;
  } else {
    slideIndex = n;
  }

  isAnimating = true;

  const activeSlide = document.querySelector(".carousel-inner > .item.active");
  const nextSlide = slides[slideIndex - 1];
  const nextDot = dots[slideIndex - 1];

  nextSlide.classList.add("next");

  afterNextRepaint(() => {
    activeSlide.classList.add("left");
    nextSlide.classList.add("left");
  });

  nextSlide.addEventListener('transitionend', () => {
    nextSlide.classList.add("active");

    activeSlide.classList.remove("left");
    activeSlide.classList.remove("active");

    nextSlide.classList.remove("next");
    nextSlide.classList.remove("left");

    nextDot.classList.add("active");

    isAnimating = false;
  }, { once: true });
}

$(".carousel-indicators li").on("click", function() {
  showSlide(parseInt(this.getAttribute("data-slide-to")) + 1)
})

这些是代码的关键部分的翻译,其他部分保持不变。

英文:

Instead of using setTimeout, use requestAnimationFrame. More specifically a double requestAnimationFrame which enables us to wait for the browser to paint the next frame and do something after that happens. This way you don't have to guess the time to wait until display: block has been painted by the browser.

Same goes for the second timeout, but there you want to do something after the transition has finished. You can accomplish this more accurately by listening to the transitionend event. And to make sure that the event is only listened to once per slide change, add { once: true } as options param to addEventListener.

I took the liberty to add a flag isAnimating to the slider to indicate that the slider is moving and nothing should happen until the animation is finished.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let slideIndex = 1;
let isAnimating = false;
function afterNextRepaint(callback) {
if (typeof callback !== &#39;function&#39;) {
return;
}
requestAnimationFrame(() =&gt; {
requestAnimationFrame(() =&gt; {
callback();
});
});
}
function showSlide(n) {
if (isAnimating || slideIndex === n) {
return;
}
let slides = document.querySelectorAll(&quot;.carousel-inner &gt; .item&quot;);
let dots = document.querySelectorAll(&quot;.carousel-indicators li&quot;);
dots[slideIndex - 1].classList.remove(&quot;active&quot;);
if (n &gt; slides.length) {
slideIndex = 1;
} else if (n &lt; 1) {
slideIndex = slides.length;
} else {
slideIndex = n;
}
isAnimating = true;
const activeSlide = document.querySelector(&quot;.carousel-inner &gt; .item.active&quot;);
const nextSlide = slides[slideIndex - 1];
const nextDot = dots[slideIndex - 1];
nextSlide.classList.add(&quot;next&quot;);
afterNextRepaint(() =&gt; {
activeSlide.classList.add(&quot;left&quot;);
nextSlide.classList.add(&quot;left&quot;);
});
nextSlide.addEventListener(&#39;transitionend&#39;, () =&gt; {
nextSlide.classList.add(&quot;active&quot;);
activeSlide.classList.remove(&quot;left&quot;);
activeSlide.classList.remove(&quot;active&quot;);
nextSlide.classList.remove(&quot;next&quot;);
nextSlide.classList.remove(&quot;left&quot;);
nextDot.classList.add(&quot;active&quot;);
isAnimating = false;
}, { once: true });
}
$(&quot;.carousel-indicators li&quot;).on(&quot;click&quot;, function() {
showSlide(parseInt(this.getAttribute(&quot;data-slide-to&quot;)) + 1)
})

<!-- language: lang-css -->

.carousel {
position: relative;
}
@media screen and (min-width: 768px) {
.carousel-indicators {
bottom: 20px;
}
}
.carousel-indicators {
position: absolute;
bottom: 10px;
left: 50%;
z-index: 15;
width: 60%;
padding-left: 0;
margin-left: -30%;
text-align: center;
list-style: none;
}
ul,
ol {
margin-top: 0;
margin-bottom: 10px;
}
.carousel-indicators li {
display: inline-block;
width: 10px;
height: 10px;
margin: 1px;
text-indent: -999px;
cursor: pointer;
background-color: #000 \9;
background-color: rgba(0, 0, 0, 0);
border: 1px solid #fff;
border-radius: 10px;
}
.carousel-indicators .active {
width: 12px;
height: 12px;
margin: 0;
background-color: #fff;
}
.carousel-inner {
position: relative;
width: 100%;
overflow: hidden;
}
.carousel-inner&gt;.item.slide1 {
background-position: center 10%;
}
.carousel-inner&gt;.item {
background-size: cover;
background-repeat: no-repeat;
height: 470px;
position: relative;
display: none;
-webkit-transition: .6s ease-in-out left;
transition: .6s ease-in-out left;
}
.carousel-inner&gt;.next,
.carousel-inner&gt;.prev {
position: absolute;
top: 0;
width: 100%
}
.carousel-inner&gt;.next {
left: 100%
}
.carousel-inner&gt;.prev {
left: -100%
}
.carousel-inner&gt;.next.left,
.carousel-inner&gt;.prev.right {
left: 0
}
.carousel-inner&gt;.active.left {
left: -100%
}
.carousel-inner&gt;.active.right {
left: 100%
}
.carousel-inner&gt;.active {
left: 0;
}
.carousel-inner&gt;.active,
.carousel-inner&gt;.next,
.carousel-inner&gt;.prev {
display: block;
}
.carousel-control.left {
background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001)));
background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0), color-stop(rgba(0, 0, 0, 0.0001) 100%));
background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%);
background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=&#39;#80000000&#39;, endColorstr=&#39;#00000000&#39;, GradientType=1);
}
.carousel-control.right {
right: 0;
left: auto;
background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5)));
background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0), color-stop(rgba(0, 0, 0, 0.5) 100%));
background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%);
background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=&#39;#00000000&#39;, endColorstr=&#39;#80000000&#39;, GradientType=1);
}
.carousel-control {
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 15%;
font-size: 20px;
color: #fff;
text-align: center;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
opacity: .5;
filter: alpha(opacity=50);
}
.carousel-control .icon-prev,
.carousel-control .glyphicon-chevron-left {
left: 50%;
}
.carousel-control .icon-prev,
.carousel-control .icon-next,
.carousel-control .glyphicon-chevron-left,
.carousel-control .glyphicon-chevron-right {
position: absolute;
top: 50%;
z-index: 5;
display: inline-block;
}
.glyphicon-chevron-left::before {
content: url(../images/icons/left-arrow.png);
border-radius: 50%;
border: 1px solid white;
display: block;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
.carousel-control .icon-next,
.carousel-control .glyphicon-chevron-right {
right: 50%;
}
.carousel-control .icon-prev,
.carousel-control .icon-next,
.carousel-control .glyphicon-chevron-left,
.carousel-control .glyphicon-chevron-right {
position: absolute;
top: 50%;
z-index: 5;
display: inline-block;
}
.glyphicon:empty {
width: 1em;
}
.glyphicon-chevron-right::before {
content: url(../images/icons/right-arrow.png);
border-radius: 50%;
border: 1px solid white;
display: block;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}

<!-- language: lang-html -->

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot; /&gt;
&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
&lt;script src=&quot;https://code.jquery.com/jquery-3.7.0.min.js&quot; integrity=&quot;sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
&lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;myCarousel&quot; class=&quot;carousel slide&quot; data-ride=&quot;carousel&quot;&gt;
&lt;ol class=&quot;carousel-indicators&quot;&gt;
&lt;li data-target=&quot;#myCarousel&quot; data-slide-to=&quot;0&quot; class=&quot;active&quot;&gt;&lt;/li&gt;
&lt;li data-target=&quot;#myCarousel&quot; data-slide-to=&quot;1&quot; class=&quot;&quot;&gt;&lt;/li&gt;
&lt;li data-target=&quot;#myCarousel&quot; data-slide-to=&quot;2&quot; class=&quot;&quot;&gt;&lt;/li&gt;
&lt;li data-target=&quot;#myCarousel&quot; data-slide-to=&quot;3&quot; class=&quot;&quot;&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;carousel-inner&quot;&gt;
&lt;div class=&quot;item slide1 active&quot; style=&quot;
background-image: url(https://upload.wikimedia.org/wikipedia/commons/1/15/Cat_August_2010-4.jpg);
background-size: cover;
background-repeat: no-repeat;
&quot;&gt;
&lt;div id=&quot;page-header-tagline&quot; class=&quot;tagline1&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;item slide2&quot; style=&quot;
background-image: url(https://static.toiimg.com/thumb/msid-67586673,width-1070,height-580,imgsize-3918697,resizemode-6,overlay-toi_sw,pt-32,y_pad-40/photo.jpg);
background-size: cover;
background-repeat: no-repeat;
&quot;&gt;
&lt;div id=&quot;page-header-tagline&quot; class=&quot;tagline2&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;item slide3&quot; style=&quot;
background-image: url(https://upload.wikimedia.org/wikipedia/commons/1/15/Cat_August_2010-4.jpg);
background-size: cover;
background-repeat: no-repeat;
&quot;&gt;
&lt;div id=&quot;page-header-tagline&quot; class=&quot;tagline3&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;item slide4&quot; style=&quot;
background-image: url(https://static.toiimg.com/thumb/msid-67586673,width-1070,height-580,imgsize-3918697,resizemode-6,overlay-toi_sw,pt-32,y_pad-40/photo.jpg);
background-size: cover;
background-repeat: no-repeat;
&quot;&gt;
&lt;div id=&quot;page-header-tagline&quot; class=&quot;tagline4&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;a class=&quot;carousel-control left&quot; href=&quot;#myCarousel&quot; data-slide=&quot;prev&quot;&gt;
&lt;span class=&quot;glyphicon glyphicon-chevron-left&quot;&gt;&lt;/span&gt;
&lt;/a&gt;
&lt;a class=&quot;carousel-control right&quot; href=&quot;#myCarousel&quot; data-slide=&quot;next&quot;&gt;
&lt;span class=&quot;glyphicon glyphicon-chevron-right&quot;&gt;&lt;/span&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

答案2

得分: 0

我通过更新 showSlide 函数来解决了这个问题,改变了 classes 的名称被添加和移除到 elements 的顺序和方式,在更改 slide 时,我还使用了 settimeout 函数,因为操作必须分为几个步骤:

  1. 将类 next 添加到要显示的元素,更新其 display 并将其呈现到 DOM 中。
  2. 第一个 timeout 负责为两个元素都添加类 left。这个类负责将两个图像(旧图像和新图像)都向左移动 100%(由于具有类 nextleft 的元素的 left 为 0,因此移动不会立即发生)。
  3. 第二个 timeout 将负责最终更新,它将添加和移除两个元素的最终类。

现在的代码如下:

let slideIndex = 1;

function showSlide(n) {
    let slides = document.querySelectorAll(".carousel-inner > .item");
    let dots = document.querySelectorAll(".carousel-indicators li");
    dots[slideIndex - 1].classList.remove("active");

    if (n > slides.length) {
        slideIndex = 1;
    } else if (n < 1) {
        slideIndex = slides.length;
    } else {
        slideIndex = n;
    }

    const activeSlide = document.querySelector(".carousel-inner > .item.active");
    slides[slideIndex - 1].classList.add("next");

    setTimeout(() => {
        activeSlide.classList.add("left");
        slides[slideIndex - 1].classList.add("left");

        setTimeout(() => {
            slides[slideIndex - 1].classList.add("active");

            activeSlide.classList.remove("left");
            activeSlide.classList.remove("active");

            slides[slideIndex - 1].classList.remove("next");
            slides[slideIndex - 1].classList.remove("left");

            dots[slideIndex - 1].classList.add("active");
        }, 800)
    }, 200)
}

$(".carousel-indicators li").on("click", function () {
    showSlide(parseInt(this.getAttribute("data-slide-to")) + 1)
})
/* CSS 样式部分已省略 */
<!-- HTML 部分已省略 -->

希望这有帮助!如果您需要进一步的解释或有其他问题,请告诉我。

英文:

I solved the issue by updating the function showSlide, by changing the order and the way the classes' names are being removed and added to elements of the transition when changing the slide, I also used settimeout function since the operation must be divided into steps :

  1. Add the class next to the element we want to show, update its display, and render it into the dom.
  2. The 1st timeout is responsible for adding the class left for both elements. That class is responsible for shifting both the images (old and new) to the left by 100% (the shift will no happen immediately since the element with the class next and left has a left of 0)
  3. The 2nd timeout will be responsible for the final updates and it will update both the elements by adding and removing their final classes.

Here is how it looks now :

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let slideIndex = 1;
function showSlide(n) {
let slides = document.querySelectorAll(&quot;.carousel-inner &gt; .item&quot;);
let dots = document.querySelectorAll(&quot;.carousel-indicators li&quot;);
dots[slideIndex - 1].classList.remove(&quot;active&quot;);
if (n &gt; slides.length) {
slideIndex = 1;
} else if (n &lt; 1) {
slideIndex = slides.length;
} else {
slideIndex = n;
}
const activeSlide = document.querySelector(&quot;.carousel-inner &gt; .item.active&quot;);
slides[slideIndex - 1].classList.add(&quot;next&quot;);
setTimeout(() =&gt; {
activeSlide.classList.add(&quot;left&quot;);
slides[slideIndex - 1].classList.add(&quot;left&quot;);
setTimeout(() =&gt; {
slides[slideIndex - 1].classList.add(&quot;active&quot;);
activeSlide.classList.remove(&quot;left&quot;);
activeSlide.classList.remove(&quot;active&quot;);
slides[slideIndex - 1].classList.remove(&quot;next&quot;);
slides[slideIndex - 1].classList.remove(&quot;left&quot;);
dots[slideIndex - 1].classList.add(&quot;active&quot;);
}, 800)
}, 200)
}
$(&quot;.carousel-indicators li&quot;).on(&quot;click&quot;, function () {
showSlide(parseInt(this.getAttribute(&quot;data-slide-to&quot;)) + 1)
})

<!-- language: lang-css -->

.carousel {
    position: relative;
}

@media screen and (min-width: 768px) {
    .carousel-indicators {
        bottom: 20px;
    }
}

.carousel-indicators {
    position: absolute;
    bottom: 10px;
    left: 50%;
    z-index: 15;
    width: 60%;
    padding-left: 0;
    margin-left: -30%;
    text-align: center;
    list-style: none;
}

ul, ol {
    margin-top: 0;
    margin-bottom: 10px;
}

.carousel-indicators li {
    display: inline-block;
    width: 10px;
    height: 10px;
    margin: 1px;
    text-indent: -999px;
    cursor: pointer;
    background-color: #000 ;
    background-color: rgba(0, 0, 0, 0);
    border: 1px solid #fff;
    border-radius: 10px;
}

.carousel-indicators .active {
    width: 12px;
    height: 12px;
    margin: 0;
    background-color: #fff;
}

.carousel-inner {
    position: relative;
    width: 100%;
    overflow: hidden;
}

.carousel-inner &gt; .item.slide1 {
    background-position: center 10%;
}

.carousel-inner &gt; .item {
    background-size: cover;
    background-repeat: no-repeat;
    height: 470px;
    position: relative;
    display: none;
    -webkit-transition: .6s ease-in-out left;
    transition: .6s ease-in-out left;
}

.carousel-inner &gt; .next, .carousel-inner &gt; .prev {
    position: absolute;
    top: 0;
    width: 100%
}

.carousel-inner &gt; .next {
    left: 100%
}

.carousel-inner &gt; .prev {
    left: -100%
}

.carousel-inner &gt; .next.left, .carousel-inner &gt; .prev.right {
    left: 0
}

.carousel-inner &gt; .active.left {
    left: -100%
}

.carousel-inner &gt; .active.right {
    left: 100%
}

.carousel-inner &gt; .active {
    left: 0;
}

.carousel-inner &gt; .active, .carousel-inner &gt; .next, .carousel-inner &gt; .prev {
    display: block;
}

.carousel-control.left {
    background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001)));
    background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0), color-stop(rgba(0, 0, 0, 0.0001) 100%));
    background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%);
    background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%);
    background-repeat: repeat-x;
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=&#39;#80000000&#39;, endColorstr=&#39;#00000000&#39;, GradientType=1);
}

.carousel-control.right {
    right: 0;
    left: auto;
    background-image: -webkit-gradient(linear, 0 top, 100% top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5)));
    background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0), color-stop(rgba(0, 0, 0, 0.5) 100%));
    background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%);
    background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%);
    background-repeat: repeat-x;
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=&#39;#00000000&#39;, endColorstr=&#39;#80000000&#39;, GradientType=1);
}

.carousel-control {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 15%;
    font-size: 20px;
    color: #fff;
    text-align: center;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
    opacity: .5;
    filter: alpha(opacity=50);
}

.carousel-control .icon-prev, .carousel-control .glyphicon-chevron-left {
    left: 50%;
}

.carousel-control .icon-prev, .carousel-control .icon-next, .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right {
    position: absolute;
    top: 50%;
    z-index: 5;
    display: inline-block;
}

.glyphicon-chevron-left::before {
    content: url(../images/icons/left-arrow.png);
    border-radius: 50%;
    border: 1px solid white;
    display: block;
    width: 100%;
    height: 100%;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}


.carousel-control .icon-next, .carousel-control .glyphicon-chevron-right {
    right: 50%;
}

.carousel-control .icon-prev, .carousel-control .icon-next, .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right {
    position: absolute;
    top: 50%;
    z-index: 5;
    display: inline-block;
}

.glyphicon:empty {
    width: 1em;
}

.glyphicon-chevron-right::before {
    content: url(../images/icons/right-arrow.png);
    border-radius: 50%;
    border: 1px solid white;
    display: block;
    width: 100%;
    height: 100%;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}

<!-- language: lang-html -->

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;script src=&quot;https://code.jquery.com/jquery-3.7.0.min.js&quot; integrity=&quot;sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
    &lt;title&gt;Document&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;myCarousel&quot; class=&quot;carousel slide&quot; data-ride=&quot;carousel&quot;&gt;
      &lt;ol class=&quot;carousel-indicators&quot;&gt;
        &lt;li data-target=&quot;#myCarousel&quot; data-slide-to=&quot;0&quot; class=&quot;active&quot;&gt;&lt;/li&gt;
        &lt;li data-target=&quot;#myCarousel&quot; data-slide-to=&quot;1&quot; class=&quot;&quot;&gt;&lt;/li&gt;
        &lt;li data-target=&quot;#myCarousel&quot; data-slide-to=&quot;2&quot; class=&quot;&quot;&gt;&lt;/li&gt;
        &lt;li data-target=&quot;#myCarousel&quot; data-slide-to=&quot;3&quot; class=&quot;&quot;&gt;&lt;/li&gt;
      &lt;/ol&gt;

      &lt;div class=&quot;carousel-inner&quot;&gt;
        &lt;div
          class=&quot;item slide1 active&quot;
          style=&quot;
            background-image: url(https://upload.wikimedia.org/wikipedia/commons/1/15/Cat_August_2010-4.jpg);
            background-size: cover;
            background-repeat: no-repeat;
          &quot;
        &gt;
          &lt;div id=&quot;page-header-tagline&quot; class=&quot;tagline1&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;

        &lt;div
          class=&quot;item slide2&quot;
          style=&quot;
            background-image: url(https://static.toiimg.com/thumb/msid-67586673,width-1070,height-580,imgsize-3918697,resizemode-6,overlay-toi_sw,pt-32,y_pad-40/photo.jpg);
            background-size: cover;
            background-repeat: no-repeat;
          &quot;
        &gt;
          &lt;div id=&quot;page-header-tagline&quot; class=&quot;tagline2&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;

        &lt;div
          class=&quot;item slide3&quot;
          style=&quot;
            background-image: url(https://upload.wikimedia.org/wikipedia/commons/1/15/Cat_August_2010-4.jpg);
            background-size: cover;
            background-repeat: no-repeat;
          &quot;
        &gt;
          &lt;div id=&quot;page-header-tagline&quot; class=&quot;tagline3&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;

        &lt;div
          class=&quot;item slide4&quot;
          style=&quot;
            background-image: url(https://static.toiimg.com/thumb/msid-67586673,width-1070,height-580,imgsize-3918697,resizemode-6,overlay-toi_sw,pt-32,y_pad-40/photo.jpg);
            background-size: cover;
            background-repeat: no-repeat;
          &quot;
        &gt;
          &lt;div id=&quot;page-header-tagline&quot; class=&quot;tagline4&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;a class=&quot;carousel-control left&quot; href=&quot;#myCarousel&quot; data-slide=&quot;prev&quot;&gt;
        &lt;span class=&quot;glyphicon glyphicon-chevron-left&quot;&gt;&lt;/span&gt;
      &lt;/a&gt;

      &lt;a class=&quot;carousel-control right&quot; href=&quot;#myCarousel&quot; data-slide=&quot;next&quot;&gt;
        &lt;span class=&quot;glyphicon glyphicon-chevron-right&quot;&gt;&lt;/span&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年5月30日 00:40:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76358990.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定