/*! * Vue-slideshow v1.1.0 * * Copyright (C) 2019, ZhaoGang * Released under the MIT license * * Update: 2019-04-20 */ !(( document, window, Vue ) => { "use strict"; function $ ( selector, context ) { return ( context || document ).querySelector( selector ); } function $$ ( selector, context ) { return [].slice.call( ( context || document ).querySelectorAll( selector ) ); } if ( !$( "style.v-slideshow-style" ) ) { $( "head" ).insertAdjacentHTML( "beforeend", `<style class="v-slideshow-style">.v-slideshow-container{position:relative;width:100%;height:100%;margin:0;padding:0;overflow:hidden;background:#fff}.v-slideshow-wrapper{position:absolute;height:100%;margin:0;padding:0}.v-slideshow-box,.v-slideshow-box a,.v-slideshow-box img{position:absolute;width:100%;height:100%}.v-slideshow-box a,.v-slideshow-box img{display:block;border:0}.v-slideshow-box-fade{opacity:0;transition:.7s;display:none}.v-slideshow-box-show{opacity:1}.v-slideshow-box-block{display:block}.v-slideshow-box.v-slideshow-block{display:block}.v-slideshow-dot{position:absolute;height:10px;bottom:20px;left:50%;transform:translateX(-50%)}.v-slideshow-dot i{display:block;float:left;cursor:pointer;width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,.5);margin:0 5px;transition:.3s}.v-slideshow-dot i.active{background:rgba(255,255,255,1)}.v-slideshow-arrow i{display:block;width:40px;height:40px;background-image:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTU1NzI0MjA4NjA5IiBjbGFzcz0iaWNvbiIgc3R5bGU9IiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjIyOTAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjgiIGhlaWdodD0iMjgiPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTY3MC42NzY5MjkgNzc3LjU5Mjk4NCA0MDMuNjI3NzggNTEzLjM2MjAyMWwyNjUuMzIwNzg1LTI2OC4xNDYxMzNjMTEuNzc2MjA4LTExLjc3NTE4NCAxMS43MzQyNTItMzAuOTA4OTY0LTAuMDkxMDc0LTQyLjczNDI5bC0wLjAwMTAyMyAwYy0xMS44MjUzMjYtMTEuODI2MzUtMzAuOTU4MDgyLTExLjg2NzI4Mi00Mi43MjgxNSAyLjkzMDc0OUwzNDMuMTAwMjQyIDQ4OC40NDA0MjFjLTMuODE3OTU1IDQuMjczMzI3LTguMjA1ODkyIDkuMzIxMjk2LTguOTMzNDYzIDEyLjA0NTMzNy00LjQ3MDgyNSAxMS4xMTIwODItMi4yMzI4NTQgMjQuNzY1MDMzIDYuNzEwODQyIDM1Ljk4NzYzMmwyODYuOTgyMTMgMjg2Ljk4MjEzYzExLjg3NTQ2OCA4Ljg0NzUwNSAzMS4wOTYyMjkgOC44OTM1NTQgNDIuOTIyNTc4LTIuOTMyNzk2QzY4Mi42MDY2MzMgODA4LjY5NjM3NiA2ODIuNTYwNTg0IDc4OS40NzY2MzkgNjcwLjY3NjkyOSA3NzcuNTkyOTg0eiIgcC1pZD0iMjI5MSIgZmlsbD0iI2ZmZmZmZiI+PC9wYXRoPjwvc3ZnPg==");background-color:rgba(0,0,0,.5);background-position:center;background-repeat:no-repeat;position:absolute;top:50%;border-radius:50%;cursor:pointer;transform:translateY(-50%)}.v-slideshow-arrow i:first-child{left:15px}.v-slideshow-arrow i:last-child{right:15px;transform:translateY(-50%) rotate(180deg)}</style> ` ); } Vue.component("vue-slideshow", { template: ` <div class="v-slideshow-container" :data-custom-arrow="Array.isArray( config.arrow ) && config.arrow.join( '|' )" :data-custom-dot="typeof config.dot === 'string' && config.dot" :data-id="'v-slideshow-id-' + Date.now() + ~~(Math.random() * 100000000)" @mouseenter="enter" @mouseleave="leave" > <div class="v-slideshow-wrapper" :style="wrapperStyle"> <div class="v-slideshow-box" v-if="config.effect === 'slide'" :style="boxStyle( 0 )"> <a :href="data[ data.length - 1 ].href"><img :src="data[ data.length - 1 ].src"></a> </div> <div v-for="( list, index ) in data" :class="boxClass( index )" :style="boxStyle( index + 1 )"> <a :href="list.href"><img :src="list.src"></a> </div> <div class="v-slideshow-box" v-if="config.effect === 'slide'" :style="boxStyle( data.length + 1 )"> <a :href="data[ 0 ].href"><img :src="data[ 0 ].src"></a> </div> </div> <div class="v-slideshow-arrow" v-if="config.arrow !== false && !Array.isArray( config.arrow )"> <i @click="arrowEvent( 0 )"></i> <i @click="arrowEvent( 1 )"></i> </div> <div class="v-slideshow-dot" v-if="config.dot !== false && typeof config.dot !== 'string'"> <i v-for="( n, index ) in data" v-if="index < data.length" :class="dotIClass( index )" @click="dotEvent( index )"></i> </div> </div> `, props: [ "data", "config" ], computed: { wrapperStyle: function () { return { width: this.config.effect === "slide" ? ( `${ 100 * ( this.data.length + 2 ) }%` ) : "100%", transform: this.config.effect === "slide" && `translateX(-${ 100 / ( this.data.length + 2 ) }%)` } }, boxClass: function () { return function ( index ) { return { "v-slideshow-box": true, "v-slideshow-box-fade": this.config.effect === "fade" && true, "v-slideshow-box-show": this.config.effect === "fade" && index === 0, "v-slideshow-box-block": this.config.effect === "fade" && index === 0 } } }, boxStyle: function () { return function ( index ) { return { width: `${ this.config.effect !== "slide" ? 100 : ( 100 / ( this.data.length + 2 ) ) }%`, left: this.config.effect === "slide" && `${ 100 / ( this.data.length + 2 ) * index }%` } } }, dotIClass: function () { return function ( index ) { return { active: index === 0 } } } }, methods: { slide: function ( index ) { const ID = window.VueSlideShowIDCache[ this.$el.getAttribute( "data-id" ) ]; ID.animated = true; const w = 100 / ( this.data.length + 2 ); const length = this.data.length; this.dotChange( index, this.config.dot ); if ( index === -1 ) { this.dotChange( length - 1, this.config.dot ); } if ( index === length ) { this.dotChange( 0, this.config.dot ); } const $wrapper = this.$el.querySelector( ".v-slideshow-wrapper" ); $wrapper.style.transition = ".7s"; requestAnimationFrame(() => { $wrapper.style.transform = `translateX(-${ w * ( index + 1 ) }%)`; }) const timer = window.setTimeout(() => { $wrapper.style.transition = "0s"; if ( index === length ) { ID.imageIndex = 0; $wrapper.style.transform = `translateX(-${ w }%)`; } if ( index === -1 ) { ID.imageIndex = length - 1; $wrapper.style.transform = `translateX(-${ w * length }%)`; } window.clearTimeout( timer ); ID.animated = false; }, 700) }, fade: function ( index ) { const ID = window.VueSlideShowIDCache[ this.$el.getAttribute( "data-id" ) ]; ID.animated = true; this.dotChange( index, this.config.dot ); const $box = $$( ".v-slideshow-box", this.$el ); $box.forEach(function ( box, item ) { if ( item === index ) { box.classList.add( "v-slideshow-box-block" ); const timer_1 = window.setTimeout(function () { box.classList.add( "v-slideshow-box-show" ); window.clearTimeout( timer_1 ); }, 16); } else { box.classList.remove( "v-slideshow-box-show" ); const timer_2 = window.setTimeout(function () { box.classList.remove( "v-slideshow-box-block" ); window.clearTimeout( timer_2 ); ID.animated = false; }, 700); } }) }, dotChange: function ( index, useCustomDot ) { window.VueSlideShowIDCache[ this.$el.getAttribute( "data-id" ) ].imageIndex = index; const $dot = typeof useCustomDot === "string" ? [].slice.call( $( useCustomDot ).children ) : $$( ".v-slideshow-dot i", this.$el ); $dot.forEach(function ( dot, item ) { dot.classList.remove( "active" ); if ( item === index ) { dot.classList.add( "active" ); } }) }, dotEvent: function ( index, useCustomDot ) { if ( !window.VueSlideShowIDCache[ this.$el.getAttribute( "data-id" ) ].animated ) { this[ this.config.effect === "fade" ? "fade" : "slide" ]( index ); this.dotChange( index, useCustomDot ); } }, arrowEvent: function ( i ) { if ( !window.VueSlideShowIDCache[ this.$el.getAttribute( "data-id" ) ].animated ) { const ID = window.VueSlideShowIDCache[ this.$el.getAttribute( "data-id" ) ]; if ( i ) { ID.imageIndex++; if ( ID.imageIndex > this.data.length - 1 && this.config.effect !== "slide" ) { ID.imageIndex = 0; } } else { ID.imageIndex--; if ( ID.imageIndex < 0 && this.config.effect !== "slide" ) { ID.imageIndex = this.data.length - 1; } } if ( this.config.effect === "fade" ) { this.fade( ID.imageIndex ); } else { this.slide( ID.imageIndex ); } } }, enter: function () { this.config.autoplay && window.clearInterval( window.VueSlideShowIDCache[ this.$el.getAttribute( "data-id" ) ].autoTimer ); }, leave: function () { this.config.autoplay && this.play(); }, play: function () { window.VueSlideShowIDCache[ this.$el.getAttribute( "data-id" ) ].autoTimer = window.setInterval(() => { this.arrowEvent( 1 ); }, ~~this.config.autoplay); } }, mounted: function () { if ( !window.VueSlideShowIDCache ) { window.VueSlideShowIDCache = {}; } window.VueSlideShowIDCache[ this.$el.getAttribute( "data-id" ) ] = { imageIndex: 0, animated: false, autoTimer: null }; this.config.autoplay && this.play(); let customArrow = this.$el.getAttribute( "data-custom-arrow" ); if ( customArrow ) { customArrow = customArrow.split( "|" ); $( customArrow[ 0 ] ).onclick = () => this.arrowEvent( 0 ); $( customArrow[ 1 ] ).onclick = () => this.arrowEvent( 1 ); } let customDot = this.$el.getAttribute( "data-custom-dot" ); if ( customDot ) { [].slice.call( $( customDot ).children ).forEach(( dot, item ) => { if ( item > this.data.length - 1 ) { return; } dot.onclick = () => this.dotEvent( item, this.config.dot ); }) } } }); Vue.prototype.VueSlideShow = function ( selector, options ) { $( selector ).innerHTML = `<vue-slideshow :data="images" :config="config"></vue-slideshow>`; return new Vue({ el: selector, data: { images: options.images, config: options.config } }); } })( document, window, Vue );