From 1d5cd9409e8c46bcba52f32e0e99edf4576daf7b Mon Sep 17 00:00:00 2001 From: Manos Psychogyiopoulos Date: Mon, 13 Mar 2017 18:58:39 +0200 Subject: [PATCH 01/10] allow multiple galleries on page and init of dynamically loaded galleries --- assets/js/frontend/add-to-cart-variation.js | 10 +- assets/js/frontend/single-product.js | 136 ++++++++++++-------- 2 files changed, 90 insertions(+), 56 deletions(-) diff --git a/assets/js/frontend/add-to-cart-variation.js b/assets/js/frontend/add-to-cart-variation.js index 9a5a430fb07..f5cfe9ca758 100644 --- a/assets/js/frontend/add-to-cart-variation.js +++ b/assets/js/frontend/add-to-cart-variation.js @@ -10,6 +10,7 @@ this.$singleVariationWrap = $form.find( '.single_variation_wrap' ); this.$resetVariations = $form.find( '.reset_variations' ); this.$product = $form.closest( '.product' ); + this.$product_gallery = this.$product.find( '.woocommerce-product-gallery' ); this.variationData = $form.data( 'product_variations' ); this.useAjax = false === this.variationData; this.xhr = false; @@ -527,7 +528,9 @@ * Reset the slide position if the variation has a different image than the current one */ $.fn.wc_maybe_trigger_slide_position_reset = function( variation ) { - var $form = $( this ), + var $form = $( this ), + $product = $form.closest( '.product' ), + $product_gallery = $product.find( '.woocommerce-product-gallery' ), reset_slide_position = false, new_image_id = ( variation && variation.image_id ) ? variation.image_id : ''; @@ -538,7 +541,7 @@ $form.attr( 'current-image', new_image_id ); if ( reset_slide_position ) { - $( 'body' ).trigger( 'woocommerce_gallery_reset_slide_position' ); + $product_gallery.trigger( 'woocommerce_gallery_reset_slide_position' ); } }; @@ -548,6 +551,7 @@ $.fn.wc_variations_image_update = function( variation ) { var $form = this, $product = $form.closest( '.product' ), + $product_gallery = $product.find( '.woocommerce-product-gallery' ), $gallery_img = $product.find( '.flex-control-nav li:eq(0) img' ), $gallery_wrapper = $product.find( '.woocommerce-product-gallery__wrapper ' ), $product_img_wrap = $gallery_wrapper.find( '.woocommerce-product-gallery__image, .woocommerce-product-gallery__image--placeholder' ).eq( 0 ), @@ -583,7 +587,7 @@ } window.setTimeout( function() { - $( 'body' ).trigger( 'woocommerce_init_gallery' ); + $product_gallery.trigger( 'woocommerce_gallery_init_zoom' ); $form.wc_maybe_trigger_slide_position_reset( variation ); $( window ).trigger( 'resize' ); }, 10 ); diff --git a/assets/js/frontend/single-product.js b/assets/js/frontend/single-product.js index 4db3a244b20..b124870fe5e 100644 --- a/assets/js/frontend/single-product.js +++ b/assets/js/frontend/single-product.js @@ -22,7 +22,7 @@ jQuery( function( $ ) { } else { $tabs.find( 'li:first a' ).click(); } - }) + } ) .on( 'click', '.wc-tabs li a, ul.tabs li a', function( e ) { e.preventDefault(); var $tab = $( this ); @@ -34,16 +34,16 @@ jQuery( function( $ ) { $tab.closest( 'li' ).addClass( 'active' ); $tabs_wrapper.find( $tab.attr( 'href' ) ).show(); - }) + } ) // Review link .on( 'click', 'a.woocommerce-review-link', function() { $( '.reviews_tab a' ).click(); return true; - }) + } ) // Star ratings for comments .on( 'init', '#rating', function() { $( '#rating' ).hide().before( '

12345

' ); - }) + } ) .on( 'click', '#respond p.stars a', function() { var $star = $( this ), $rating = $( this ).closest( '#respond' ).find( '#rating' ), @@ -55,7 +55,7 @@ jQuery( function( $ ) { $container.addClass( 'selected' ); return false; - }) + } ) .on( 'click', '#respond #submit', function() { var $rating = $( this ).closest( '#respond' ).find( '#rating' ), rating = $rating.val(); @@ -65,12 +65,7 @@ jQuery( function( $ ) { return false; } - }) - .on( 'woocommerce_init_gallery', function() { - if ( $.isFunction( $.fn.zoom ) && wc_single_product_params.zoom_enabled ) { - wc_product_gallery.init_zoom(); - } - }); + } ); //Init Tabs and Star Ratings $( '.wc-tabs-wrapper, .woocommerce-tabs, #rating' ).trigger( 'init' ); @@ -78,28 +73,30 @@ jQuery( function( $ ) { /** * Product gallery class. */ - var wc_product_gallery = { + var Product_Gallery = function( $el ) { + + this.$el = $el; /** * Initialize gallery actions and events. */ - init: function() { - if ( $.isFunction( $.fn.flexslider ) && wc_single_product_params.flexslider_enabled ) { - this.init_flexslider(); - } - if ( $.isFunction( $.fn.zoom ) && wc_single_product_params.zoom_enabled ) { - this.init_zoom(); - } - if ( typeof PhotoSwipe !== 'undefined' && wc_single_product_params.photoswipe_enabled ) { - this.init_photoswipe(); - } - }, + this.init = function() { + + this.init_flexslider(); + this.init_zoom(); + this.init_photoswipe(); + }; /** * Initialize flexSlider. */ - init_flexslider: function() { - $( '.woocommerce-product-gallery' ).flexslider({ + this.init_flexslider = function() { + + if ( ! $.isFunction( $.fn.flexslider ) || ! wc_single_product_params.flexslider_enabled ) { + return; + } + + $el.flexslider( { selector: '.woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image', animation: wc_single_product_params.flexslider.animation, smoothHeight: wc_single_product_params.flexslider.smoothHeight, @@ -118,24 +115,29 @@ jQuery( function( $ ) { if ( height > largest_height ) { largest_height = height; } - }); + } ); $images.each( function() { $( this ).css( 'min-height', largest_height ); - }); + } ); } - }); - - $( 'body' ).on( 'woocommerce_gallery_reset_slide_position', function(){ - $( '.woocommerce-product-gallery' ).flexslider( 0 ); } ); - }, + + $el.on( 'woocommerce_gallery_reset_slide_position', this.reset_slide_position ); + + $el.on( 'woocommerce_gallery_init_zoom', this.init_zoom ); + }; /** * Init zoom. */ - init_zoom: function() { - var zoom_target = $( '.woocommerce-product-gallery__image' ), + this.init_zoom = function() { + + if ( ! $.isFunction( $.fn.zoom ) || ! wc_single_product_params.zoom_enabled ) { + return; + } + + var zoom_target = $( '.woocommerce-product-gallery__image', $el ), enable_zoom = false; if ( ! wc_single_product_params.flexslider_enabled ) { @@ -145,7 +147,7 @@ jQuery( function( $ ) { $( zoom_target ).each( function( index, target ) { var image = $( target ).find( 'img' ); - if ( image.attr( 'width' ) > $( '.woocommerce-product-gallery' ).width() ) { + if ( image.attr( 'width' ) > $el.width() ) { enable_zoom = true; return false; } @@ -156,15 +158,19 @@ jQuery( function( $ ) { zoom_target.trigger( 'zoom.destroy' ); zoom_target.zoom({ touch: false - }); + } ); } - }, + }; + + this.reset_slide_position = function() { + $el.flexslider( 0 ); + }; /** * Get product gallery image items. */ - get_gallery_items: function() { - var $slides = $( '.woocommerce-product-gallery__wrapper' ).children(), + this.get_gallery_items = function() { + var $slides = $( '.woocommerce-product-gallery__wrapper', $el ).children(), items = [], index = $slides.filter( '.' + 'flex-active-slide' ).index(); @@ -181,41 +187,49 @@ jQuery( function( $ ) { title: img.attr( 'title' ) }; items.push( item ); - }); + } ); } return { index: index, items: items }; - }, + }; /** * Init PhotoSwipe. */ - init_photoswipe: function() { - if ( wc_single_product_params.zoom_enabled ) { - $( '.woocommerce-product-gallery--with-images' ).prepend( '🔍' ); - $( document ).on( 'click', '.woocommerce-product-gallery__trigger', this.trigger_photoswipe ); + this.init_photoswipe = function() { + + if ( typeof PhotoSwipe === 'undefined' || ! wc_single_product_params.photoswipe_enabled ) { + return; } - $( document ).on( 'click', '.woocommerce-product-gallery__image a', this.trigger_photoswipe ); - }, + + if ( wc_single_product_params.zoom_enabled ) { + if ( $el.hasClass( 'woocommerce-product-gallery--with-images' ) ) { + $el.prepend( '🔍' ); + } + $el.on( 'click', '.woocommerce-product-gallery__trigger', { gallery: this }, this.trigger_photoswipe ); + } + $el.on( 'click', '.woocommerce-product-gallery__image a', { gallery: this }, this.trigger_photoswipe ); + }; /** * Initialise photoswipe. */ - trigger_photoswipe: function( e ) { + this.trigger_photoswipe = function( e ) { + e.preventDefault(); var pswpElement = $( '.pswp' )[0], - items = wc_product_gallery.get_gallery_items(), + items = e.data.gallery.get_gallery_items(), target = $( e.target ), clicked; if ( ! target.is( '.woocommerce-product-gallery__trigger' ) ) { clicked = e.target.closest( 'figure' ); } else { - clicked = target.parents( '.woocommerce-product-gallery' ).find( '.flex-active-slide' ); + clicked = e.data.gallery.$el.find( '.flex-active-slide' ); } var options = { @@ -230,8 +244,24 @@ jQuery( function( $ ) { // Initializes and opens PhotoSwipe. var gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items.items, options ); gallery.init(); - } + }; + + this.init(); }; - wc_product_gallery.init(); -}); + /** + * Function to call wc_product_gallery on jquery selector. + */ + $.fn.wc_product_gallery = function() { + new Product_Gallery( this ); + return this; + }; + + /* + * Initialize all galleries on page. + */ + $( '.woocommerce-product-gallery' ).each( function() { + $( this ).wc_product_gallery( this ); + } ); + +} ); From 9181f1c1513c0df77b2139021e2469b1e487bc85 Mon Sep 17 00:00:00 2001 From: Manos Psychogyiopoulos Date: Tue, 14 Mar 2017 12:55:25 +0200 Subject: [PATCH 02/10] allow init with args --- assets/js/frontend/add-to-cart-variation.js | 27 ++++--- assets/js/frontend/single-product.js | 72 +++++++++++-------- templates/single-product/product-image.php | 8 +-- .../single-product/product-thumbnails.php | 6 +- 4 files changed, 62 insertions(+), 51 deletions(-) diff --git a/assets/js/frontend/add-to-cart-variation.js b/assets/js/frontend/add-to-cart-variation.js index f5cfe9ca758..cb9e251853f 100644 --- a/assets/js/frontend/add-to-cart-variation.js +++ b/assets/js/frontend/add-to-cart-variation.js @@ -10,7 +10,6 @@ this.$singleVariationWrap = $form.find( '.single_variation_wrap' ); this.$resetVariations = $form.find( '.reset_variations' ); this.$product = $form.closest( '.product' ); - this.$product_gallery = this.$product.find( '.woocommerce-product-gallery' ); this.variationData = $form.data( 'product_variations' ); this.useAjax = false === this.variationData; this.xhr = false; @@ -22,10 +21,10 @@ this.$attributeFields.unbind( 'change ' ); // Methods. - this.getChosenAttributes = this.getChosenAttributes.bind( this ); + this.getChosenAttributes = this.getChosenAttributes.bind( this ); this.findMatchingVariations = this.findMatchingVariations.bind( this ); - this.isMatch = this.isMatch.bind( this ); - this.toggleResetLink = this.toggleResetLink.bind( this ); + this.isMatch = this.isMatch.bind( this ); + this.toggleResetLink = this.toggleResetLink.bind( this ); // Events. $form.on( 'click', '.reset_variations', { variationForm: this }, this.onReset ); @@ -530,7 +529,7 @@ $.fn.wc_maybe_trigger_slide_position_reset = function( variation ) { var $form = $( this ), $product = $form.closest( '.product' ), - $product_gallery = $product.find( '.woocommerce-product-gallery' ), + $product_gallery = $product.find( '.images' ), reset_slide_position = false, new_image_id = ( variation && variation.image_id ) ? variation.image_id : ''; @@ -551,10 +550,9 @@ $.fn.wc_variations_image_update = function( variation ) { var $form = this, $product = $form.closest( '.product' ), - $product_gallery = $product.find( '.woocommerce-product-gallery' ), + $product_gallery = $product.find( '.images' ), $gallery_img = $product.find( '.flex-control-nav li:eq(0) img' ), - $gallery_wrapper = $product.find( '.woocommerce-product-gallery__wrapper ' ), - $product_img_wrap = $gallery_wrapper.find( '.woocommerce-product-gallery__image, .woocommerce-product-gallery__image--placeholder' ).eq( 0 ), + $product_img_wrap = $product_gallery.find( '.woocommerce-product-gallery__image, .woocommerce-product-gallery__image--placeholder' ).eq( 0 ), $product_img = $product_img_wrap.find( '.wp-post-image' ); if ( variation && variation.image && variation.image.src && variation.image.src.length > 1 ) { @@ -565,9 +563,9 @@ $product_img.wc_set_variation_attr( 'sizes', variation.image.sizes ); $product_img.wc_set_variation_attr( 'title', variation.image.title ); $product_img.wc_set_variation_attr( 'alt', variation.image.alt ); - $product_img.wc_set_variation_attr( 'data-large-image', variation.image.full_src ); - $product_img.wc_set_variation_attr( 'data-large-image-width', variation.image.full_src_w ); - $product_img.wc_set_variation_attr( 'data-large-image-height', variation.image.full_src_h ); + $product_img.wc_set_variation_attr( 'data-large_image', variation.image.full_src ); + $product_img.wc_set_variation_attr( 'data-large_image_width', variation.image.full_src_w ); + $product_img.wc_set_variation_attr( 'data-large_image_height', variation.image.full_src_h ); $product_img_wrap.wc_set_variation_attr( 'data-thumb', variation.image.src ); $gallery_img.wc_set_variation_attr( 'src', variation.image.src ); } else { @@ -578,11 +576,10 @@ $product_img.wc_reset_variation_attr( 'sizes' ); $product_img.wc_reset_variation_attr( 'title' ); $product_img.wc_reset_variation_attr( 'alt' ); - $product_img.wc_reset_variation_attr( 'data-large-image' ); - $product_img.wc_reset_variation_attr( 'data-large-image-width' ); - $product_img.wc_reset_variation_attr( 'data-large-image-height' ); + $product_img.wc_reset_variation_attr( 'data-large_image' ); + $product_img.wc_reset_variation_attr( 'data-large_image_width' ); + $product_img.wc_reset_variation_attr( 'data-large_image_height' ); $product_img_wrap.wc_reset_variation_attr( 'data-thumb' ); - $product_img.wc_reset_variation_attr( 'large-image' ); $gallery_img.wc_reset_variation_attr( 'src' ); } diff --git a/assets/js/frontend/single-product.js b/assets/js/frontend/single-product.js index b124870fe5e..5d09789e1a6 100644 --- a/assets/js/frontend/single-product.js +++ b/assets/js/frontend/single-product.js @@ -73,9 +73,27 @@ jQuery( function( $ ) { /** * Product gallery class. */ - var Product_Gallery = function( $el ) { + var Product_Gallery = function( $el, args ) { - this.$el = $el; + var gallery = this; + + this.$el = $el; + this.$images = $( '.woocommerce-product-gallery__image', $el ); + + // Make this object available. + $el.data['product_gallery'] = this; + + // Pick functionality to initialize... + this.flexslider_enabled = $.isFunction( $.fn.flexslider ) && wc_single_product_params.flexslider_enabled; + this.zoom_enabled = $.isFunction( $.fn.zoom ) && wc_single_product_params.zoom_enabled; + this.photoswipe_enabled = typeof PhotoSwipe !== 'undefined' && wc_single_product_params.photoswipe_enabled; + + // ...also taking args into account. + if ( args ) { + this.flexslider_enabled = false === args.photoswipe_enabled ? false : this.flexslider_enabled; + this.zoom_enabled = false === args.zoom_enabled ? false : this.zoom_enabled; + this.photoswipe_enabled = false === args.photoswipe_enabled ? false : this.photoswipe_enabled; + } /** * Initialize gallery actions and events. @@ -92,7 +110,7 @@ jQuery( function( $ ) { */ this.init_flexslider = function() { - if ( ! $.isFunction( $.fn.flexslider ) || ! wc_single_product_params.flexslider_enabled ) { + if ( ! this.flexslider_enabled ) { return; } @@ -106,10 +124,10 @@ jQuery( function( $ ) { animationSpeed: wc_single_product_params.flexslider.animationSpeed, animationLoop: wc_single_product_params.flexslider.animationLoop, // Breaks photoswipe pagination if true. start: function() { - var $images = $( '.woocommerce-product-gallery__image' ); + var largest_height = 0; - $images.each( function() { + gallery.$images.each( function() { var height = $( this ).height(); if ( height > largest_height ) { @@ -117,7 +135,7 @@ jQuery( function( $ ) { } } ); - $images.each( function() { + gallery.$images.each( function() { $( this ).css( 'min-height', largest_height ); } ); } @@ -133,11 +151,11 @@ jQuery( function( $ ) { */ this.init_zoom = function() { - if ( ! $.isFunction( $.fn.zoom ) || ! wc_single_product_params.zoom_enabled ) { + if ( ! gallery.zoom_enabled ) { return; } - var zoom_target = $( '.woocommerce-product-gallery__image', $el ), + var zoom_target = gallery.$images, enable_zoom = false; if ( ! wc_single_product_params.flexslider_enabled ) { @@ -156,7 +174,7 @@ jQuery( function( $ ) { // But only zoom if the img is larger than its container. if ( enable_zoom ) { zoom_target.trigger( 'zoom.destroy' ); - zoom_target.zoom({ + zoom_target.zoom( { touch: false } ); } @@ -170,16 +188,16 @@ jQuery( function( $ ) { * Get product gallery image items. */ this.get_gallery_items = function() { - var $slides = $( '.woocommerce-product-gallery__wrapper', $el ).children(), - items = [], - index = $slides.filter( '.' + 'flex-active-slide' ).index(); + + var $slides = this.$images, + items = []; if ( $slides.length > 0 ) { $slides.each( function( i, el ) { var img = $( el ).find( 'img' ), - large_image_src = img.attr( 'data-large-image' ), - large_image_w = img.attr( 'data-large-image-width' ), - large_image_h = img.attr( 'data-large-image-height' ), + large_image_src = img.data( 'large_image' ), + large_image_w = img.data( 'large_image_width' ), + large_image_h = img.data( 'large_image_height' ), item = { src: large_image_src, w: large_image_w, @@ -190,10 +208,7 @@ jQuery( function( $ ) { } ); } - return { - index: index, - items: items - }; + return items; }; /** @@ -201,16 +216,15 @@ jQuery( function( $ ) { */ this.init_photoswipe = function() { - if ( typeof PhotoSwipe === 'undefined' || ! wc_single_product_params.photoswipe_enabled ) { + if ( ! this.photoswipe_enabled ) { return; } - if ( wc_single_product_params.zoom_enabled ) { - if ( $el.hasClass( 'woocommerce-product-gallery--with-images' ) ) { - $el.prepend( '🔍' ); - } + if ( this.zoom_enabled && this.$images.length > 0 ) { + $el.prepend( '🔍' ); $el.on( 'click', '.woocommerce-product-gallery__trigger', { gallery: this }, this.trigger_photoswipe ); } + $el.on( 'click', '.woocommerce-product-gallery__image a', { gallery: this }, this.trigger_photoswipe ); }; @@ -227,7 +241,7 @@ jQuery( function( $ ) { clicked; if ( ! target.is( '.woocommerce-product-gallery__trigger' ) ) { - clicked = e.target.closest( 'figure' ); + clicked = e.target.closest( '.woocommerce-product-gallery__image' ); } else { clicked = e.data.gallery.$el.find( '.flex-active-slide' ); } @@ -242,7 +256,7 @@ jQuery( function( $ ) { }; // Initializes and opens PhotoSwipe. - var gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items.items, options ); + var gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options ); gallery.init(); }; @@ -252,8 +266,8 @@ jQuery( function( $ ) { /** * Function to call wc_product_gallery on jquery selector. */ - $.fn.wc_product_gallery = function() { - new Product_Gallery( this ); + $.fn.wc_product_gallery = function( args ) { + new Product_Gallery( this, args ); return this; }; @@ -261,7 +275,7 @@ jQuery( function( $ ) { * Initialize all galleries on page. */ $( '.woocommerce-product-gallery' ).each( function() { - $( this ).wc_product_gallery( this ); + $( this ).wc_product_gallery(); } ); } ); diff --git a/templates/single-product/product-image.php b/templates/single-product/product-image.php index 5b70531697b..2e74ce71fa8 100644 --- a/templates/single-product/product-image.php +++ b/templates/single-product/product-image.php @@ -38,10 +38,10 @@ $wrapper_classes = apply_filters( 'woocommerce_single_product_image_gallery_cl