使用原生 JavaScript 防止轮播中的气泡

Prevent bubbles in carousel with native javascript

本文关键字:气泡 原生 JavaScript      更新时间:2023-09-26

如何阻止此轮播冒泡动画?如果你点击得更快,它会开始混淆事情。如果动画正在运行,我需要停止事件处理程序函数,在该timeOut内,处理程序应该脱机。

请参阅下面的片段:

var Carousel = function(element, options) {
  this.carousel = document.querySelector(element);
  this.slides = Array.prototype.slice.call(this.carousel.querySelectorAll('.item'), null);
  this.prev = this.carousel.querySelector("[data-slide='prev']");
  this.next = this.carousel.querySelector("[data-slide='next']");
  this.indicators = this.carousel.querySelectorAll(".carousel-indicators li");
  this.interval = options && options.interval ? options.interval : 5000;
  this.duration = 600; // bootstrap carousel default transition duration
  this.paused = null;
  this.direction = null;
  this.index = 0;
  this.total = this.slides.length;
  this.init();
};
Carousel.prototype = {
  init: function() {
    this.cycle();
    this.actions();
  },
  _slideTo: function(next, e) {
    var self = this;
    //determine type
    var active = self._getActiveIndex(); // the current active
    var direction = self.direction;
    var type = direction === 'left' ? 'next' : 'prev';
    if (!this.slides[next].classList.contains(type)) {
      //e.preventDefault();         
      //e.defaultPrevented = false;
      this.slides[next].classList.add(type);
      this.slides[next].offsetWidth;
      this.slides[active].classList.add(direction);
      this.slides[next].classList.add(direction);
      setTimeout(function() {
        console.log('inside timeout prevented? ' + e.defaultPrevented);
        self.slides[next].classList.remove(type, direction);
        self.slides[next].classList.add('active');
        self.slides[active].classList.remove('active', direction);
        self._curentPage(self.indicators[next]);
        //e.defaultPrevented = false;
      }, self.duration + 200);
    }
  },
  _getActiveIndex: function() {
    return this._getItemIndex('.item.active')
  },
  _getItemIndex: function(itm) {
    return this.slides.indexOf(this.carousel.querySelector(itm))
  },
  _curentPage: function(p) {
    for (var i = 0; i < this.indicators.length; ++i) {
      var a = this.indicators[i];
      a.className = "";
    }
    p.className = "active";
  },
  cycle: function() {
    var self = this;
    //deleted some shit
  },
  actions: function() {
    var self = this;
    self.next.addEventListener("click", function(e) {
      e.preventDefault();
      self.index++;
      self.direction = 'left'; //set direction first
      if (self.index == self.total - 1) {
        self.index = self.total - 1;
      } else if (self.index == self.total) {
        self.index = 0
      }
      self._slideTo(self.index, e);
    }, false);
    self.prev.addEventListener("click", function(e) {
      e.preventDefault();
      self.index--;
      self.direction = 'right'; //set direction first
      if (self.index == 0) {
        self.index = 0;
      } else if (self.index < 0) {
        self.index = self.total - 1
      }
      self._slideTo(self.index, e);
    }, false);
    for (var i = 0; i < self.indicators.length; ++i) {
      var a = self.indicators[i];
      a.addEventListener("click", function(e) {
        e.preventDefault();
        var n = parseInt(this.getAttribute("data-slide-to"), 10);
        self.index = n;
        if (self.index == 0) {
          self.index = 0;
        }
        if (self.index > 0) {}
        if (self.index == self.total - 1) {
          self.index = self.total - 1;
        } else {}
        //determine direction first
        var active = self._getActiveIndex(); // the current active
        if ((active < self.index) || (active === self.total - 1 && self.index === 0)) {
          self.direction = 'left'; // next
        } else if ((active > self.index) || (active === 0 && self.index === self.total - 1)) {
          self.direction = 'right'; // prev
        }
        self._slideTo(self.index, e);
      }, false);
    }
    window.addEventListener('keydown', function(e) {
      if (/input|textarea/i.test(e.target.tagName)) return;
      switch (e.which) {
        case 39:
          self.index++;
          self.direction = 'left';
          if (self.index == self.total - 1) {
            self.index = self.total - 1;
          } else
          if (self.index == self.total) {
            self.index = 0
          }
          break;
        case 37:
          self.index--;
          self.direction = 'right';
          if (self.index == 0) {
            self.index = 0;
          } else
          if (self.index < 0) {
            self.index = self.total - 1
          }
          break;
        default:
          return;
      }
      // e.preventDefault();
      self._slideTo(self.index, e);
    }, false)
  }
}

var slider = new Carousel("#myCarousel1");
#myCarousel1 {
  height: 300px;
  max-width: 100%
}
.item {
  height: 300px;
  background: url(http://placehold.it/100x100/069/069.png) repeat center center;
  background-size: cover
}
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
<div id="myCarousel1" class="carousel slide" data-ride="carousel">
  <ol class="carousel-indicators">
    <li data-target="#myCarousel1" data-slide-to="0" class="active"></li>
    <li data-target="#myCarousel1" data-slide-to="1"></li>
    <li data-target="#myCarousel1" data-slide-to="2"></li>
  </ol>
  <div class="carousel-inner">
    <div class="item active">
      <div class="container">
        <div class="carousel-caption">
          <h1>Example headline.</h1>
          <p>Note: If you're viewing this page via a <code>file://</code> URL, the "next" and "previous" Glyphicon buttons on the left and right might not load/display properly due to web browser security rules.</p>
          <p><a class="btn btn-lg btn-primary" href="#" role="button">Sign up today</a>
          </p>
        </div>
      </div>
    </div>
    <div class="item">
      <div class="container">
        <div class="carousel-caption">
          <h1>Another example headline.</h1>
          <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
          <p><a class="btn btn-lg btn-primary" href="#" role="button">Learn more</a>
          </p>
        </div>
      </div>
    </div>
    <div class="item">
      <div class="container">
        <div class="carousel-caption">
          <h1>One more for good measure.</h1>
          <p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
          <p><a class="btn btn-lg btn-primary" href="#" role="button">Browse gallery</a>
          </p>
        </div>
      </div>
    </div>
  </div>
  <a href="#myCarousel1" class="left carousel-control" data-slide="prev"><span class="glyphicon glyphicon-chevron-left"></span></a>
  <a href="#myCarousel1" class="right carousel-control" data-slide="next"><span class="glyphicon glyphicon-chevron-right"></span></a>
</div>

也许检查点击之间的时间间隔并从滑动轮播的功能返回 false 可以解决这个问题:

var oldTs = 0;
element.removeEventListener("click", slideClickHandler);
function slideClickHandler(e) {
    var ts = e.timeStamp;
    if ((oldTs !== 0) && (ts - oldTs < 500)) return false; //If time between clicks is 500 miliseconds and its not the first click cancel slide
    else {
        oldTs = ts; //Update timestamp buffer
        slide(); //Do the sliding stuff
    }
}
element.addEventListener('click', slideClickHandler);

编辑:您应该将此代码放在一个函数中,并在每张幻灯片后刷新单击处理程序以使其正常工作。