jQuery自定义图像滑块仅工作一次或第三次

时间:2019-05-11 15:42:08

标签: javascript jquery

我正在尝试创建一个简单的图像滑块。我面临的问题是next和prev按钮只能在第一次使用。然后,当您再次悬停一个项目时,它将不起作用。第三次将鼠标悬停在项目上时,依此类推。

我只是找不到导致此行为的原因。

这是工作中的fiddle

$('.item.with-sec-image').on('mouseenter', function() {
  var $this = $(this);

  /* load data only once */
  if (!$this.hasClass('images-initialized')) {
    var url = $this.data('handle').replace('.html', '.ajax');
    var purl = $this.data('handle');
    $.getJSON(url, function(data) {
      if (data.images.length > 1) {
        var slider = $this.find('.slider');
        if (data.images.length >= 2 && data.images.length != slider.find('li.selected').length) {
          $.each(data.images, function(index, image) {
            var img_url = image.replace('50x50x2', '400x400x2')
            if (slider.find('li.selected').data('index') != index) {
              var $newImage = $('<li><a href="' + purl + '"><img src="' + img_url + '" /></a></li>')
              slider.append($newImage);
            }
          });
        }
      }
    }).done(function() {
      $this.addClass('images-initialized');
    });
  }
  $this.on('click', '.slider-btn', function() {
    updateSlider($this)
  });
});

更新滑块的功能

function updateSlider(navigation) {
  var $this = navigation
  var sliderContainer = $this.find('.images .slider'),
    activeSlider = sliderContainer.children('.selected').removeClass('selected');

  if ($this.hasClass('next')) {
    (!activeSlider.is(':last-child')) ? activeSlider.next().addClass('selected'): sliderContainer.children('li').eq(0).addClass('selected');
  } else {
    (!activeSlider.is(':first-child')) ? activeSlider.prev().addClass('selected'): sliderContainer.children('li').last().addClass('selected');
  }
}

这是我的HTML:

<div class="item with-sec-image" data-handle="some-url">

  <div class="images">
    <ul class="slider">
      <li data-index="0" class="selected"><img src="link-to-image" /></li>
    </ul>

    <ul class="slider-navigation">
      <li class="prev btn-round slider-btn small"><i class="icon-left"></i></li>
      <li class="next btn-round slider-btn small"><i class="icon-right"></i></li>
    </ul>
  </div>
</div>

$('.item.with-sec-image').on('mouseenter', function() {
  var $this = $(this);

  /* load data only once */
  if (!$this.hasClass('images-initialized')) {
    var url = $this.data('handle').replace('.html', '.ajax');
    var purl = $this.data('handle');
    $.getJSON(url, function(data) {
      if (data.images.length > 1) {
        var slider = $this.find('.slider');
        if (data.images.length >= 2 && data.images.length != slider.find('li.selected').length) {
          $.each(data.images, function(index, image) {
            var img_url = image.replace('50x50x2', '400x400x2')
            if (slider.find('li.selected').data('index') != index) {
              var $newImage = $('<li><a href="' + purl + '"><img src="' + img_url + '" /></a></li>')
              slider.append($newImage);
            }
          });
        }
      }
    }).done(function() {
      $this.addClass('images-initialized');
    });
  }
  $this.on('click', '.slider-btn', function() {
    updateSlider($this)
  });
});

// The function to update the slider

function updateSlider(navigation) {
  var $this = navigation
  var sliderContainer = $this.find('.images .slider'),
    activeSlider = sliderContainer.children('.selected').removeClass('selected');

  if ($this.hasClass('next')) {
    (!activeSlider.is(':last-child')) ? activeSlider.next().addClass('selected'): sliderContainer.children('li').eq(0).addClass('selected');
  } else {
    (!activeSlider.is(':first-child')) ? activeSlider.prev().addClass('selected'): sliderContainer.children('li').last().addClass('selected');
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item with-sec-image" data-handle="some-url">

  <div class="images">
    <ul class="slider">
      <li data-index="0" class="selected"><img src="link-to-image" /></li>
    </ul>

    <ul class="slider-navigation">
      <li class="prev btn-round slider-btn small"><i class="icon-left"></i></li>
      <li class="next btn-round slider-btn small"><i class="icon-right"></i></li>
    </ul>
  </div>
</div>

1 个答案:

答案 0 :(得分:1)

好的,我发现了问题。

您正在绑定mouseenter上的click事件,这意味着它将绑定很多次。因此一次点击就等于多次点击,这就是为什么您会遇到这种情况。

我对您的代码做了一些小的更改,如下所示。这也是fiddler工作示例

 function updateSlider(btn) {
   var $this = btn.closest(".item.with-sec-image");
   var sliderContainer = $this.find('.images .slider'),
     activeSlider = sliderContainer.children('.selected').removeClass('selected');

   if (btn.hasClass('next')) {
     (!activeSlider.is(':last-child')) ? activeSlider.next().addClass('selected'): sliderContainer.children('li').eq(0).addClass('selected');
   } else {
     (!activeSlider.is(':first-child')) ? activeSlider.prev().addClass('selected'): sliderContainer.children('li').last().addClass('selected');
   }
 }

  // second image only on hover
$(function(){

   $('.item.with-sec-image').on('mouseenter', function() {
     var $this = $(this);
     if (!$this.hasClass('images-initialized')) {
       var url = $this.data('handle').replace('.html', '.ajax');
       var purl = $this.data('handle');
       $.getJSON(url, function(data) {
         if (data.images.length > 1) {
           var slider = $this.find('.slider');
           if (data.images.length >= 2 && data.images.length != slider.find('li.selected').length) {
             $.each(data.images, function(index, image) {
               var img_url = image.replace('50x50x2', '400x400x2')
               if (slider.find('li.selected').data('index') != index) {
                 var $newImage = $('<li><a href="' + purl + '"><img src="' + img_url + '" /></a></li>')
                 slider.append($newImage);
               }
             });
           }
         }
       }).done(function() {
         $this.addClass('images-initialized');
       });
     }

   }).on('click', '.slider-btn', function() {// this should be run outside the mouseenter function or else it will bind many times
       updateSlider($(this))
     });
 });