PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.82
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.82
51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / widgets / Slider / script.js

script.js in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.82, at includes/widgets/Slider/script.js

381 lines 23.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use strict";
2
3 (function ($) {
4 $(window).on("elementor/frontend/init", function () {
5 elementorFrontend.hooks.addAction(
6 "frontend/element_ready/king-addons-slider.default",
7 function ($scope) {
8 elementorFrontend.elementsHandler.addHandler(
9 elementorModules.frontend.handlers.Base.extend({
10 onInit: function onInit() {
11 const $slider = this.$element.find(".king-addons-advanced-slider");
12 const sliderData = $slider.data("slick");
13 const videoBtnSize = $slider.data("video-btn-size");
14 const dataSlideEffect = $slider.attr("data-slide-effect") || "slide";
15
16 // Capture class names
17 const sliderClass = this.$element.attr("class") || "";
18
19 // Helper to match columns or slides from class
20 const matchNumber = (pattern, fallback) => {
21 const match = sliderClass.match(pattern);
22 return match ? +match[0].replace(/\D/g, "") : fallback;
23 };
24
25 // Simple debounce helper.
26 const debounce = (func, threshold = 100, execAsap) => {
27 let timeout;
28 return function (...args) {
29 const context = this;
30 const delayed = () => {
31 if (!execAsap) func.apply(context, args);
32 timeout = null;
33 };
34 if (timeout) clearTimeout(timeout);
35 else if (execAsap) func.apply(context, args);
36 timeout = setTimeout(delayed, threshold);
37 };
38 };
39
40 $.fn.smartresize = function (fn) {
41 return fn ? this.on("resize", debounce(fn)) : this.trigger("smartresize");
42 };
43
44 // Extract columns from class
45 const sliderColumnsDesktop = matchNumber(/king-addons-adv-slider-columns-\d/, 2);
46 const sliderColumnsWideScreen = matchNumber(/columns--widescreen\d/, sliderColumnsDesktop);
47 const sliderColumnsLaptop = matchNumber(/columns--laptop\d/, sliderColumnsDesktop);
48 const sliderColumnsTabletExtra = matchNumber(/columns--tablet_extra\d/, 2);
49 const sliderColumnsTablet = matchNumber(/columns--tablet\d/, sliderColumnsTabletExtra);
50 const sliderColumnsMobileExtra = matchNumber(/columns--mobile_extra\d/, sliderColumnsTablet);
51 const sliderColumnsMobile = matchNumber(/columns--mobile\d/, 1);
52 const sliderSlidesToScroll = matchNumber(/king-addons-adv-slides-to-scroll-\d/, 1);
53
54 // Helper to determine if 'fade' effect applies
55 const isFade = (cols) => cols === 1 && dataSlideEffect === "fade";
56
57 // Initialize slick
58 $slider.slick({
59 ...sliderData, // in case there are any relevant data options
60 appendArrows: this.$element.find(".king-addons-slider-controls"),
61 appendDots: this.$element.find(".king-addons-slider-dots"),
62 customPaging: () => '<span class="king-addons-slider-dot"></span>',
63 slidesToShow: sliderColumnsDesktop,
64 responsive: [
65 {
66 breakpoint: 10000,
67 settings: {
68 slidesToShow: sliderColumnsWideScreen,
69 slidesToScroll: sliderSlidesToScroll > sliderColumnsWideScreen ? 1 : sliderSlidesToScroll,
70 fade: isFade(sliderColumnsWideScreen),
71 },
72 },
73 {
74 breakpoint: 2399,
75 settings: {
76 slidesToShow: sliderColumnsDesktop,
77 slidesToScroll: sliderSlidesToScroll > sliderColumnsDesktop ? 1 : sliderSlidesToScroll,
78 fade: isFade(sliderColumnsDesktop),
79 },
80 },
81 {
82 breakpoint: 1221,
83 settings: {
84 slidesToShow: sliderColumnsLaptop,
85 slidesToScroll: sliderSlidesToScroll > sliderColumnsLaptop ? 1 : sliderSlidesToScroll,
86 fade: isFade(sliderColumnsLaptop),
87 },
88 },
89 {
90 breakpoint: 1200,
91 settings: {
92 slidesToShow: sliderColumnsTabletExtra,
93 slidesToScroll: sliderSlidesToScroll > sliderColumnsTabletExtra ? 1 : sliderSlidesToScroll,
94 fade: isFade(sliderColumnsTabletExtra),
95 },
96 },
97 {
98 breakpoint: 1024,
99 settings: {
100 slidesToShow: sliderColumnsTablet,
101 slidesToScroll: sliderSlidesToScroll > sliderColumnsTablet ? 1 : sliderSlidesToScroll,
102 fade: isFade(sliderColumnsTablet),
103 },
104 },
105 {
106 breakpoint: 880,
107 settings: {
108 slidesToShow: sliderColumnsMobileExtra,
109 slidesToScroll: sliderSlidesToScroll > sliderColumnsMobileExtra ? 1 : sliderSlidesToScroll,
110 fade: isFade(sliderColumnsMobileExtra),
111 },
112 },
113 {
114 breakpoint: 768,
115 settings: {
116 slidesToShow: sliderColumnsMobile,
117 slidesToScroll: sliderSlidesToScroll > sliderColumnsMobile ? 1 : sliderSlidesToScroll,
118 fade: isFade(sliderColumnsMobile),
119 },
120 },
121 ],
122 });
123
124 // Helper to update slider height
125 const updateSliderHeight = () => {
126 $slider.css("height", this.$element.find(".slick-current").outerHeight());
127 };
128
129 // If there's an image, adjust slider height on arrow click & resize
130 if (this.$element.find(".king-addons-slider-img").length) {
131 updateSliderHeight();
132 this.$element.find(".king-addons-slider-arrow").on("click", updateSliderHeight);
133 // noinspection JSUnresolvedReference
134 $(window).smartresize(updateSliderHeight);
135 }
136
137 // Handle sizing of video icons and iframes
138 const sliderVideoSize = () => {
139 const $items = this.$element.find(".king-addons-slider-item");
140 $slider.find("iframe").attr({
141 width: $items.width(),
142 height: $items.height(),
143 });
144
145 // Identify breakpoints from Elementor
146 const viewportWidth = $(window).outerWidth();
147 const {
148 mobile,
149 mobile_extra,
150 tablet,
151 tablet_extra,
152 laptop,
153 widescreen,
154 } = elementorFrontend.config.responsive.breakpoints;
155 const activeBPs = elementorFrontend.config.responsive.activeBreakpoints;
156
157 // Remove existing video-icon-size classes
158 [...this.$element[0].classList].forEach((className) => {
159 if (className.startsWith("king-addons-slider-video-icon-size-")) {
160 this.$element[0].classList.remove(className);
161 }
162 });
163
164 // Add new video-icon-size class based on breakpoint
165 if (viewportWidth <= mobile.value && activeBPs.mobile) {
166 this.$element.addClass("king-addons-slider-video-icon-size-" + videoBtnSize.mobile);
167 } else if (viewportWidth <= mobile_extra.value && activeBPs.mobile_extra) {
168 this.$element.addClass("king-addons-slider-video-icon-size-" + videoBtnSize.mobile_extra);
169 } else if (viewportWidth <= tablet.value && activeBPs.tablet) {
170 this.$element.addClass("king-addons-slider-video-icon-size-" + videoBtnSize.tablet);
171 } else if (viewportWidth <= tablet_extra.value && activeBPs.tablet_extra) {
172 this.$element.addClass("king-addons-slider-video-icon-size-" + videoBtnSize.tablet_extra);
173 } else if (viewportWidth <= laptop.value && activeBPs.laptop) {
174 this.$element.addClass("king-addons-slider-video-icon-size-" + videoBtnSize.laptop);
175 } else if (viewportWidth < widescreen.value) {
176 this.$element.addClass("king-addons-slider-video-icon-size-" + videoBtnSize.desktop);
177 } else {
178 this.$element.addClass("king-addons-slider-video-icon-size-" + videoBtnSize.widescreen);
179 }
180 };
181
182 $(window).on("load resize", sliderVideoSize);
183
184 // Autoplay for embedded videos
185 const autoplayVideo = () => {
186 $slider.find(".slick-current").each(function () {
187 const $current = $(this).find(".king-addons-slider-item");
188 const videoSrc = $current.attr("data-video-src") || "";
189 const videoAutoplay = $current.attr("data-video-autoplay");
190
191 if (
192 $(this).find(".king-addons-slider-video").length < 1 &&
193 videoAutoplay === "yes"
194 ) {
195 if (videoSrc.includes("vimeo") || videoSrc.includes("youtube")) {
196 // If single column, embed in .king-addons-cv-inner
197 if (sliderColumnsDesktop === 1) {
198 $(this)
199 .find(".king-addons-cv-inner")
200 .prepend(
201 `<div class="king-addons-slider-video">
202 <iframe src="${videoSrc}" allow="autoplay" allowfullscreen></iframe>
203 </div>`
204 );
205 } else {
206 // Multiple columns
207 $(this)
208 .find(".king-addons-cv-container")
209 .prepend(
210 `<div class="king-addons-slider-video">
211 <iframe src="${videoSrc}" width="100%" height="100%"
212 allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
213 allowfullscreen>
214 </iframe>
215 </div>`
216 );
217 }
218 sliderVideoSize();
219 } else {
220 // Custom video
221 const videoMute = $current.attr("data-video-mute") || "";
222 const videoControls = $current.attr("data-video-controls") || "";
223 const videoLoop = $current.attr("data-video-loop") || "";
224 $(this)
225 .find(".king-addons-cv-inner")
226 .prepend(
227 `<div class="king-addons-slider-video king-addons-custom-video">
228 <video autoplay ${videoLoop} ${videoMute} ${videoControls}
229 src="${videoSrc}" width="100%" height="100%">
230 </video>
231 </div>`
232 );
233
234 $slider.find("video").attr({
235 width: $(this).find(".king-addons-slider-item").width(),
236 height: $(this).find(".king-addons-slider-item").height(),
237 });
238 }
239
240 // Hide content if video is autoplaying
241 if ($(this).find(".king-addons-slider-content")) {
242 $(this).find(".king-addons-slider-content").fadeOut(300);
243 }
244 }
245 });
246 };
247
248 // Slide animations
249 const slideAnimationOff = () => {
250 if (sliderColumnsDesktop === 1) {
251 $slider
252 .find(".king-addons-slider-item")
253 .not(".slick-active")
254 .find(".king-addons-slider-animation")
255 .removeClass("king-addons-animation-enter");
256 }
257 };
258
259 const slideAnimationOn = () => {
260 $slider.find(".slick-active, .slick-cloned, .slick-current").find(".king-addons-slider-content").fadeIn(0);
261 if (sliderColumnsDesktop === 1) {
262 $slider.find(".slick-active .king-addons-slider-animation").addClass("king-addons-animation-enter");
263 }
264 };
265
266 // Initial setup
267 slideAnimationOn();
268 this.$element.find(".slick-current").addClass("king-addons-slick-visible");
269 $slider.css("opacity", 1);
270 autoplayVideo();
271
272 // Video play button
273 $slider.on("click", ".king-addons-slider-video-btn", function () {
274 const $currentSlide = $(this).closest(".slick-slide");
275 let videoSrc = $currentSlide.find(".king-addons-slider-item").attr("data-video-src") || "";
276
277 if (videoSrc.includes("youtube")) {
278 videoSrc += "&autoplay=1";
279 }
280
281 if (videoSrc.includes("youtube") || videoSrc.includes("vimeo")) {
282 const allowFullScreen = videoSrc.includes("youtube")
283 ? 'allowfullscreen="allowfullscreen"'
284 : "allowfullscreen";
285
286 if ($currentSlide.find(".king-addons-slider-video").length < 1) {
287 $currentSlide
288 .find(".king-addons-cv-container")
289 .prepend(
290 `<div class="king-addons-slider-video">
291 <iframe src="${videoSrc}" width="100%" height="100%"
292 allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
293 ${allowFullScreen}>
294 </iframe>
295 </div>`
296 );
297 sliderVideoSize();
298 // noinspection JSValidateTypes
299 $currentSlide.find(".king-addons-slider-content").fadeOut(300);
300 }
301 } else {
302 // Custom video
303 const videoMute = $currentSlide.find(".king-addons-slider-item").attr("data-video-mute") || "";
304 const videoControls = $currentSlide.find(".king-addons-slider-item").attr("data-video-controls") || "";
305 const videoLoop = $currentSlide.find(".king-addons-slider-item").attr("data-video-loop") || "";
306
307 if ($currentSlide.find(".king-addons-slider-video").length < 1) {
308 $currentSlide
309 .find(".king-addons-cv-container")
310 .prepend(
311 `<div class="king-addons-slider-video king-addons-custom-video">
312 <video ${videoLoop} ${videoMute} ${videoControls}
313 src="${videoSrc}" width="100%" height="100%">
314 </video>
315 </div>`
316 );
317 $slider.find("video").attr({
318 width: $currentSlide.find(".king-addons-slider-item").width(),
319 height: $currentSlide.find(".king-addons-slider-item").height(),
320 });
321 // noinspection JSValidateTypes
322 $currentSlide.find(".king-addons-slider-content").fadeOut(300);
323 $currentSlide.find("video")[0].play();
324 }
325 }
326 });
327
328 // Slick events
329 $slider.on({
330 beforeChange: () => {
331 $slider.find(".king-addons-slider-video").remove();
332 $slider.find(".king-addons-animation-enter .king-addons-slider-content").fadeOut(300);
333 slideAnimationOff();
334 },
335 afterChange: () => {
336 slideAnimationOn();
337 autoplayVideo();
338 this.$element.find(".slick-slide").removeClass("king-addons-slick-visible");
339 this.$element.find(".slick-current").addClass("king-addons-slick-visible");
340 // noinspection JSUnresolvedReference
341 this.$element
342 .find(".slick-current")
343 .nextAll()
344 .slice(0, sliderColumnsDesktop - 1)
345 .addClass("king-addons-slick-visible");
346 updateSliderHeight();
347 },
348 });
349
350 // If dots exist and are horizontal
351 if (
352 this.$element.find(".slick-dots").length &&
353 this.$element.hasClass("king-addons-slider-dots-horizontal")
354 ) {
355 const setDotsWidth = () => {
356 const $dots = this.$element.find(".slick-dots");
357 const $dotsLi = $dots.find("li");
358 if (!$dotsLi.length) return;
359 // Each dot's width * total - margin-right
360 const dotsWrapWidth =
361 $dotsLi.outerWidth() * $dotsLi.length -
362 parseInt($dotsLi.find("span").css("margin-right"), 10);
363 $dots.css("width", dotsWrapWidth);
364 };
365
366 setDotsWidth();
367 // noinspection JSUnresolvedReference
368 $(window).smartresize(() => {
369 setTimeout(setDotsWidth, 300);
370 });
371 }
372 },
373 }),
374 {
375 $element: $scope,
376 }
377 );
378 }
379 );
380 });
381 })(jQuery);