Jquery 函数没有在应该的时候将 class 添加到 Dom 元素。尝试构建按钮功能幻灯片

Jquery function isn't adding class to Dom elements when it should be. Trying to build a button function slideshow

我正在尝试为项目制作幻灯片。

我构建的代码相当简单,但出于某种原因,我只能使下一个箭头起作用,而不能使前一个箭头起作用。

当您单击下一步时,它会从当前图像中删除 class 活动图像,将 class 添加到下一个图像并将显示更改为新的活动图像。

当您单击“上一步”时,它会删除活动的 class,但不会向任何其他元素添加任何 class。然后出于某种原因将显示更改为最终图像。

我试过重新排列调用函数的顺序。我也试过将活动 class 添加到最后一张图像时会发生什么(它有同样的问题,但在反转,所以现在 next 不起作用,但 previous 没问题。

var activeSlide = $('.active');
var nextSlide = activeSlide.next('.slide');
var prevSlide = activeSlide.prev('.slide');
var arrow = $('.arrow');
var firstSlide = $('.first');
var lastSlide = $('.last');

// slideshow functions

// next arrow
function nextArrow () {
  if (!activeSlide.hasClass('last')) {
            activeSlide.removeClass('active');
            nextSlide.addClass('active');
            activeSlide = nextSlide;
            nextSlide = activeSlide.next('.slide');
            // check if new slide is last slide and remove the click button
            if (activeSlide.hasClass('last')) {
                $('.next').fadeOut();   
            }
        }  
};
// previous arrow
function prevArrow () {
    if(!activeSlide.hasClass('first')) {
        activeSlide.removeClass('active');
        prevSlide.addClass('active');
        activeSlide = prevSlide;
        prevSlide = activeSlide.prev('.slide');
        // check if new slide is the first slide and remove the click button
        if (activeSlide.hasClass('first')) {
            $('.previous').fadeOut();
        }
    } 
};

//click element and call functions
$('.arrow').click( function () {
    if ($(this).hasClass('next')) {
        nextArrow();
    } else {
        prevArrow();        
    }
});
#slideshow {
    position: relative;
    height: 400px;  
    width: 600px;
    margin: 15% auto;
}
.slide {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 8;
    height: 100%;
    width: 100%;
}
.active {
    z-index: 10;
}
.arrow {
    text-decoration: none;
    display: inline-block;
    padding: 8px 16px;
}
.arrow:hover {
    background-color: #ddd;
    color: black;
    opacity: 0.9;
    cursor: pointer;
}
.previous {
    left: 0;
}

.next {
    right: 0;
}
.arrow {
    z-index: 11;
    background-color: #ddd;
    color: black;
    position: absolute;
    top: 50%;
    opacity: 0.5;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="slideshow">
        <div id="slides">
            <img class="slide active first" src="Toscana 1.jpg" alt="image of toscana, slideshow image 1" />
            <img class="slide" src="Toscana 2.jpg" alt="image of toscana, slideshow image 1" />
            <img class="slide" src="Toscana 3.jpg" alt="image of toscana, slideshow image 2" />
            <img class="slide last" src="Toscana 4.jpg" alt="image of toscana, slideshow image 3" />
        </div>
        <div class="previous arrow">&#8249;</div>
        <div class="next arrow">&#8250;</div>
    </div>
    <script src="javascript/practice.js"></script>

理论上,您应该可以单击下一步并查看序列中的下一张图像。然后,当您想查看序列中的上一张图像时,您应该能够单击上一张,它将从当前图像中删除活动 class 并将其添加到之前的图像中。

如果有人能够提供帮助,非常感谢帮助了解出了什么问题。

您没有在下一个箭头函数中设置 prevSlide。因此,当您开始时,prevSlide 为空。然后单击下一个箭头按钮并将活动幻灯片设置为下一张幻灯片,然后将下一张幻灯片设置为活动幻灯片之后的一张,但您没有设置上一张幻灯片,因此它保持为空

例如幻灯片 1 = 当前幻灯片,幻灯片 2 = 即将上线,幻灯片 3 = 即将下一张

点击下一个箭头的操作应该是:

  1. 将 prevSlide 设置为当前幻灯片(此操作不会发生)
  2. 将 activeSlide 设置为下一张幻灯片
  3. 将 nextSlide 设置为下一张-slide.next

同样在你的prevArrow中,你需要设置nextSlide

您依靠全局变量来维护您的程序状态,但并不总是设法使变量的状态与 DOM 的状态相匹配。

使用 DOM 作为单一事实来源可能更好:"active" 幻灯片是当前具有 "active" class 的任何节点,您可以根据位置计算下一个和上一个。

这还需要在 "next" / "previous" 按钮可见性方面做一些工作:您在范围的末尾和开头隐藏按钮,但从未将它们恢复;您还需要在最初禁用 "previous" 按钮的情况下加载。

//No global variables. Use $('.active') to determine the currently active slide

// next arrow
function nextArrow() {
  var activeSlide = $('.active');
  if (activeSlide.hasClass('last')) return; // bail if the user managed to click the 'next' button while it was fading out

  activeSlide.removeClass('active');
  activeSlide.next().addClass('active');
  // $('.active') is now the "next" slide
  if ($('.active').hasClass('last')) { 
    $('.next').fadeOut();
  } 
  
  // Always bring back the "previous" button when user hits next:
  $('.previous').fadeIn(); 
};

// previous arrow
function prevArrow() {
  var activeSlide = $('.active');
  if (activeSlide.hasClass('first')) return;
  activeSlide.removeClass('active');
  activeSlide.prev().addClass('active');
  if ($('.active').hasClass('first')) {
    $('.previous').fadeOut();
  }
  $('.next').fadeIn();
};

//click element and call functions
// removing the unnecessary intermediate function here:
$('.next').click(nextArrow)
$('.previous').click(prevArrow)
#slideshow {
  position: relative;
  height: 200px;
  width: 300px;
  margin: 15% auto;
}

.slide {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 8;
  height: 100%;
  width: 100%;
}

.active {
  z-index: 10;
}

.arrow {
  text-decoration: none;
  display: inline-block;
  padding: 8px 16px;
}

.arrow:hover {
  background-color: #ddd;
  color: black;
  opacity: 0.9;
  cursor: pointer;
}

.previous {
  left: 0;
  display:none;
}

.next {
  right: 0;
}

.arrow {
  z-index: 11;
  background-color: #ddd;
  color: black;
  position: absolute;
  top: 50%;
  opacity: 0.5;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="slideshow">
  <div id="slides">
    <img class="slide active first" src="https://placehold.it/600x400" alt="image of toscana, slideshow image 1" />
    <img class="slide" src="https://placehold.it/601x401" alt="image of toscana, slideshow image 2" />
    <img class="slide" src="https://placehold.it/602x402" alt="image of toscana, slideshow image 1" />
    <img class="slide last" src="https://placehold.it/603x403" alt="image of toscana, slideshow image 1" />
  </div>
  <div class="previous arrow">&#8249;</div>
  <div class="next arrow">&#8250;</div>
</div>

你可以试试class $('.active');

        if(!activeSlide.hasClass('first')) {

            var currentSlide = $('.active');
            var prevSlide = currentSlide.prev();

             currentSlide.removeClass('active');
             prevSlide.addClass('active');