首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >纯JS Carousel错误

问纯JS Carousel错误
EN

Stack Overflow用户
提问于 2015-05-22 16:04:33
回答 2查看 921关注 0票数 4

我正在锻炼,并尝试在纯JS上编写自己的旋转木马。

JSFiddle

代码语言:javascript
复制
window.onload = function () {

    var slider = document.getElementById('slide-list');
    var left = document.getElementById('rewind');
    var right = document.getElementById('forward');

    var clickDisabled = false;

    function spin() {
        slider.firstChild.style.marginLeft = -800 + 'px';
        setTimeout(function () {
            slider.appendChild(slider.removeChild(slider.firstChild));
            slider.lastChild.style.marginLeft = '0px';
        }, 2000);
    }

    var slideShow = setInterval(spin, 4000);

    left.onclick = function () {
        if (clickDisabled) {return;}
        else {
            clickDisabled = true;
            clearInterval(slideShow);
            slider.lastChild.style.marginLeft = -800 + 'px';
            slider.insertBefore(slider.lastChild, slider.firstChild);
            // the crutch - try to unwrap content from timeout and see that image changes instantly, with no transition
            setTimeout(function () { slider.firstChild.style.marginLeft = '0px'; }, 1);
            slideShow = setInterval(spin, 4000);
            setTimeout(function() {clickDisabled = false;}, 2000);
        }
    }

    right.onclick = function () {
        // fix of fast sliding after multiple clicks
        if (clickDisabled) {return;}
        else {
            clickDisabled = true;
            clearInterval(slideShow);
            spin();
            slideShow = setInterval(spin, 4000);
            setTimeout(function() {clickDisabled = false;}, 2000);
        }
    }
}

我的想法是,我有一个带有旋转幻灯片的列表,然后我用setInterval重新排列这些幻灯片。平滑的滑动过渡是通过在CSS中有过渡和改变幻灯片的边距来实现的-因此,这种过渡可以使它平滑地滑动。

自动旋转工作正常,没有问题,问题是手动更换幻灯片,使用左键和右键。问题是,如果没有一个非常奇怪的(对我来说)拐杖,它是不会工作的。它被标记在代码中(第28行)。似乎有什么东西阻止了过渡的完成,如果没有这个拐杖,图像就会改变,没有过渡。我也非常感谢对我的想法发表意见,我的想法是临时阻止按钮的onclick事件,以防止混乱和即时滑动,如果他们被点击多次。也许这是一种糟糕的方式?还有什么方法可以更好呢?

EN

回答 2

Stack Overflow用户

发布于 2016-01-30 22:55:07

你可以用我做的这个图像滑块...虽然它只适用于现代浏览器。

http://codepen.io/team/moderndeveloper/pen/MKgqzq

代码语言:javascript
复制
/* global Modernizr */

if (!Object.assign) {
  Object.defineProperty(Object, 'assign', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(target) {
      'use strict';
      if (target === undefined || target === null) {
        throw new TypeError('Cannot convert first argument to object');
      }

      var to = Object(target);
      for (var i = 1; i < arguments.length; i++) {
        var nextSource = arguments[i];
        if (nextSource === undefined || nextSource === null) {
          continue;
        }
        nextSource = Object(nextSource);

        var keysArray = Object.keys(nextSource);
        for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
      return to;
    }
  });
}

(function(window, document, Modernizr) {
  "use strict";

  var d = document;
  var transform = Modernizr.prefixed('transform');

  function ImageSliderIndicators(imageSlider, options) {
    this.imageSlider = imageSlider;
    this.options = Object.assign({}, ImageSliderIndicators.DEFAULTS, options || {});
    this.el = d.querySelector('.' + this.options.indicatorsClass);
    this.indicators = [].slice.call(d.querySelectorAll('.' + this.options.indicatorClass));

    this.imageSlider.el.addEventListener('positionChanged', this.onPositionChanged.bind(this));
    this.el.addEventListener('click', this.onIndicatorClick.bind(this), false);
    this.onPositionChanged();
  }

  ImageSliderIndicators.DEFAULTS = {
    indicatorsClass: 'ImageSlider-indicators',
    indicatorClass: 'ImageSlider-indicator',
    indicatorActiveClass: 'ImageSlider-indicator--is-active'
  };

  ImageSliderIndicators.prototype.onIndicatorClick = function onIndicatorClick(event) {
    var position = this.indicators.indexOf(event.target);
    if (position !== -1) {
      this.imageSlider.goto(position);
    }
  };

  ImageSliderIndicators.prototype.onPositionChanged = function onPositionChanged() {
    var self = this;
    this.indicators.forEach(function(element, index) {
      var action = index === self.imageSlider.position ? 'add' : 'remove';
      element.classList[action](self.options.indicatorActiveClass);
    });
  };

  function ImageSlider(options) {
    this.options = Object.assign({}, ImageSlider.DEFAULTS, options || {});
    this.position = 0;
    this.el = d.querySelector('.' + this.options.imageSliderClass);
    this.items = d.querySelector('.' + this.options.itemsClass);
    this.itemCount = d.querySelectorAll('.' + this.options.itemClass).length;
    this.scroller = d.querySelector('.' + this.options.scrollerClass);
    this.previousButton = d.querySelector('.' + this.options.previousButtonClass);
    this.nextButton = d.querySelector('.' + this.options.nextButtonClass);
    this.indicators = new ImageSliderIndicators(this, this.options.indicators);

    window.addEventListener('resize', this.render.bind(this));
    this.nextButton && this.nextButton.addEventListener('click', this.next.bind(this));
    this.previousButton && this.previousButton.addEventListener('click', this.previous.bind(this));
  }

  ImageSlider.DEFAULTS = {
    imageSliderClass: 'ImageSlider',
    itemsClass: 'ImageSlider-items',
    itemClass: 'ImageSlider-item',
    scrollerClass: 'ImageSlider-scroller',
    previousButtonClass: 'js-ImageSlider-button--previous',
    nextButtonClass: 'js-ImageSlider-button--next'
  };

  ImageSlider.prototype.render = function render() {
    this.items.style[transform] = 'translate3d(' + (-this.position * this.items.offsetWidth) + 'px,0,0)';
  };

  ImageSlider.prototype.goto = function goto(position) {
    var event = d.createEvent('Event');
    event.initEvent('positionChanged', true, true);
    this.position = position;
    this.el.dispatchEvent(event);
    this.render();
  };

  ImageSlider.prototype.previous = function previous() {
    this.goto((this.position + (this.itemCount - 1)) % this.itemCount);
  };

  ImageSlider.prototype.next = function next() {
    this.goto((this.position + 1) % this.itemCount);
  };

  window.ImageSlider = ImageSlider;

}).call(this, window, window.document, Modernizr);

new ImageSlider();
票数 0
EN

Stack Overflow用户

发布于 2021-03-29 03:34:34

为了简单起见。图像、css和javascript都是同时渲染的。因此,转换无法发生,因为在运行转换时,映像已经具有您要“更改”的值。

它的渲染是在值添加之后进行的,因此没有转换。在这种情况下,使用setTimeout是相当标准的。然而,你应该意识到,如果某人使用的是慢速互联网连接,1/1000秒的超时可能并不总是足够的。

正确的解决方案不是使用javascript更改您的样式,而是创建一个覆盖默认样式的类,并使用javascript来切换您的类。

希望这实际上是你问题的答案,而不仅仅是我建议你使用预先存在的解决方案。

但就我个人而言,我所做的正是您正在做的事情,如我自己的carousel示例所示:

代码语言:javascript
复制
/* set each image except first to not display */  
  document.querySelectorAll('.imgContainer div:not(:nth-child(1))').forEach(function(el) {
    el.style.display = 'none';
    el.style.opacity =  0;
  });

/* set onclick event for navigation dots */
  var dotty = document.querySelectorAll('ul li');
  for (var i = 0; i < dotty.length; i++) {
    dotty[i].addEventListener("click", contentChanger);
  }

/* rotate function */
  function contentChanger(evt) {
    var id = evt.target.id;
    x = evt.target.id;
    [].forEach.call(document.querySelectorAll('li'), function (el) {
      el.classList.remove('active');
    });
    evt.target.classList.add('active');
    document.querySelectorAll('.imgContainer div:not(:nth-child(' + id + '))').forEach(function(el) {
      el.style.display = 'none';
      el.style.opacity = '0';
    });
    document.querySelector('.imgContainer div:nth-child(' + id + ')').style.display = 'block';
    setTimeout(function(){
      document.querySelector('.imgContainer div:nth-child(' + id + ')').style.opacity =  1;
    }, 50);
  }

/* only required to automate rotation leave this code out if you want only a click navigation. */
  function clickIt(i) {
    document.querySelector('ul li:nth-child('+i+')').click();
  }
  var x = 0;
  setInterval(function(){
    x++;
    if (x > dotty.length) { x = 1; }
    clickIt(x);
  }, 5000);

https://codepen.io/billy-bucks/pen/RwKRyEx

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30391432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档