PageSourceSearch

https://www.buysnowsportplows.com/javascript/customerJSFile.js?ver=1005051557559

js buysnowsportplows.com collected 2026-10-05 05:21:16 UTC 11,972 bytes, 412 lines download raw bytes

1// Custom JavaScript Functions
2function is_touch_device() {
3  return !!('ontouchstart' in window);
4}
5/* Owners */
6function owners_hover(id){
7	if(id == 'owner-manuals'){
8		if(is_touch_device()){
9			document.getElementById('owner-manuals').style.opacity=0.5;
10			document.getElementById('owner-manuals-mob').style.opacity=0.5;
11		}
12		else {
13			document.getElementById('owner-manuals').style.opacity=1.0;
14			document.getElementById('owner-manuals-mob').style.opacity=1.0;
15		}
16	}
17	else if(id == 'owner-parts'){
18		if(is_touch_device()){
19			document.getElementById('owner-parts').style.opacity=0.5;
20			document.getElementById('owner-parts-mob').style.opacity=0.5;
21		}
22		else {
23			document.getElementById('owner-parts').style.opacity=1.0;
24			document.getElementById('owner-parts-mob').style.opacity=1.0;
25		}
26	}
27	else {
28		if(is_touch_device()){
29			document.getElementById(id).style.opacity=0.5;
30		}
31		else {
32			document.getElementById(id).style.opacity=1.0;
33		}
34	}
35}
36function owners_out(id){
37	if(id == 'owner-manuals'){
38		document.getElementById('owner-manuals').style.opacity=0.5;
39		document.getElementById('owner-manuals-mob').style.opacity=0.5;
40	}
41	else if(id == 'owner-parts'){
42		document.getElementById('owner-parts').style.opacity=0.5;
43		document.getElementById('owner-parts-mob').style.opacity=0.5;
44	}
45	else
46		document.getElementById(id).style.opacity=0.5;
47}
48/* Lineup */
49function lineup_hover(id){
50	// Deal with mobile version
51	var mobid = id.concat('-mob');
52	if(is_touch_device()){
53		document.getElementById(id).style.opacity=1.0;
54		document.getElementById(mobid).style.opacity=1.0;
55	}
56	else {
57		document.getElementById(id).style.opacity=0.5;
58		document.getElementById(id).style.filter = 'filter:alpha(opacity=50)';
59		document.getElementById(id).style.transition = 'opacity 500ms ease-in-out';
60		document.getElementById(mobid).style.opacity=0.5;
61		document.getElementById(mobid).style.filter = 'filter:alpha(opacity=50)';
62		document.getElementById(mobid).style.transition = 'opacity 500ms ease-in-out';
63	}
64}
65function lineup_out(id){
66	// Deal with mobile version
67	var mobid = id.concat('-mob');
68	document.getElementById(id).style.opacity=1.0;
69	document.getElementById(mobid).style.opacity=1.0;
70}
71/* Feature */
72function feature_hover(id){
73	// Deal with mobile version
74	var mobid = id.concat('-mob');
75	if(is_touch_device()){
76		document.getElementById(id).style.opacity=1.0;
77		document.getElementById(mobid).style.opacity=1.0;
78	}
79	else {
80		document.getElementById(id).style.opacity=0.8;
81		document.getElementById(id).style.transform = "scale(1.1)";
82		document.getElementById(id).style.webkitTransform = "scale(1.1)";		
83		document.getElementById(id).style.MozTransfrom = "scale(1.1)";
84		document.getElementById(mobid).style.opacity=0.8;
85		document.getElementById(mobid).style.transform = "scale(1.1)";
86		document.getElementById(mobid).style.webkitTransform = "scale(1.1)";		
87		document.getElementById(mobid).style.MozTransfrom = "scale(1.1)";
88	}
89}
90function feature_out(id){
91	// Deal with mobile version
92	var mobid = id.concat('-mob');
93	document.getElementById(id).style.opacity=1.0;	
94	document.getElementById(id).style.transform = "scale(1.0)";
95	document.getElementById(mobid).style.opacity=1.0;
96	document.getElementById(mobid).style.transform = "scale(1.0)";
97}
98// Instructions/Videos/FAQ Show/Hide Function
99function showhidetext(question) {
100	var $hidelink = "";
101	if(question === 'moreproducts'){
102		$hidelink = 'showproductvideos';
103	}
104	else if(question === 'moreinstall'){
105		$hidelink = 'showinstallvideos';
106	}
107	else if(question === 'moreaccessories'){
108		$hidelink = 'showaccessoriesvideos';
109	}
110	// Set the vars
111	var x = document.getElementById(question);
112	var y = document.getElementById($hidelink);
113	
114	if (x.style.display === "block"){
115		x.style.display = "none";
116	}
117	else{
118		x.style.display = "block";
119		if(question === 'moreproducts' || question === 'moreinstall' || question === 'moreaccessories'){
120			y.style.display = "none";
121		}
122	}
123}
124
125// Show free shipping icon and banner when subtotal is over $100
126const originalAdditemToolProcessSuccessful = ECCAddItemTool.prototype.processSuccessful;
127
128ECCAddItemTool.prototype.processSuccessful = function(data) {
129	var tool = this;
130	if (data && data.data && data.data.cart && data.data.cart.subtotal) {
131		
132	    // Show the new subtotal
133		$(tool.successModal).find('.ACIFreeShipping .ACICartSubtotal').html(ECCUserMiscTool.formatCurrency(data.data.cart.subtotal));
134		
135		// Show the free shipping banner if the subtotal is over $100
136		if (data.data.cart.subtotal >= 100) {
137			$(tool.successModal).find('.ACIFreeShipping .ACINeededForFreeShipping').hide();
138			$(tool.successModal).find('.ACIFreeShipping .ACIFreeShippingBanner').show();
139		} else {
140			$(tool.successModal).find('.ACIFreeShipping .ACIFreeShippingBanner').hide();
141			$(tool.successModal).find('.ACIFreeShipping .ACINeededForFreeShipping-amount').html(ECCUserMiscTool.formatCurrency(100 - data.data.cart.subtotal));
142			$(tool.successModal).find('.ACIFreeShipping .ACINeededForFreeShipping').show();
143		}
144	}
145    originalAdditemToolProcessSuccessful.call(this, data);
146};
147
148/* FAQ - Show/Hide Answer */
149document.querySelectorAll(".faq-question").forEach(q => {
150    q.addEventListener("click", () => {
151        document.querySelectorAll(".faq-item").forEach(item => {
152            if (item !== q.parentElement) {
153                item.classList.remove("open");
154            }
155        });
156        q.parentElement.classList.toggle("open");
157    });
158});
159
160/* New Video Slider */
161document.addEventListener('DOMContentLoaded', function () {
162  const sliderRoot = document.querySelector('#videosection .snow-video-slider');
163  if (!sliderRoot) return;
164
165  const viewport = sliderRoot.querySelector('.slider-viewport');
166  const track = sliderRoot.querySelector('.slider-track');
167  const prevBtn = sliderRoot.querySelector('.slider-nav.prev');
168  const nextBtn = sliderRoot.querySelector('.slider-nav.next');
169
170  const modalEl = document.getElementById('videoLightboxModal');
171  const modalFrame = document.getElementById('youtubeLightboxFrame');
172  const videoModal = new bootstrap.Modal(modalEl);
173
174  const originalSlides = Array.from(track.querySelectorAll('.video-slide'));
175  const totalOriginal = originalSlides.length;
176
177  let currentIndex = 1;
178  let slideWidth = 0;
179  let gap = 16;
180  let isTransitioning = false;
181
182  let startX = 0;
183  let currentTranslate = 0;
184  let prevTranslate = 0;
185  let isDragging = false;
186
187  function getSlidesPerView() {
188    const width = window.innerWidth;
189
190    if (width >= 1400) return 2.6;
191    if (width >= 1200) return 2.45;
192    if (width >= 992) return 2.2;
193    if (width >= 768) return 1.7;
194    if (width >= 576) return 1.25;
195    return 1.05;
196  }
197
198  function cloneSlides() {
199    track.innerHTML = '';
200
201    const firstClone = originalSlides[0].cloneNode(true);
202    firstClone.classList.add('clone');
203
204    const lastClone = originalSlides[totalOriginal - 1].cloneNode(true);
205    lastClone.classList.add('clone');
206
207    track.appendChild(lastClone);
208
209    originalSlides.forEach(slide => {
210      track.appendChild(slide.cloneNode(true));
211    });
212
213    track.appendChild(firstClone);
214  }
215
216  function setSlideWidths() {
217    const slides = track.querySelectorAll('.video-slide');
218    gap = parseFloat(window.getComputedStyle(track).gap) || 16;
219
220    const slidesPerView = getSlidesPerView();
221    slideWidth = (viewport.clientWidth - (gap * (slidesPerView - 1))) / slidesPerView;
222
223    slides.forEach(slide => {
224      slide.style.width = slideWidth + 'px';
225    });
226  }
227
228  function getTranslateForIndex(index) {
229    return -index * (slideWidth + gap);
230  }
231
232  function setTrackPosition(animate = true) {
233    if (!animate) {
234      track.style.transition = 'none';
235    } else {
236      track.style.transition = 'transform 0.45s ease';
237    }
238
239    const translate = getTranslateForIndex(currentIndex);
240    track.style.transform = 'translateX(' + translate + 'px)';
241    currentTranslate = translate;
242    prevTranslate = translate;
243  }
244
245  function nextSlide() {
246    if (isTransitioning) return;
247    isTransitioning = true;
248    currentIndex++;
249    setTrackPosition(true);
250  }
251
252  function prevSlide() {
253    if (isTransitioning) return;
254    isTransitioning = true;
255    currentIndex--;
256    setTrackPosition(true);
257  }
258
259  function handleLoopReset() {
260    const slides = track.querySelectorAll('.video-slide');
261
262    if (currentIndex === slides.length - 1) {
263      currentIndex = 1;
264      setTrackPosition(false);
265    }
266
267    if (currentIndex === 0) {
268      currentIndex = totalOriginal;
269      setTrackPosition(false);
270    }
271
272    isTransitioning = false;
273  }
274
275  function rebuildSlider() {
276    cloneSlides();
277    setSlideWidths();
278    currentIndex = 1;
279    setTrackPosition(false);
280    bindSlideClicks();
281  }
282
283  function bindSlideClicks() {
284    const slides = track.querySelectorAll('.video-slide');
285
286    slides.forEach(slide => {
287      slide.addEventListener('click', function (e) {
288        if (isDragging) return;
289
290        const videoId = this.getAttribute('data-video-id');
291        if (!videoId) return;
292
293        modalFrame.src = 'https://www.youtube.com/embed/' + videoId + '?autoplay=1&rel=0';
294        videoModal.show();
295      });
296    });
297  }
298
299  function pointerDown(x) {
300    isDragging = true;
301    startX = x;
302    prevTranslate = currentTranslate;
303    track.style.transition = 'none';
304  }
305
306  function pointerMove(x) {
307    if (!isDragging) return;
308    const delta = x - startX;
309    currentTranslate = prevTranslate + delta;
310    track.style.transform = 'translateX(' + currentTranslate + 'px)';
311  }
312
313  function pointerUp(x) {
314    if (!isDragging) return;
315
316    isDragging = false;
317    const movedBy = x - startX;
318    const threshold = 60;
319
320    if (movedBy < -threshold) {
321      currentIndex++;
322    } else if (movedBy > threshold) {
323      currentIndex--;
324    }
325
326    isTransitioning = true;
327    setTrackPosition(true);
328  }
329
330  nextBtn.addEventListener('click', nextSlide);
331  prevBtn.addEventListener('click', prevSlide);
332
333  track.addEventListener('transitionend', handleLoopReset);
334
335  viewport.addEventListener('touchstart', function (e) {
336    pointerDown(e.touches[0].clientX);
337  }, { passive: true });
338
339  viewport.addEventListener('touchmove', function (e) {
340    pointerMove(e.touches[0].clientX);
341  }, { passive: true });
342
343  viewport.addEventListener('touchend', function (e) {
344    pointerUp(e.changedTouches[0].clientX);
345  });
346
347  viewport.addEventListener('mousedown', function (e) {
348    pointerDown(e.clientX);
349  });
350
351  window.addEventListener('mousemove', function (e) {
352    if (!isDragging) return;
353    pointerMove(e.clientX);
354  });
355
356  window.addEventListener('mouseup', function (e) {
357    if (!isDragging) return;
358    pointerUp(e.clientX);
359  });
360
361  viewport.addEventListener('mouseleave', function (e) {
362    if (!isDragging) return;
363    pointerUp(e.clientX);
364  });
365
366  modalEl.addEventListener('hidden.bs.modal', function () {
367    modalFrame.src = '';
368  });
369
370  let resizeTimer;
371  window.addEventListener('resize', function () {
372    clearTimeout(resizeTimer);
373    resizeTimer = setTimeout(function () {
374      setSlideWidths();
375      setTrackPosition(false);
376    }, 120);
377  });
378
379  rebuildSlider();
380});
381
382/* Open Youtube Playlist in Lightbox */
383document.addEventListener('DOMContentLoaded', function () {
384
385  const playlistModalEl = document.getElementById('playlistModal');
386  const playlistFrame = document.getElementById('playlistFrame');
387  const playlistModal = new bootstrap.Modal(playlistModalEl);
388
389  // Handle ALL playlist buttons dynamically
390  document.addEventListener('click', function (e) {
391    const btn = e.target.closest('.open-playlist-btn');
392    if (!btn) return;
393
394    e.preventDefault();
395
396    const playlistId = btn.getAttribute('data-playlist');
397    if (!playlistId) return;
398
399    playlistFrame.src =
400      "https://www.youtube.com/embed/videoseries?list=" +
401      playlistId +
402      "&autoplay=1";
403
404    playlistModal.show();
405  });
406
407  // Stop playback when modal closes
408  playlistModalEl.addEventListener('hidden.bs.modal', function () {
409    playlistFrame.src = "";
410  });
411
412});

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.