------index06.html
------index06.html以上 ------style.css .slider { position: relative; width: 100%; height: 100%; overflow: hidden; } .slider__wrapper { height: 100%; list-style: none; overflow: hidden; *zoom: 1; -webkit-backface-visibility: hidden; -webkit-transform-style: preserve-3d; } .slider__item { height: 100%; float: left; clear: none; } .slider__arrows-item { position: absolute; display: block; margin-bottom: -20px; padding: 20px; cursor: pointer; } .slider__arrows-item--right { bottom: 50%; right: 30px; } .slider__arrows-item--left { bottom: 50%; left: 30px; } .slider__nav { position: absolute; bottom: 30px; } .slider__nav-item { width: 12px; height: 12px; float: left; clear: none; display: block; margin: 0 5px; background: #fff; } .slider__nav-item--current { background: #ccc; } .slider__nav-item:hover { background: #ccc; } ------style.css以上 ------jquery.glide.js /*! * Glide.js * Version: 1.0.7 * Simple, lightweight and fast jQuery slider * Author: @JedrzejChalubek * Site: http://jedrzejchalubek.com/ * Licensed under the MIT license */ ;(function ($, window, document, undefined) { var name = 'glide', defaults = { // {Int or Bool} False for turning off autoplay autoplay: 4000, // {Bool} Pause autoplay on mouseover slider hoverpause: true, // {Bool} Circual play circular: true, // {String} Transition type ('slide' or 'fade') transitionType: 'slide', // {Int} Animation time animationDuration: 500, // {String} Animation easing function animationTimingFunc: 'cubic-bezier(0.165, 0.840, 0.440, 1.000)', /** * {Bool or String} Show/hide/appendTo arrows * True for append arrows to slider wrapper * False for not appending arrows * Id or class name (e.g. '.class-name') for appending to specific HTML markup */ arrows: true, // {String} Arrows wrapper class arrowsWrapperClass: 'slider__arrows', // {String} Main class for both arrows arrowMainClass: 'slider__arrows-item', // {String} Right arrow arrowRightClass: 'slider__arrows-item--right', // {String} Right arrow text arrowRightText: '次へ→', // {String} Left arrow arrowLeftClass: 'slider__arrows-item--left', // {String} Left arrow text arrowLeftText: '←前へ', /** * {Bool or String} Show/hide/appendTo bullets navigation * True for append arrows to slider wrapper * False for not appending arrows * Id or class name (e.g. '.class-name') for appending to specific HTML markup */ navigation: true, // {Bool} Center bullet navigation navigationCenter: true, // {String} Navigation class navigationClass: 'slider__nav', // {String} Navigation item class navigationItemClass: 'slider__nav-item', // {String} Current navigation item class navigationCurrentItemClass: 'slider__nav-item--current', // {String} Current slider item class sliderCurrentItemClass: 'slider__item--current', // {Bool} Slide on left/right keyboard arrows press keyboard: true, // {Int or Bool} Touch settings touchDistance: 60, // {Bool} Use JS animation ( $.animate() ) instead of CSS transition and transform forceJS: false, // {Function} Callback before plugin init beforeInit: function() {}, // {Function} Callback after plugin init afterInit: function() {}, // {Function} Callback before slide change beforeTransition: function() {}, // {Function} Callback after slide change afterTransition: function() {} }; /** * Slider Constructor * @param {Object} parent * @param {Object} options */ function Glide(parent, options) { // Cache this var self = this; // Extend options this.options = $.extend({}, defaults, options); // Current slide id this.currentSlide = 0; // Check options variable for forceJS (Fallback) if (this.options.forceJS) { // Set cssSupport to false if forceJS is set to true this.cssSupport = false; } else { // If CSS3 Transition isn't supported switch cssSupport variable to false and use $.animate() this.cssSupport = ( !this.css.isSupported("transition") || !this.css.isSupported("transform") ) ? false : true; } // Disable circular when fade is set for transition if (this.options.transitionType == "fade") { this.options.circular = false; } // If circular set offset, two cloned slides this.offset = (this.options.circular) ? 2 : 0; // Callbacks before plugin init this.options.beforeInit.call(this); // Sidebar this.parent = parent; // Initialize this.init(); // Start autoplay this.play(); // Callback after plugin init this.options.afterInit.call(this); /** * API * Returning slider methods */ return { /** * Get current slide number * @return {Int} */ current: function() { return -(self.currentSlide) + 1; }, /** * Reinit * Rebuild and recalculate dimensions of slider elements */ reinit: function() { self.init(); }, /** * Destroy * Revert init modifications and freeze slides */ destroy: function(){ self.destroy(); }, /** * Start autoplay */ play: function() { self.play(); }, /** * Stop autoplay */ pause: function() { self.pause(); }, /** * Slide one forward * @param {Function} callback */ next: function(callback) { self.slide(1, false, callback); }, /** * Slide one backward * @param {Function} callback */ prev: function(callback) { self.slide(-1, false, callback); }, /** * Jump to specifed slide * @param {Int} distance * @param {Function} callback */ jump: function(distance, callback) { self.slide(distance-1, true, callback); }, /** * Append navigation to specifet target * @param {Mixed} target */ nav: function(target) { /** * If navigation wrapper already exist * Remove it, protection before doubled navigation */ if (self.navigation.wrapper) self.navigation.wrapper.remove(); // While target isn't specifed, use slider wrapper self.options.navigation = (target) ? target : self.options.navigation; // Build self.navigation(); }, /** * Append arrows to specifet target * @param {Mixed} target */ arrows: function(target) { /** * If arrows wrapper already exist * Remove it, protection before doubled arrows */ if (self.arrows.wrapper) self.arrows.wrapper.remove(); // While target isn't specifed, use slider wrapper self.options.arrows = (target) ? target : self.options.arrows; // Build self.arrows(); } }; } /** * Building slider */ Glide.prototype.build = function() { /* * Build slides for fade */ if (this.options.transitionType == 'fade') { // Reset opacity to all slides this.slides.css({opacity: 0, 'position': 'absolute' }); if (this.cssSupport) { this.slides.css({ 'transition': 'opacity ' + this.options.animationDuration + 'ms linear' }); } // Add some css properties to first slider this.slides.filter(':first-child') .css({ opacity: 1, 'z-index': '2'}).animate({ opacity: 1 }, this.options.animationDuration); } /** * Attatch bindings */ this.bindings(); /* * Add sliderCurrentItemClass to the first slider */ this.slides.filter(':first-child') .addClass(this.options.sliderCurrentItemClass); /** * There is more than one slide */ if (this.slides.length > 1) { /** * Circular * If circular option is true * Append left and right arrow */ if (this.options.circular) this.circular(); /** * Arrows * If arrows option is true * Append left and right arrow */ if (this.options.arrows) this.arrows(); /** * Navigation * If navigation option is true * Append navigation item for each slide */ if (this.options.navigation) this.navigation(); } /** * Attatch events */ this.events(); }; /** * Build circular DOM elements * Clone first and last slide * Set wrapper width with addional slides * Move slider wrapper to first slide */ Glide.prototype.circular = function() { /** * Clone first and last slide * and set width for each * Remove sliderCurrentItemClass on first cloned element */ this.firstClone = this.slides.filter(':first-child').clone().width(this.slides.spread).removeClass(this.options.sliderCurrentItemClass); this.lastClone = this.slides.filter(':last-child').clone().width(this.slides.spread); /** * Append clodes slides to slider wrapper at the beginning and end * Increase wrapper with with values of addional slides * Clear translate and skip cloned last slide at the beginning */ this.wrapper.append(this.firstClone).prepend(this.lastClone).width( this.parent.width() * (this.slides.length+2) ) .trigger('clearTransition') .trigger('setTranslate', [-this.slides.spread]); }; /** * Building navigation DOM */ Glide.prototype.navigation = function() { this.navigation.items = {}; // Navigation wrapper this.navigation.wrapper = $('
', { 'class': this.options.navigationClass }).appendTo( /** * Setting append target * If option is true set default target, that is slider wrapper * Else get target set in options * @type {Bool or String} */ (this.options.navigation === true) ? this.parent : this.options.navigation ); for (var i = 0; i < this.slides.length; i++) { this.navigation.items[i] = $('', { 'href': '#', 'class': this.options.navigationItemClass, // Direction and distance -> Item index forward 'data-distance': i }).appendTo(this.navigation.wrapper); } // Add navCurrentItemClass to the first navigation item this.navigation.items[0].addClass(this.options.navigationCurrentItemClass); // If centered option is true if (this.options.navigationCenter) { // Center bullet navigation this.navigation.wrapper.css({ 'left': '50%', 'width': this.navigation.wrapper.children().outerWidth(true) * this.navigation.wrapper.children().length, 'margin-left': -(this.navigation.wrapper.outerWidth(true)/2) }); } }; /** * Building arrows DOM */ Glide.prototype.arrows = function() { /** * Arrows wrapper * @type {Obejct} */ this.arrows.wrapper = $('
', { 'class': this.options.arrowsWrapperClass }).appendTo( /** * Setting append target * If option is true set default target, that is slider wrapper * Else get target set in options * @type {Bool or String} */ (this.options.arrows === true) ? this.parent : this.options.arrows ); /** * Right arrow * @type {Obejct} */ this.arrows.right = $('
', { 'class': this.options.arrowMainClass + ' ' + this.options.arrowRightClass, // Direction and distance -> One forward 'data-distance': '1', 'html': this.options.arrowRightText }).appendTo(this.arrows.wrapper); /** * Left arrow * @type {Object} */ this.arrows.left = $('
', { 'class': this.options.arrowMainClass + ' ' + this.options.arrowLeftClass, // Direction and distance -> One backward 'data-distance': '-1', 'html': this.options.arrowLeftText }).appendTo(this.arrows.wrapper); }; /** * Function bindings */ Glide.prototype.bindings = function() { var self = this, o = this.options, prefix = this.css.getPrefix(); /** * Setup slider wrapper bindings * for translate and transition control */ this.wrapper.bind({ /** * Set transition */ 'setTransition': function() { $(this).css( prefix + 'transition', prefix + 'transform ' + o.animationDuration + 'ms ' + o.animationTimingFunc); }, /** * Clear transition * for immediate jump effect */ 'clearTransition': function() { $(this).css( prefix + 'transition', 'none'); }, /** * Set translate value * @param {Object} event * @param {Ind} translate */ 'setTranslate': function(event, translate) { // if css3 suported set translate3d if (self.cssSupport) $(this).css( prefix + 'transform', 'translate3d(' + translate + 'px, 0px, 0px)'); // if not set left margin else $(this).css('margin-left', translate); } }); }; /** * Events controllers */ Glide.prototype.events = function() { /** * Swipe * If swipe option is true * Attach touch events */ if (this.options.touchDistance) { this.parent.on({ 'touchstart MSPointerDown': $.proxy(this.events.touchstart, this), 'touchmove MSPointerMove': $.proxy(this.events.touchmove, this), 'touchend MSPointerUp': $.proxy(this.events.touchend, this) }); } /** * Arrows * If arrows exists * Attach click event */ if (this.arrows.wrapper) { $(this.arrows.wrapper).children().on('click touchstart', $.proxy(this.events.arrows, this) ); } /** * Navigation * If navigation exists * Attach click event */ if (this.navigation.wrapper) { $(this.navigation.wrapper).children().on('click touchstart', $.proxy(this.events.navigation, this) ); } /** * Keyboard * If keyboard option is true * Attach press event */ if (this.options.keyboard) { $(document).on('keyup.glideKeyup', $.proxy(this.events.keyboard, this) ); } /** * Slider hover * If hover option is true * Attach hover event */ if (this.options.hoverpause) { this.parent.on('mouseover mouseout', $.proxy(this.events.hover, this) ); } /** * Slider resize * On window resize * Attach resize event */ $(window).on('resize', $.proxy(this.events.resize, this) ); }; /** * Navigation event controller * On click in navigation item get distance * Then slide specified distance with jump */ Glide.prototype.events.navigation = function(event) { if ( !this.wrapper.attr('disabled') ) { // Prevent default behaviour event.preventDefault(); // Slide distance specified in data attribute this.slide( $(event.currentTarget).data('distance'), true ); } }; /** * Arrows event controller * On click in arrows get direction and distance * Then slide specified distance without jump * @param {Obejct} event */ Glide.prototype.events.arrows = function(event) { if ( !this.wrapper.attr('disabled') ) { // Prevent default behaviour event.preventDefault(); // Slide distance specified in data attribute this.slide( $(event.currentTarget).data('distance'), false ); } }; /** * Keyboard arrows event controller * Keyboard left and right arrow keys press */ Glide.prototype.events.keyboard = function(event) { if ( !this.wrapper.attr('disabled') ) { // Next if (event.keyCode === 39) this.slide(1); // Prev if (event.keyCode === 37) this.slide(-1); } }; /** * When mouse is over slider, pause autoplay * On out, start autoplay again */ Glide.prototype.events.hover = function(event) { // Pasue autoplay this.pause(); // When mouse left slider or touch end, start autoplay anew if (event.type === 'mouseout') this.play(); }; /** * When resize browser window * Reinit plugin for new slider dimensions * Correct crop to current slide */ Glide.prototype.events.resize = function(event) { // Reinit plugin (set new slider dimensions) this.dimensions(); // Crop to current slide this.slide(0); }; /** * Disable events thats controls slide changes */ Glide.prototype.disableEvents = function() { this.wrapper.attr( 'disabled', true ); }; /** * Enable events thats controls slide changes */ Glide.prototype.enableEvents = function() { this.wrapper.attr( 'disabled', false ); }; /** * Touch start * @param {Object} e event */ Glide.prototype.events.touchstart = function(event) { if ( !this.wrapper.attr('disabled') ) { // Cache event var touch = event.originalEvent.touches[0] || event.originalEvent.changedTouches[0]; // Get touch start points this.events.touchStartX = touch.pageX; this.events.touchStartY = touch.pageY; this.events.touchSin = null; } }; /** * Touch move * From swipe length segments calculate swipe angle * @param {Obejct} e event */ Glide.prototype.events.touchmove = function(event) { if ( !this.wrapper.attr('disabled') ) { // Cache event var touch = event.originalEvent.touches[0] || event.originalEvent.changedTouches[0]; // Calculate start, end points var subExSx = touch.pageX - this.events.touchStartX; var subEySy = touch.pageY - this.events.touchStartY; // Bitwise subExSx pow var powEX = Math.abs( subExSx << 2 ); // Bitwise subEySy pow var powEY = Math.abs( subEySy << 2 ); // Calculate the length of the hypotenuse segment var touchHypotenuse = Math.sqrt( powEX + powEY ); // Calculate the length of the cathetus segment var touchCathetus = Math.sqrt( powEY ); // Calculate the sine of the angle this.events.touchSin = Math.asin( touchCathetus/touchHypotenuse ); if ( (this.events.touchSin * (180 / Math.PI)) < 45 ) event.preventDefault(); } }; /** * Touch end * @param {Object} e event */ Glide.prototype.events.touchend = function(event) { if ( !this.wrapper.attr('disabled') ) { // Cache event var touch = event.originalEvent.touches[0] || event.originalEvent.changedTouches[0]; // Calculate touch distance var touchDistance = touch.pageX - this.events.touchStartX; // While touch is positive and greater than distance set in options if ( (touchDistance > this.options.touchDistance) && ( (this.events.touchSin * (180 / Math.PI)) < 45) ) { // Slide one backward this.slide(-1); // While touch is negative and lower than negative distance set in options } else if ( (touchDistance < -this.options.touchDistance) && ( (this.events.touchSin * (180 / Math.PI)) < 45) ) { // Slide one forward this.slide(1); } } }; /** * Slides change & animate logic * @param {int} distance * @param {bool} jump * @param {function} callback */ Glide.prototype.slide = function(distance, jump, callback) { // If there is one slide, escape if (this.slides.length <= 1) { return false; } /** * Stop autoplay * Clearing timer */ this.pause(); // Callbacks before slide change this.options.beforeTransition.call(this); // Setup variables var self = this, currentSlide = (jump) ? 0 : this.currentSlide, slidesLength = -(this.slides.length-1), fromFirst = false, fromLast = false; /** * Check if current slide is first and direction is previous, then go to last slide * or current slide is last and direction is next, then go to the first slide * else change current slide normally */ if ( currentSlide === 0 && distance === -1 ) { fromFirst = true; currentSlide = slidesLength; } else if ( currentSlide === slidesLength && distance === 1 ) { fromLast = true; currentSlide = 0; } else { currentSlide = currentSlide + (-distance); } /** * Crop to current slide. * Mul slide width by current slide number. */ var offset = this.slides.spread * currentSlide; /* * Add sliderCurrentItemClass to active slider. * Get right element when circular is active */ if (this.options.circular) { $('.slider__wrapper').children() .eq(-currentSlide + 1).addClass(this.options.sliderCurrentItemClass) .siblings() .removeClass(this.options.sliderCurrentItemClass); } else { $('.slider__wrapper').children() .eq(-currentSlide).addClass(this.options.sliderCurrentItemClass) .siblings() .removeClass(this.options.sliderCurrentItemClass); } /** * While circular decrease offset with the width of single slide * When fromFirst and fromLast flags are set, unbind events thats controls changing * When fromLast flags is set, set offset to slide width mulled by slides count without cloned slides * When fromFirst flags is set, set offset to zero */ if (this.options.circular) { offset = offset - this.slides.spread; if (fromLast || fromFirst) this.disableEvents(); if (fromLast) offset = this.slides.spread * (slidesLength - 2); if (fromFirst) offset = 0; } /** * Slide change animation * While CSS3 is supported use offset * if not, use $.animate(); */ if (this.options.transitionType == 'slide') { if (this.cssSupport) this.wrapper.trigger('setTransition').trigger('setTranslate', [offset]); else this.wrapper.stop().animate({ 'margin-left': offset }, this.options.animationDuration); } else { /* * Change duration value when css transition is supported */ if (this.cssSupport) { tempAnimationDuration = 0; // transition is done by CSS } else { tempAnimationDuration = this.options.animationDuration; } // Set item current class to slider $('.slider__wrapper').children() .eq(-currentSlide) .css('z-index', '2') .stop(true, false).animate({ opacity: 1 },tempAnimationDuration) .siblings() .css('z-index', '1') .stop(true, true).delay(tempAnimationDuration).animate({ opacity: 0 },0); } /** * While circular */ if (this.options.circular) { /** * When fromFirst and fromLast flags are set * after animation clear transition and bind events that control slides changing */ if (fromFirst || fromLast) { this.afterAnimation(function(){ self.wrapper.trigger('clearTransition'); self.enableEvents(); }); } /** * When fromLast flag is set * after animation make immediate jump from cloned slide to proper one */ if (fromLast) { this.afterAnimation(function(){ fromLast = false; self.wrapper.trigger('setTranslate', [-self.slides.spread]); }); } /** * When fromFirst flag is set * after animation make immediate jump from cloned slide to proper one */ if (fromFirst) { this.afterAnimation(function(){ fromFirst = false; self.wrapper.trigger('setTranslate', [self.slides.spread * (slidesLength-1)]); }); } } // Set to navigation item current class if (this.options.navigation && this.navigation.wrapper) { $('.' + this.options.navigationClass, (this.options.navigation === true) ? this.parent : this.options.navigation).children() .eq(-currentSlide) .addClass(this.options.navigationCurrentItemClass) .siblings() .removeClass(this.options.navigationCurrentItemClass); } // Update current slide globaly this.currentSlide = currentSlide; // Callbacks after slide change this.afterAnimation(function(){ self.options.afterTransition.call(self); if ( (callback !== 'undefined') && (typeof callback === 'function') ) callback(); }); /** * Start autoplay * Setting up timer */ this.play(); }; /** * Autoplay logic * Setup counting */ Glide.prototype.play = function() { // Cache this var self = this; /** * If autoplay turn on * Slide one forward after a set time */ if (this.options.autoplay) { this.auto = setInterval(function() { self.slide(1, false); }, this.options.autoplay); } }; /** * Autoplay pause * Clear counting */ Glide.prototype.pause = function() { /** * If autoplay turn on * Clear interial */ if (this.options.autoplay) this.auto = clearInterval(this.auto); }; /** * Call callback after animation duration * Added 10 ms to duration to be sure is fired after animation * @param {Function} callback */ Glide.prototype.afterAnimation = function(callback) { setTimeout(function(){ callback(); }, this.options.animationDuration + 10); }; /** * Dimensions * Get & set dimensions of slider elements */ Glide.prototype.dimensions = function() { // Get slide width this.slides.spread = this.parent.width(); // Set wrapper width if (this.options.transitionType == 'slide') { this.wrapper.width(this.slides.spread * (this.slides.length + this.offset)); } else { this.wrapper.width(this.slides.spread); } // Set slide width this.slides.add(this.firstClone).add(this.lastClone).width(this.slides.spread); }; /** * Destroy * Revert init modifications and freeze slides */ Glide.prototype.destroy = function() { this.parent.unbind(); this.wrapper.unbind(); this.wrapper.removeAttr("style"); $(this.navigation.wrapper).children().unbind(); $(this.arrows.wrapper).children().unbind(); this.slide(0, true); this.pause(); if(this.options.circular) { this.firstClone.remove(); this.lastClone.remove(); } }; /** * Initialize * Set wrapper * Set slides * Set animation type */ Glide.prototype.init = function() { // Set slides wrapper this.wrapper = this.parent.children(); // Set slides this.slides = this.wrapper.children(); // Set slider dimentions this.dimensions(); // Build DOM this.build(); }; /** * Methods for css3 management */ Glide.prototype.css = { /** * Check css3 support * @param {String} Declaration name to check * @return {Boolean} */ isSupported: function(declaration) { var isSupported = false, prefixes = 'Khtml ms O Moz Webkit'.split(' '), clone = document.createElement('div'), declarationCapital = null; declaration = declaration.toLowerCase(); if (clone.style[declaration] !== undefined) isSupported = true; if (isSupported === false) { declarationCapital = declaration.charAt(0).toUpperCase() + declaration.substr(1); for( var i = 0; i < prefixes.length; i++ ) { if( clone.style[prefixes[i] + declarationCapital ] !== undefined ) { isSupported = true; break; } } } if (window.opera) { if (window.opera.version() < 13) isSupported = false; } if (isSupported === 'undefined' || isSupported === undefined) isSupported = false; return isSupported; }, /** * Get browser css prefix * @return {String} Returns prefix in "-{prefix}-" format */ getPrefix: function () { if (!window.getComputedStyle) return ''; var styles = window.getComputedStyle(document.documentElement, ''); return '-' + (Array.prototype.slice .call(styles) .join('') .match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o']) )[1] + '-'; } }; $.fn[name] = function(options) { return this.each(function () { if ( !$.data(this, 'api_' + name) ) { $.data(this, 'api_' + name, new Glide($(this), options) ); } }); }; })(jQuery, window, document); ------jquery.glide.js以上