2015-01-12 1 views
0

프로젝트에 슬릿 슬라이더 (http://tympanus.net/codrops/2012/06/05/fullscreen-slit-slider-with-jquery-and-css3/)를 사용하고 있으며 화살표를 계속 활성 상태로 유지하면서 슬라이더를 마지막 슬라이드 이후에 멈추고 싶습니다. jquery 코딩에 익숙하지 않아 누구나 정말 도움이된다면 정말 감사하겠습니다.슬라이드가 끝난 후 Slit Slider를 멈추게하려면 어떻게해야합니까?

http://jsfiddle.net/totimage/y40wy5uf/ 내가 현재 사용하고 코드입니다 :

;(function($, window, undefined) { 

    'use strict'; 

    var $event = $.event, 
    $special, 
    resizeTimeout; 

    $special = $event.special.debouncedresize = { 
     setup: function() { 
      $(this).on("resize", $special.handler); 
     }, 
     teardown: function() { 
      $(this).off("resize", $special.handler); 
     }, 
     handler: function(event, execAsap) { 
      // Save the context 
      var context = this, 
       args = arguments, 
       dispatch = function() { 
        // set correct event type 
        event.type = "debouncedresize"; 
        $event.dispatch.apply(context, args); 
       }; 

      if (resizeTimeout) { 
       clearTimeout(resizeTimeout); 
      } 

      execAsap ? 
       dispatch() : 
       resizeTimeout = setTimeout(dispatch, $special.threshold); 
     }, 
     threshold: 20 
    }; 

    // global 
    var $window = $(window), 
     $document = $(document), 
     Modernizr = window.Modernizr; 

    $.Slitslider = function(options, element) { 

     this.$elWrapper = $(element); 
     this._init(options); 

    }; 

    $.Slitslider.defaults = { 
     // transitions speed 
     speed : 1500, 
     // if true the item's slices will also animate the opacity value 
     optOpacity : true, 
     // amount (%) to translate both slices - adjust as necessary 
     translateFactor : 230, 
     // maximum possible angle 
     maxAngle : 25, 
     // maximum possible scale 
     maxScale : 2, 
     // slideshow on/off 
     autoplay : true, 
     // keyboard navigation 
     keyboard : false, 
     // time between transitions 
     interval : 500, 
     // callbacks 
     onBeforeChange : function(slide, idx) { return true; }, 
     onAfterChange : function(slide, idx) { return false; } 
    }; 

    $.Slitslider.prototype = { 

     _init : function(options) { 

      // options 
      this.options = $.extend(true, {}, $.Slitslider.defaults, options); 

      // https://github.com/twitter/bootstrap/issues/2870 
      this.transEndEventNames = { 
       'WebkitTransition' : 'webkitTransitionEnd', 
       'MozTransition' : 'transitionend', 
       'OTransition' : 'oTransitionEnd', 
       'msTransition' : 'MSTransitionEnd', 
       'transition' : 'transitionend' 
      }; 
      this.transEndEventName = this.transEndEventNames[ Modernizr.prefixed('transition') ]; 
      // suport for css 3d transforms and css transitions 
      this.support = Modernizr.csstransitions && Modernizr.csstransforms3d; 
      // the slider 
      this.$el = this.$elWrapper.children('.sl-slider'); 
      // the slides 
      this.$slides = this.$el.children('.sl-slide').hide(); 
      // total slides 
      this.slidesCount = this.$slides.length; 
      // current slide 
      this.current = 0; 
      // control if it's animating 
      this.isAnimating = false; 
      // get container size 
      this._getSize(); 
      // layout 
      this._layout(); 
      // load some events 
      this._loadEvents(); 
      // slideshow 
      if(this.options.autoplay) { 

       this._startSlideshow(); 

      } 

     }, 
     // gets the current container width & height 
     _getSize : function() { 

      this.size = { 
       width : this.$elWrapper.outerWidth(true), 
       height : this.$elWrapper.outerHeight(true) 
      }; 

     }, 
     _layout : function() { 

      this.$slideWrapper = $('<div class="sl-slides-wrapper" />'); 

      // wrap the slides 
      this.$slides.wrapAll(this.$slideWrapper).each(function(i) { 

       var $slide = $(this), 
        // vertical || horizontal 
        orientation = $slide.data('orientation'); 

       $slide.addClass('sl-slide-' + orientation) 
         .children() 
         .wrapAll('<div class="sl-content-wrapper" />') 
         .wrapAll('<div class="sl-content" />'); 

      }); 

      // set the right size of the slider/slides for the current window size 
      this._setSize(); 
      // show first slide 
      this.$slides.eq(this.current).show(); 

     }, 
     _navigate : function(dir, pos) { 

      if(this.isAnimating || this.slidesCount < 2) { 

       return false; 

      } 

      this.isAnimating = true; 

      var self = this, 
       $currentSlide = this.$slides.eq(this.current); 

      // if position is passed 
      if(pos !== undefined) { 

       this.current = pos; 

      } 
      // if not check the boundaries 
      else if(dir === 'next') { 

       this.current = this.current < this.slidesCount - 1 ? ++this.current : 0; 

      } 
      else if(dir === 'prev') { 

       this.current = this.current > 0 ? --this.current : this.slidesCount - 1; 

      } 

      this.options.onBeforeChange($currentSlide, this.current); 

      // next slide to be shown 
      var $nextSlide = this.$slides.eq(this.current), 
       // the slide we want to cut and animate 
       $movingSlide = (dir === 'next') ? $currentSlide : $nextSlide, 

       // the following are the data attrs set for each slide 
       configData = $movingSlide.data(), 
       config = {}; 

      config.orientation = configData.orientation || 'horizontal', 
      config.slice1angle = configData.slice1Rotation || 0, 
      config.slice1scale = configData.slice1Scale || 1, 
      config.slice2angle = configData.slice2Rotation || 0, 
      config.slice2scale = configData.slice2Scale || 1; 

      this._validateValues(config); 

      var cssStyle = config.orientation === 'horizontal' ? { 
        marginTop : -this.size.height/2 
       } : { 
        marginLeft : -this.size.width/2 
       }, 
       // default slide's slices style 
       resetStyle = { 
        'transform' : 'translate(0%,0%) rotate(0deg) scale(1)', 
        opacity : 1 
       }, 
       // slice1 style 
       slice1Style = config.orientation === 'horizontal' ? { 
        'transform' : 'translateY(-' + this.options.translateFactor + '%) rotate(' + config.slice1angle + 'deg) scale(' + config.slice1scale + ')' 
       } : { 
        'transform' : 'translateX(-' + this.options.translateFactor + '%) rotate(' + config.slice1angle + 'deg) scale(' + config.slice1scale + ')' 
       }, 
       // slice2 style 
       slice2Style = config.orientation === 'horizontal' ? { 
        'transform' : 'translateY(' + this.options.translateFactor + '%) rotate(' + config.slice2angle + 'deg) scale(' + config.slice2scale + ')' 
       } : { 
        'transform' : 'translateX(' + this.options.translateFactor + '%) rotate(' + config.slice2angle + 'deg) scale(' + config.slice2scale + ')' 
       }; 

      if(this.options.optOpacity) { 

       slice1Style.opacity = 0; 
       slice2Style.opacity = 0; 

      } 

      // we are adding the classes sl-trans-elems and sl-trans-back-elems to the slide that is either coming "next" 
      // or going "prev" according to the direction. 
      // the idea is to make it more interesting by giving some animations to the respective slide's elements 
      //(dir === 'next') ? $nextSlide.addClass('sl-trans-elems') : $currentSlide.addClass('sl-trans-back-elems'); 

      $currentSlide.removeClass('sl-trans-elems'); 

      var transitionProp = { 
       'transition' : 'all ' + this.options.speed + 'ms ease-in-out' 
      }; 

      // add the 2 slices and animate them 
      $movingSlide.css('z-index', this.slidesCount) 
         .find('div.sl-content-wrapper') 
         .wrap($('<div class="sl-content-slice" />').css(transitionProp)) 
         .parent() 
         .cond(
          dir === 'prev', 
          function() { 

           var slice = this; 
           this.css(slice1Style); 
           setTimeout(function() { 

            slice.css(resetStyle); 

           }, 50); 

          }, 
          function() { 

           var slice = this; 
           setTimeout(function() { 

            slice.css(slice1Style); 

           }, 50); 

          } 
         ) 
         .clone() 
         .appendTo($movingSlide) 
         .cond(
          dir === 'prev', 
          function() { 

           var slice = this; 
           this.css(slice2Style); 
           setTimeout(function() { 

            $currentSlide.addClass('sl-trans-back-elems'); 

            if(self.support) { 

             slice.css(resetStyle).on(self.transEndEventName, function() { 

              self._onEndNavigate(slice, $currentSlide, dir); 

             }); 

            } 
            else { 

             self._onEndNavigate(slice, $currentSlide, dir); 

            } 

           }, 50); 

          }, 
          function() { 

           var slice = this; 
           setTimeout(function() { 

            $nextSlide.addClass('sl-trans-elems'); 

            if(self.support) { 

             slice.css(slice2Style).on(self.transEndEventName, function() { 

              self._onEndNavigate(slice, $currentSlide, dir); 

             }); 

            } 
            else { 

             self._onEndNavigate(slice, $currentSlide, dir); 

            } 

           }, 50); 

          } 
         ) 
         .find('div.sl-content-wrapper') 
         .css(cssStyle); 

      $nextSlide.show(); 

     }, 
     _validateValues : function(config) { 

      // OK, so we are restricting the angles and scale values here. 
      // This is to avoid the slices wrong sides to be shown. 
      // you can adjust these values as you wish but make sure you also ajust the 
      // paddings of the slides and also the options.translateFactor value and scale data attrs 
      if(config.slice1angle > this.options.maxAngle || config.slice1angle < -this.options.maxAngle) { 

       config.slice1angle = this.options.maxAngle; 

      } 
      if(config.slice2angle > this.options.maxAngle || config.slice2angle < -this.options.maxAngle) { 

       config.slice2angle = this.options.maxAngle; 

      } 
      if(config.slice1scale > this.options.maxScale || config.slice1scale <= 0) { 

       config.slice1scale = this.options.maxScale; 

      } 
      if(config.slice2scale > this.options.maxScale || config.slice2scale <= 0) { 

       config.slice2scale = this.options.maxScale; 

      } 
      if(config.orientation !== 'vertical' && config.orientation !== 'horizontal') { 

       config.orientation = 'horizontal' 

      } 

     }, 
     _onEndNavigate : function($slice, $oldSlide, dir) { 

      // reset previous slide's style after next slide is shown 
      var $slide = $slice.parent(), 
       removeClasses = 'sl-trans-elems sl-trans-back-elems'; 

      // remove second slide's slice 
      $slice.remove(); 
      // unwrap.. 
      $slide.css('z-index', 1) 
        .find('div.sl-content-wrapper') 
        .unwrap(); 

      // hide previous current slide 
      $oldSlide.hide().removeClass(removeClasses); 
      $slide.removeClass(removeClasses); 
      // now we can navigate again.. 
      this.isAnimating = false; 
      this.options.onAfterChange($slide, this.current); 

     }, 
     _setSize : function() { 

      // the slider and content wrappers will have the window's width and height 
      var cssStyle = { 
       width : this.size.width, 
       height : this.size.height 
      }; 

      this.$el.css(cssStyle).find('div.sl-content-wrapper').css(cssStyle); 

     }, 
     _loadEvents : function() { 

      var self = this; 

      $window.on('debouncedresize.slitslider', function(event) { 

       // update size values 
       self._getSize(); 
       // set the sizes again 
       self._setSize(); 

      }); 

      if (this.options.keyboard) { 

       $document.on('keydown.slitslider', function(e) { 

        var keyCode = e.keyCode || e.which, 
         arrow = { 
          left: 37, 
          up: 38, 
          right: 39, 
          down: 40 
         }; 

        switch (keyCode) { 

         case arrow.left : 

          self._stopSlideshow(); 
          self._navigate('prev'); 
          break; 

         case arrow.right : 

          self._stopSlideshow(); 
          self._navigate('next'); 
          break; 

        } 

       }); 

      } 

     }, 
     _startSlideshow: function() { 

      var self = this; 

      this.slideshow = setTimeout(function() { 

       self._navigate('next'); 

       if (self.options.autoplay) { 

        self._startSlideshow(); 

       } 

      }, this.options.interval); 

     }, 
     _stopSlideshow: function() { 

      if (this.options.autoplay) { 

       clearTimeout(this.slideshow); 
       this.isPlaying = false; 
       this.options.autoplay = false; 

      } 

     }, 
     _destroy : function(callback) { 

      this.$el.off('.slitslider').removeData('slitslider'); 
      $window.off('.slitslider'); 
      $document.off('.slitslider'); 
      this.$slides.each(function(i) { 

       var $slide = $(this), 
        $content = $slide.find('div.sl-content').children(); 

       $content.appendTo($slide); 
       $slide.children('div.sl-content-wrapper').remove(); 

      }); 
      this.$slides.unwrap(this.$slideWrapper).hide(); 
      this.$slides.eq(0).show(); 
      if(callback) { 

       callback.call(); 

      } 

     }, 
     // public methos: adds more slides to the slider 
     add : function($slides, callback) { 

      this.$slides = this.$slides.add($slides); 

      var self = this; 


      $slides.each(function(i) { 

       var $slide = $(this), 
        // vertical || horizontal 
        orientation = $slide.data('orientation'); 

       $slide.hide().addClass('sl-slide-' + orientation) 
         .children() 
         .wrapAll('<div class="sl-content-wrapper" />') 
         .wrapAll('<div class="sl-content" />') 
         .end() 
         .appendTo(self.$el.find('div.sl-slides-wrapper')); 

      }); 

      this._setSize(); 

      this.slidesCount = this.$slides.length; 

      if (callback) { 

       callback.call($items); 

      } 

     }, 
     // public method: shows next slide 
     next : function() { 

      this._stopSlideshow(); 
      this._navigate('next'); 

     }, 
     // public method: shows previous slide 
     previous : function() { 

      this._stopSlideshow(); 
      this._navigate('prev'); 

     }, 
     // public method: goes to a specific slide 
     jump : function(pos) { 

      pos -= 1; 

      if(pos === this.current || pos >= this.slidesCount || pos < 0) { 

       return false; 

      } 

      this._stopSlideshow(); 
      this._navigate(pos > this.current ? 'next' : 'prev', pos); 

     }, 
     // public method: starts the slideshow 
     // any call to next(), previous() or jump() will stop the slideshow 
     play : function() { 

      if(!this.isPlaying) { 

       this.isPlaying = true; 

       this._navigate('next'); 
       this.options.autoplay = true; 
       this._startSlideshow(); 

      } 

     }, 
     // public method: pauses the slideshow 
     pause : function() { 

      if(this.isPlaying) { 

       this._stopSlideshow(); 

      } 

     }, 
     // public method: check if isAnimating is true 
     isActive : function() { 

      return this.isAnimating; 

     }, 
     // publicc methos: destroys the slicebox instance 
     destroy : function(callback) { 

      this._destroy(callback); 

     } 

    }; 

    var logError = function(message) { 

     if (window.console) { 

      window.console.error(message); 

     } 

    }; 

    $.fn.slitslider = function(options) { 

     var self = $.data(this, 'slitslider'); 

     if (typeof options === 'string') { 

      var args = Array.prototype.slice.call(arguments, 1); 

      this.each(function() { 

       if (!self) { 

        logError("cannot call methods on slitslider prior to initialization; " + 
        "attempted to call method '" + options + "'"); 
        return; 

       } 

       if (!$.isFunction(self[options]) || options.charAt(0) === "_") { 

        logError("no such method '" + options + "' for slitslider self"); 
        return; 

       } 

       self[ options ].apply(self, args); 

      }); 

     } 
     else { 

      this.each(function() { 

       if (self) { 

        self._init(); 

       } 
       else { 

        self = $.data(this, 'slitslider', new $.Slitslider(options, this)); 

       } 

      }); 

     } 

     return self; 

    }; 

})(jQuery, window); 
+0

나는 코드의 빠른 jsfiddle을 만들었지 만 실제 페이지 안에는 jsfiddle을 소개하여 어떻게 작동하는지 알 수없는 스크립트가있어서 js 코드의 저작권 공지 위에 붙여 넣었을 수도있다. 나는 이틀 동안 노력했기 때문에 이것에 대한 이야기를 할 수 있습니다. http://jsfiddle.net/nz07s6b1/3/ –

답변

0

당신은 말한다 _navigate,의 코드를 변경해야 할 것 :

// if not check the boundaries 
else if(dir === 'next') { 

    this.current = this.current < this.slidesCount - 1 ? ++this.current : 0; 

} 
else if(dir === 'prev') { 

    this.current = this.current > 0 ? --this.current : this.slidesCount - 1; 

} 

지정하는 장소의 그 어떤 슬라이드는 다음/이전 슬라이드 (첫 번째/마지막 슬라이드인지 확인)가되어 "원형 효과"를 만듭니다. 그것을 변경해보십시오, 한계라면 슬라이드는 다음/이전 슬라이드로 변경하는 대신 동일하게 유지됩니다. 이 같은

뭔가 : 슬라이드에서 순환 효과를 방지 할 수 있습니다 ...하지만 애니메이션에 문제를 만들 것입니다

// if not check the boundaries 
else if(dir === 'next') { 

    this.current = this.current < this.slidesCount - 1 ? ++this.current : this.slidesCount - 1; 

} 
else if(dir === 'prev') { 

    this.current = this.current > 0 ? --this.current : 0; 

} 

. 애니메이션의 문제점을 해결하려면 this.current (상기 코드)의 값을 변경 한 후 광고 this.prevCurrent = this.current;

  • 추가

    1. _navigate의 시작에서, 이와 같은 함수의 나머지 포장 :

      if (this.prevCurrent != this.current) { .... } else { this.isAnimating = false; }

      화살표가 여전히 작동

    하지만, 첫 번째 (또는 그 반대)에 마지막에서 뛰어하지 않습니다. 그러나 그것은 약간 해키니까, 나는 플러그인이 그 옵션을 가질 것으로 기대했을 것이다.

  • +0

    예, 자동 탐색 기능이있어 자동으로 멈추지 만 운이 없다는 사실을 발견 했으므로 처음 찾았습니다.위의 수정 사항은 어느 정도 작동했지만 탐색 도구는 슬라이드의 변경 사항을 보여줍니다 (어느 슬라이드가 표시되는지 보여주는 아래의 작은 nav 영역이 있으며 1에서 2까지 뒤로 이동할 수 있지만 왼쪽 화살표 만 사용). 그러나 지금은 슬라이드는 실제로 더 이상 움직이지 않으며, 하나에서 다른 슬라이드로 바뀌지 않고 탐색 만 수행됩니다. –

    +0

    의견을 이해할 수 없습니다. $ 무엇이 작동하지 않습니까? –

    0

    실제로 그것을 테스트하지 않은,하지만 당신은 같은 말을하여 해당 옵션을 제공하기 위해 플러그인을 확장 할 수 : 그 코드가 작동하지 않는 경우

    $.Slitslider.prototype._startSlideshow = function() { 
        var self = this; 
        this.rotationCount = ++this.rotationCount || 1; 
        if((this.rotationCount !== this.slidesCount && this.options.playOnce) || !this.options.playOnce) { 
         this.slideshow = setTimeout(function() { 
          self._navigate('next'); 
          if (self.options.autoplay) { 
           self._startSlideshow(); 
          } 
         }, this.options.interval); 
        } 
    }; 
    

    을, 당신은 (그것을 중지를이 방법을 시도 할 수 false로 자동 재생을 설정 슬라이드 쇼) :

    $.Slitslider.prototype._startSlideshow = function() { 
        var self = this; 
        this.rotationCount = ++this.rotationCount || 1; 
        if(this.rotationCount === this.slidesCount && this.options.playOnce) this._stopSlideshow(); 
        this.slideshow = setTimeout(function() { 
         self._navigate('next'); 
         if (self.options.autoplay) { 
          self._startSlideshow(); 
         } 
        }, this.options.interval); 
    }; 
    

    그리고 그 방법은, 당신은 당신의 플러그인 호출에 옵션을 추가하고 말할 수 뭔가 같은 :

    $('div').slitslider({ 
        autoplay: true, 
        playOnce: true 
    }); 
    

    이 코드는 자동 재생이 한 번 재생되도록하고 playOnce 옵션을 true로 설정하면 마지막으로 순환 한 후에 멈 춥니 다.

    +0

    나는 그것을 시험해 보았지만, 슬라이드를 완전히 깨뜨렸다. 너무 많은 번거 로움이 아니라면 html과 jsfiddle을 추가했습니다. 아마도 문제를 더 잘 설명하는 데 도움이 될 것입니다. –

    +0

    어떻게 깨지나요? 오류가 있습니까? – Chad

    +0

    두 슬라이드가 겹쳐서 표시되고 애니메이션이 사라집니다. 그래도 에러가 발생하지 않습니다 ... –

    관련 문제