123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- /**
- * The component for synchronizing a slider with another.
- *
- * @author Naotoshi Fujita
- * @copyright Naotoshi Fujita. All rights reserved.
- */
- import { subscribe } from '../../utils/dom';
- import { LOOP } from '../../constants/types';
- import { IDLE } from "../../constants/states";
- /**
- * The event name for sync.
- *
- * @type {string}
- */
- const SYNC_EVENT = 'move.sync';
- /**
- * The keys for triggering the navigation button.
- *
- * @type {String[]}
- */
- const TRIGGER_KEYS = [ ' ', 'Enter', 'Spacebar' ];
- /**
- * The component for synchronizing a slider with another.
- *
- * @param {Splide} Splide - A Splide instance.
- *
- * @return {Object} - The component object.
- */
- export default ( Splide ) => {
- /**
- * Keep the sibling Splide instance.
- *
- * @type {Splide}
- */
- let sibling = Splide.sibling;
- /**
- * Whether the sibling slider is navigation or not.
- *
- * @type {Splide|boolean}
- */
- const isNavigation = sibling && sibling.options.isNavigation;
- /**
- * Layout component object.
- *
- * @type {Object}
- */
- const Sync = {
- /**
- * Required only when the sub slider is available.
- *
- * @type {boolean}
- */
- required: !! sibling,
- /**
- * Called when the component is mounted.
- */
- mount() {
- syncMain();
- syncSibling();
- if ( isNavigation ) {
- bind();
- }
- },
- /**
- * Called after all components are mounted.
- */
- mounted() {
- if ( isNavigation ) {
- sibling.emit( 'navigation:mounted', Splide );
- }
- },
- };
- /**
- * Listen the primary slider event to move secondary one.
- * Must unbind a handler at first to avoid infinite loop.
- */
- function syncMain() {
- Splide.on( SYNC_EVENT, ( newIndex, prevIndex, destIndex ) => {
- sibling
- .off( SYNC_EVENT )
- .go( sibling.is( LOOP ) ? destIndex : newIndex, false );
- syncSibling();
- } );
- }
- /**
- * Listen the secondary slider event to move primary one.
- * Must unbind a handler at first to avoid infinite loop.
- */
- function syncSibling() {
- sibling.on( SYNC_EVENT, ( newIndex, prevIndex, destIndex ) => {
- Splide
- .off( SYNC_EVENT )
- .go( Splide.is( LOOP ) ? destIndex : newIndex, false );
- syncMain();
- } );
- }
- /**
- * Listen some events on each slide.
- */
- function bind() {
- const Slides = sibling.Components.Slides.getSlides( true, true );
- Slides.forEach( Slide => {
- const slide = Slide.slide;
- /*
- * Listen mouseup and touchend events to handle click.
- * Need to check "IDLE" status because slides can be moving by Drag component.
- */
- subscribe( slide, 'mouseup touchend', e => {
- // Ignore a middle or right click.
- if ( ! e.button || e.button === 0 ) {
- moveSibling( Slide.index );
- }
- } );
- /*
- * Subscribe keyup to handle Enter and Space key.
- * Note that Array.includes is not supported by IE.
- */
- subscribe( slide, 'keyup', e => {
- if ( TRIGGER_KEYS.indexOf( e.key ) > -1 ) {
- e.preventDefault();
- moveSibling( Slide.index );
- }
- }, { passive: false } );
- } );
- }
- function moveSibling( index ) {
- if ( Splide.State.is( IDLE ) ) {
- sibling.go( index );
- }
- }
- return Sync;
- }
|