qa-prevention-gwj-vue/static/bi/tree/js/vue-slideshow.js

240 lines
10 KiB
JavaScript
Raw Permalink Normal View History

2023-11-06 18:11:01 +08:00
/*
* 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 );