Created
November 20, 2017 15:11
-
-
Save Cheffheid/d19c676047dd456f1b9b7d9560ddb70f to your computer and use it in GitHub Desktop.
Modal / owl carousel codes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* File modal.js | |
* | |
* Deal with multiple modals and their media. | |
*/ | |
window.wdsModal = {}; | |
( function( window, $, app ) { | |
let $modalToggle, | |
$focusableChildren, | |
$player, | |
$tag = document.createElement( 'script' ), | |
$firstScriptTag = document.getElementsByTagName( 'script' )[0], | |
YT; | |
// Constructor. | |
app.init = function() { | |
app.cache(); | |
if ( app.meetsRequirements() ) { | |
$firstScriptTag.parentNode.insertBefore( $tag, $firstScriptTag ); | |
app.bindEvents(); | |
} | |
}; | |
// Cache all the things. | |
app.cache = function() { | |
app.$c = { | |
'window': $( window ), | |
'body': $( 'body' ) | |
}; | |
}; | |
// Do we meet the requirements? | |
app.meetsRequirements = function() { | |
return $( '.modal-trigger' ).length; | |
}; | |
// Combine all events. | |
app.bindEvents = function() { | |
// Trigger a modal to open. | |
app.$c.body.on( 'click touchend', '.modal-trigger', app.openModal ); | |
// Trigger the close button to close the modal. | |
app.$c.body.on( 'click touchend', '.close', app.closeModal ); | |
// Allow the user to close the modal by hitting the esc key. | |
app.$c.body.on( 'keydown', app.escKeyClose ); | |
// Allow the user to close the modal by clicking outside of the modal. | |
app.$c.body.on( 'click touchend', 'div.modal-open', app.closeModalByClick ); | |
// Listen to tabs, trap keyboard if we need to | |
app.$c.body.on( 'keydown', app.trapKeyboardMaybe ); | |
}; | |
// Open the modal. | |
app.openModal = function( event ) { | |
event.preventDefault(); | |
// Store the modal toggle element | |
$modalToggle = $( this ); | |
// Figure out which modal we're opening and store the object. | |
let $modal = $( $( this ).data( 'target' ) ), | |
index = $( this ).data( 'index' ); | |
// Display the modal. | |
$modal.addClass( 'modal-open' ); | |
// Add body class. | |
app.$c.body.addClass( 'modal-open' ); | |
// Find the focusable children of the modal. | |
// This list may be incomplete, really wish jQuery had the :focusable pseudo like jQuery UI does. | |
// For more about :input see: https://api.jquery.com/input-selector/ | |
$focusableChildren = $modal.find( 'a, :input, [tabindex]' ); | |
// Ideally, there is always one (the close button), but you never know. | |
if ( 0 < $focusableChildren.length ) { | |
// Shift focus to the first focusable element. | |
$focusableChildren[0].focus(); | |
} | |
// Trigger modal open event. | |
$modal.trigger( 'modal-open', [ index ] ); | |
}; | |
// Close the modal. | |
app.closeModal = function( event ) { | |
event.preventDefault(); | |
// Figure the opened modal we're closing and store the object. | |
let $modal = $( $( 'div.modal-open .close' ).data( 'target' ) ), | |
// Find the iframe in the $modal object. | |
$iframe = $modal.find( 'iframe' ), | |
// Find any video tags. | |
$videos = $modal.find( 'video' ); | |
// Only do this if there are any iframes. | |
if ( $iframe.length ) { | |
// Get the iframe src URL. | |
let url = $iframe.attr( 'src' ); | |
// Removing/Readding the URL will effectively break the YouTube API. | |
// So let's not do that when the iframe URL contains the enablejsapi parameter. | |
if ( ! url.includes( 'enablejsapi=1' ) ) { | |
// Remove the source URL, then add it back, so the video can be played again later. | |
$iframe.attr( 'src', '' ).attr( 'src', url ); | |
} else { | |
// Use the YouTube API to stop the video. | |
$player.stopVideo(); | |
} | |
} | |
// Kill any videos that may be in this modal. | |
if ( $videos.length ) { | |
$videos.each( function() { | |
$( this ).get( 0 ).pause(); | |
}); | |
} | |
// Finally, hide the modal. | |
$modal.removeClass( 'modal-open' ); | |
// Remove the body class. | |
app.$c.body.removeClass( 'modal-open' ); | |
$modal.trigger( 'modal-close' ); | |
// Revert focus back to toggle element | |
$modalToggle.focus(); | |
}; | |
// Close if "esc" key is pressed. | |
app.escKeyClose = function( event ) { | |
if ( 27 === event.keyCode ) { | |
app.closeModal( event ); | |
} | |
}; | |
// Close if the user clicks outside of the modal | |
app.closeModalByClick = function( event ) { | |
// If the parent container is NOT the modal dialog container, close the modal | |
if ( ! $( event.target ).parents( 'div' ).hasClass( 'modal-dialog' ) ) { | |
app.closeModal( event ); | |
} | |
}; | |
// Trap the keyboard into a modal when one is active. | |
app.trapKeyboardMaybe = function( event ) { | |
// We only need to do stuff when the modal is open and tab is pressed. | |
if ( 9 === event.which && 0 < $( '.modal-open' ).length ) { | |
let $focused = $( ':focus' ), | |
focusIndex = $focusableChildren.index( $focused ); | |
if ( 0 === focusIndex && event.shiftKey ) { | |
// If this is the first focusable element, and shift is held when pressing tab, go back to last focusable element. | |
$focusableChildren[ $focusableChildren.length - 1 ].focus(); | |
event.preventDefault(); | |
} else if ( ! event.shiftKey && focusIndex === $focusableChildren.length - 1 ) { | |
// If this is the last focusable element, and shift is not held, go back to the first focusable element. | |
$focusableChildren[0].focus(); | |
event.preventDefault(); | |
} | |
} | |
}; | |
// Hook into YouTube <iframe>. | |
app.onYouTubeIframeAPIReady = function() { | |
let $modal = $( 'div.modal' ), | |
$iframeid = $modal.find( 'iframe' ).attr( 'id' ); | |
$player = new YT.Player( $iframeid, { | |
events: { | |
'onReady': app.onPlayerReady, | |
'onStateChange': app.onPlayerStateChange | |
} | |
} ); | |
}; | |
// Do something on player ready. | |
app.onPlayerReady = function() { | |
}; | |
// Do something on player state change. | |
app.onPlayerStateChange = function() { | |
// Set focus to the first focusable element inside of the modal the player is in. | |
$( event.target.a ).parents( '.modal' ).find( 'a, :input, [tabindex]' ).first().focus(); | |
}; | |
// Engage! | |
$( app.init ); | |
}( window, jQuery, window.wdsModal ) ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* File owl-carousel.js | |
* | |
* Initiate Owl Carousels | |
*/ | |
window.wdsOwlCarousels = {}; | |
( function( window, $, app ) { | |
let carouselOptions = { | |
lazyLoad: true, | |
center: true, | |
loop: true, | |
items: 1, | |
margin: 25, | |
nav: true, | |
navElement: 'button', | |
startPosition: 0, | |
navText: [ | |
'‹', | |
'›' | |
], | |
autoWidth: false, | |
video: false, | |
responsiveClass: true, | |
responsive: { | |
1024: { | |
autowidth: true | |
} | |
} | |
}; | |
// Constructor. | |
app.init = function() { | |
app.cache(); | |
if ( app.meetsRequirements() ) { | |
app.bindEvents(); | |
} | |
}; | |
// Cache all the things. | |
app.cache = function() { | |
app.$c = { | |
window: $( window ), | |
modals: $( '.modal' ), | |
carousels: $( '.owl-carousel' ) | |
}; | |
}; | |
// Combine all events. | |
app.bindEvents = function() { | |
app.$c.modals.on( 'modal-open', app.initializeCarouselMaybe ); // This is a custom event triggered in modal.js | |
app.$c.modals.on( 'modal-close', app.destroyCarousel ); | |
}; | |
// Do we meet the requirements? | |
app.meetsRequirements = function() { | |
return app.$c.carousels.length; | |
}; | |
// Initialize Carousel. | |
app.initializeCarouselMaybe = function( event, index ) { | |
const $modalCarousel = $( this ).find( '.owl-carousel' ); | |
if ( 0 === $modalCarousel.length ) { | |
return; | |
} | |
if ( index ) { | |
carouselOptions.startPosition = parseInt( index, 10 ); | |
} | |
if ( 0 < $modalCarousel.find( 'video' ).length ) { | |
carouselOptions.video = true; | |
$modalCarousel.on( 'changed.owl.carousel', app.lazyLoadVideo ); | |
$modalCarousel.on( 'change.owl.carousel', app.pauseVideo ); | |
} | |
$modalCarousel.owlCarousel( carouselOptions ); | |
}; | |
// Burn the carousel down when the modal closes. 🔥 | |
app.destroyCarousel = function() { | |
const $modal = $( this ), | |
$carousel = $modal.find( '.owl-carousel' ); | |
$carousel.trigger( 'destroy.owl.carousel' ); | |
}; | |
// Allow video tags to be lazy loaded through a data-src attribute. | |
app.lazyLoadVideo = function( event ) { | |
let current = event.item.index, | |
currentVideo = $( event.target ).find( '.owl-item' ).eq( current ).find( 'video' ), | |
currentVideoSource = currentVideo.find( 'source' ); | |
// Play if video found | |
if ( currentVideo.length ) { | |
let currentVideoSrc = currentVideoSource.attr( 'data-src' ); | |
currentVideoSource.attr( 'src', currentVideoSrc ); | |
currentVideo[0].load(); | |
} | |
}; | |
// Pauses a video inside of a carousel slide. | |
app.pauseVideo = function( event ) { | |
// Bail if this is not a position/slide change. | |
if ( 'position' !== event.property.name ) { | |
return false; | |
} | |
// Pause the video. | |
$( event.target ).find( '.owl-item:not(.cloned) video' ).get( event.page.index ).pause(); | |
}; | |
// Engage! | |
$( app.init ); | |
}( window, jQuery, window.wdsOwlCarousels ) ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment