PageSourceSearch

https://www.mingmeng07.com/wp-content/themes/MM/static/js/single-product-9.3.3.js

js mingmeng07.com collected 2026-10-04 04:56:14 UTC 10,808 bytes, 357 lines download raw bytes

1/*global wc_single_product_params, PhotoSwipe, PhotoSwipeUI_Default */
2jQuery( function( $ ) {
3
4	// wc_single_product_params is required to continue.
5	if ( typeof wc_single_product_params === 'undefined' ) {
6		return false;
7	}
8
9	$( 'body' )
10		// Tabs
11		.on( 'init', '.wc-tabs-wrapper, .woocommerce-tabs', function() {
12			$( this ).find( '.wc-tab, .woocommerce-tabs .panel:not(.panel .panel)' ).hide();
13
14			var hash  = window.location.hash;
15			var url   = window.location.href;
16			var $tabs = $( this ).find( '.wc-tabs, ul.tabs' ).first();
17
18			if ( hash.toLowerCase().indexOf( 'comment-' ) >= 0 || hash === '#reviews' || hash === '#tab-reviews' ) {
19				$tabs.find( 'li.reviews_tab a' ).trigger( 'click' );
20			} else if ( url.indexOf( 'comment-page-' ) > 0 || url.indexOf( 'cpage=' ) > 0 ) {
21				$tabs.find( 'li.reviews_tab a' ).trigger( 'click' );
22			} else if ( hash === '#tab-additional_information' ) {
23				$tabs.find( 'li.additional_information_tab a' ).trigger( 'click' );
24			} else {
25				$tabs.find( 'li:first a' ).trigger( 'click' );
26			}
27		} )
28		.on( 'click', '.wc-tabs li a, ul.tabs li a', function( e ) {
29			e.preventDefault();
30			var $tab          = $( this );
31			var $tabs_wrapper = $tab.closest( '.wc-tabs-wrapper, .woocommerce-tabs' );
32			var $tabs         = $tabs_wrapper.find( '.wc-tabs, ul.tabs' );
33
34			$tabs.find( 'li' ).attr( 'aria-selected', 'false' );
35			$tabs.find( 'li' ).removeClass( 'active' );
36			$tabs_wrapper.find( '.wc-tab, .panel:not(.panel .panel)' ).hide();
37
38			$tab.closest( 'li' ).attr( 'aria-selected', 'true' );
39			$tab.closest( 'li' ).addClass( 'active' );
40			$tabs_wrapper.find( '#' + $tab.attr( 'href' ).split( '#' )[1] ).show();
41		} )
42		// Review link
43		.on( 'click', 'a.woocommerce-review-link', function() {
44			$( '.reviews_tab a' ).trigger( 'click' );
45			return true;
46		} )
47		// Star ratings for comments
48		.on( 'init', '#rating', function() {
49			$( '#rating' )
50				.hide()
51				.before(
52					'<p class="stars">\
53						<span>\
54							<a class="star-1" href="#">1</a>\
55							<a class="star-2" href="#">2</a>\
56							<a class="star-3" href="#">3</a>\
57							<a class="star-4" href="#">4</a>\
58							<a class="star-5" href="#">5</a>\
59						</span>\
60					</p>'
61				);
62		} )
63		.on( 'click', '#respond p.stars a', function() {
64			var $star   	= $( this ),
65				$rating 	= $( this ).closest( '#respond' ).find( '#rating' ),
66				$container 	= $( this ).closest( '.stars' );
67
68			$rating.val( $star.text() );
69			$star.siblings( 'a' ).removeClass( 'active' );
70			$star.addClass( 'active' );
71			$container.addClass( 'selected' );
72
73			return false;
74		} )
75		.on( 'click', '#respond #submit', function() {
76			var $rating = $( this ).closest( '#respond' ).find( '#rating' ),
77				rating  = $rating.val();
78
79			if ( $rating.length > 0 && ! rating && wc_single_product_params.review_rating_required === 'yes' ) {
80				window.alert( wc_single_product_params.i18n_required_rating_text );
81
82				return false;
83			}
84		} );
85
86	// Init Tabs and Star Ratings
87	$( '.wc-tabs-wrapper, .woocommerce-tabs, #rating' ).trigger( 'init' );
88
89	/**
90	 * Product gallery class.
91	 */
92	var ProductGallery = function( $target, args ) {
93		this.$target = $target;
94		this.$images = $( '.woocommerce-product-gallery__image', $target );
95
96		// No images? Abort.
97		if ( 0 === this.$images.length ) {
98			this.$target.css( 'opacity', 1 );
99			return;
100		}
101
102		// Make this object available.
103		$target.data( 'product_gallery', this );
104
105		// Pick functionality to initialize...
106		this.flexslider_enabled = 'function' === typeof $.fn.flexslider && wc_single_product_params.flexslider_enabled;
107		this.zoom_enabled       = 'function' === typeof $.fn.zoom && wc_single_product_params.zoom_enabled;
108		this.photoswipe_enabled = typeof PhotoSwipe !== 'undefined' && wc_single_product_params.photoswipe_enabled;
109
110		// ...also taking args into account.
111		if ( args ) {
112			this.flexslider_enabled = false === args.flexslider_enabled ? false : this.flexslider_enabled;
113			this.zoom_enabled       = false === args.zoom_enabled ? false : this.zoom_enabled;
114			this.photoswipe_enabled = false === args.photoswipe_enabled ? false : this.photoswipe_enabled;
115		}
116
117		// ...and what is in the gallery.
118		if ( 1 === this.$images.length ) {
119			this.flexslider_enabled = false;
120		}
121
122		// Bind functions to this.
123		this.initFlexslider       = this.initFlexslider.bind( this );
124		this.initZoom             = this.initZoom.bind( this );
125		this.initZoomForTarget    = this.initZoomForTarget.bind( this );
126		this.initPhotoswipe       = this.initPhotoswipe.bind( this );
127		this.onResetSlidePosition = this.onResetSlidePosition.bind( this );
128		this.getGalleryItems      = this.getGalleryItems.bind( this );
129		this.openPhotoswipe       = this.openPhotoswipe.bind( this );
130
131		if ( this.flexslider_enabled ) {
132			this.initFlexslider( args.flexslider );
133			$target.on( 'woocommerce_gallery_reset_slide_position', this.onResetSlidePosition );
134		} else {
135			this.$target.css( 'opacity', 1 );
136		}
137
138		if ( this.zoom_enabled ) {
139			this.initZoom();
140			$target.on( 'woocommerce_gallery_init_zoom', this.initZoom );
141		}
142
143		if ( this.photoswipe_enabled ) {
144			this.initPhotoswipe();
145		}
146	};
147
148	/**
149	 * Initialize flexSlider.
150	 */
151	ProductGallery.prototype.initFlexslider = function( args ) {
152		var $target = this.$target,
153			gallery = this;
154
155		var options = $.extend( {
156			selector: '.woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image',
157			start: function() {
158				$target.css( 'opacity', 1 );
159			},
160			after: function( slider ) {
161				gallery.initZoomForTarget( gallery.$images.eq( slider.currentSlide ) );
162			}
163		}, args );
164
165		$target.flexslider( options );
166
167		// Trigger resize after main image loads to ensure correct gallery size.
168		$( '.woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image:eq(0) .wp-post-image' ).one( 'load', function() {
169			var $image = $( this );
170
171			if ( $image ) {
172				setTimeout( function() {
173					var setHeight = $image.closest( '.woocommerce-product-gallery__image' ).height();
174					var $viewport = $image.closest( '.flex-viewport' );
175
176					if ( setHeight && $viewport ) {
177						$viewport.height( setHeight );
178					}
179				}, 100 );
180			}
181		} ).each( function() {
182			if ( this.complete ) {
183				$( this ).trigger( 'load' );
184			}
185		} );
186	};
187
188	/**
189	 * Init zoom.
190	 */
191	ProductGallery.prototype.initZoom = function() {
192		this.initZoomForTarget( this.$images.first() );
193	};
194
195	/**
196	 * Init zoom.
197	 */
198	ProductGallery.prototype.initZoomForTarget = function( zoomTarget ) {
199		if ( ! this.zoom_enabled ) {
200			return false;
201		}
202
203		var galleryWidth = this.$target.width(),
204			zoomEnabled  = false;
205
206		$( zoomTarget ).each( function( index, target ) {
207			var image = $( target ).find( 'img' );
208
209			if ( image.data( 'large_image_width' ) > galleryWidth ) {
210				zoomEnabled = true;
211				return false;
212			}
213		} );
214
215		// But only zoom if the img is larger than its container.
216		if ( zoomEnabled ) {
217			var zoom_options = $.extend( {
218				touch: false,
219				callback: function() {
220					var zoomImg = this;
221					
222					setTimeout( function() {
223						zoomImg.removeAttribute( 'role' );
224						zoomImg.setAttribute( 'alt', '' );
225						zoomImg.setAttribute( 'aria-hidden', 'true' );
226					}, 100 );
227				}
228			}, wc_single_product_params.zoom_options );
229
230			if ( 'ontouchstart' in document.documentElement ) {
231				zoom_options.on = 'click';
232			}
233
234			zoomTarget.trigger( 'zoom.destroy' );
235			zoomTarget.zoom( zoom_options );
236
237			setTimeout( function() {
238				if ( zoomTarget.find(':hover').length ) {
239					zoomTarget.trigger( 'mouseover' );
240				}
241			}, 100 );
242		}
243	};
244
245	/**
246	 * Init PhotoSwipe.
247	 */
248	ProductGallery.prototype.initPhotoswipe = function() {
249		if ( this.zoom_enabled && this.$images.length > 0 ) {
250			this.$target.prepend( '<a href="#" class="woocommerce-product-gallery__trigger">🔍</a>' );
251			this.$target.on( 'click', '.woocommerce-product-gallery__trigger', this.openPhotoswipe );
252			this.$target.on( 'click', '.woocommerce-product-gallery__image a', function( e ) {
253				e.preventDefault();
254			});
255
256			// If flexslider is disabled, gallery images also need to trigger photoswipe on click.
257			if ( ! this.flexslider_enabled ) {
258				this.$target.on( 'click', '.woocommerce-product-gallery__image a', this.openPhotoswipe );
259			}
260		} else {
261			this.$target.on( 'click', '.woocommerce-product-gallery__image a', this.openPhotoswipe );
262		}
263	};
264
265	/**
266	 * Reset slide position to 0.
267	 */
268	ProductGallery.prototype.onResetSlidePosition = function() {
269		this.$target.flexslider( 0 );
270	};
271
272	/**
273	 * Get product gallery image items.
274	 */
275	ProductGallery.prototype.getGalleryItems = function() {
276		var $slides = this.$images,
277			items   = [];
278
279		if ( $slides.length > 0 ) {
280			$slides.each( function( i, el ) {
281				var img = $( el ).find( 'img' );
282
283				if ( img.length ) {
284					var large_image_src = img.attr( 'data-large_image' ),
285						large_image_w   = img.attr( 'data-large_image_width' ),
286						large_image_h   = img.attr( 'data-large_image_height' ),
287						alt             = img.attr( 'alt' ),
288						item            = {
289							alt  : alt,
290							src  : large_image_src,
291							w    : large_image_w,
292							h    : large_image_h,
293							title: img.attr( 'data-caption' ) ? img.attr( 'data-caption' ) : img.attr( 'title' )
294						};
295					items.push( item );
296				}
297			} );
298		}
299
300		return items;
301	};
302
303	/**
304	 * Open photoswipe modal.
305	 */
306	ProductGallery.prototype.openPhotoswipe = function( e ) {
307		e.preventDefault();
308
309		var pswpElement = $( '.pswp' )[0],
310			items       = this.getGalleryItems(),
311			eventTarget = $( e.target ),
312			clicked;
313
314		if ( 0 < eventTarget.closest( '.woocommerce-product-gallery__trigger' ).length ) {
315			clicked = this.$target.find( '.flex-active-slide' );
316		} else {
317			clicked = eventTarget.closest( '.woocommerce-product-gallery__image' );
318		}
319
320		var options = $.extend( {
321			index: $( clicked ).index(),
322			addCaptionHTMLFn: function( item, captionEl ) {
323				if ( ! item.title ) {
324					captionEl.children[0].textContent = '';
325					return false;
326				}
327				captionEl.children[0].textContent = item.title;
328				return true;
329			}
330		}, wc_single_product_params.photoswipe_options );
331
332		// Initializes and opens PhotoSwipe.
333		var photoswipe = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options );
334		photoswipe.init();
335	};
336
337	/**
338	 * Function to call wc_product_gallery on jquery selector.
339	 */
340	$.fn.wc_product_gallery = function( args ) {
341		new ProductGallery( this, args || wc_single_product_params );
342		return this;
343	};
344
345	/*
346	 * Initialize all galleries on page.
347	 */
348	$( '.woocommerce-product-gallery' ).each( function() {
349
350		$( this ).trigger( 'wc-product-gallery-before-init', [ this, wc_single_product_params ] );
351
352		$( this ).wc_product_gallery( wc_single_product_params );
353
354		$( this ).trigger( 'wc-product-gallery-after-init', [ this, wc_single_product_params ] );
355
356	} );
357} );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.