PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.86
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.86
51.1.86 51.1.84 51.1.85 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 All 40 releases
← All changes | includes/widgets/Image_Accordion/script.js +355 -0 51.1.2 → 51.1.86 View file →
@@ -1,0 +1,355 @@
1 +"use strict";
2 +
3 +(function ($) {
4 + $(window).on("elementor/frontend/init", function () {
5 + elementorFrontend.hooks.addAction(
6 + "frontend/element_ready/king-addons-image-accordion.default",
7 + function ($scope) {
8 + elementorFrontend.elementsHandler.addHandler(
9 + elementorModules.frontend.handlers.Base.extend({
10 + onInit() {
11 + const normalizeSafeUrl = (rawUrl) => {
12 + if (!rawUrl || typeof rawUrl !== "string") return null;
13 + try {
14 + const url = new URL(rawUrl, window.location.href);
15 + const allowedProtocols = ["http:", "https:", "mailto:", "tel:"];
16 + if (allowedProtocols.includes(url.protocol)) {
17 + return url.href;
18 + }
19 + } catch (e) {
20 + // ignore
21 + }
22 + return null;
23 + };
24 +
25 + const $elem = this.$element,
26 + $wrap = $elem.find(".king-addons-image-accordion"),
27 + $wrapContainer = $elem.find(".king-addons-image-accordion-wrap"),
28 + settings = JSON.parse(
29 + $elem
30 + .find(".king-addons-img-accordion-media-hover")
31 + .attr("data-settings")
32 + ),
33 + lightboxAttr = $wrap.attr("lightbox"),
34 + lightboxSettings = lightboxAttr ? JSON.parse(lightboxAttr) : "",
35 + $accordionItems = $elem.find(".king-addons-image-accordion-item");
36 +
37 + // Content stays at the open-item size for the whole animation.
38 + // Clearing that size when the transition ends was an instant
39 + // resize: the text wrapped and the block jumped.
40 + const contentAxis = () =>
41 + $wrap.css("flex-direction") === "column" ? "height" : "width";
42 +
43 + const setOpenContentSize = () => {
44 + const axis = contentAxis();
45 + const margin = axis === "height" ? "margin-bottom" : "margin-right";
46 + const count = $accordionItems.length;
47 + let gaps = 0;
48 +
49 + $accordionItems.each(function (index) {
50 + if (index < count - 1) {
51 + gaps += parseFloat($(this).css(margin)) || 0;
52 + }
53 + });
54 +
55 + const total =
56 + ($wrap[axis === "height" ? "innerHeight" : "innerWidth"]() || 0) - gaps;
57 + const activeGrow = parseFloat(settings.activeItem.activeWidth) || 1;
58 + let inactiveGrow = 1;
59 +
60 + $accordionItems.each(function () {
61 + if (!$(this).hasClass("king-addons-image-accordion-item-grow")) {
62 + inactiveGrow = parseFloat(window.getComputedStyle(this).flexGrow) || 1;
63 + return false;
64 + }
65 + });
66 +
67 + const sum = activeGrow + inactiveGrow * Math.max(count - 1, 0);
68 + if (total <= 0 || sum <= 0) {
69 + return;
70 + }
71 +
72 + $wrap[0].style.setProperty(
73 + "--king-acc-open-size",
74 + Math.round((total * activeGrow) / sum) + "px"
75 + );
76 + };
77 +
78 + setOpenContentSize();
79 + const resizeEvent = "resize.kingAddonsImageAccordion" + ($elem.data("id") || "item");
80 + $(window).off(resizeEvent).on(resizeEvent, setOpenContentSize);
81 + this.onDestroy = () => {
82 + $(window).off(resizeEvent);
83 + };
84 +
85 + // Adjust row/column layout if necessary
86 + if ($wrapContainer.hasClass("king-addons-acc-no-column")) {
87 + if (!$elem.hasClass("king-addons-image-accordion-row")) {
88 + $elem
89 + .removeClass("king-addons-image-accordion-column")
90 + .addClass("king-addons-image-accordion-row");
91 + $wrap.css("flex-direction", "row");
92 + }
93 + }
94 +
95 + // Initialize lightbox if settings exist
96 + if (lightboxSettings) {
97 + $wrap.lightGallery(lightboxSettings);
98 +
99 + // Adjust thumbnails in lightbox
100 + $wrap.on("onAfterOpen.lg", function () {
101 + const $lgOuter = $(".lg-outer");
102 + if ($lgOuter.find(".lg-thumb-item").length) {
103 + $lgOuter.find(".lg-thumb-item").each(function () {
104 + const $img = $(this).find("img");
105 + const imgSrc = $img.attr("src");
106 + const extIndex = imgSrc.lastIndexOf(".");
107 + const ext = imgSrc.slice(extIndex);
108 + const cropIndex = imgSrc.lastIndexOf("-");
109 + let cropSize = /\d{3,}x\d{3,}/.test(
110 + imgSrc.substring(extIndex, cropIndex)
111 + )
112 + ? imgSrc.substring(extIndex, cropIndex)
113 + : false;
114 + let newImgSrc = imgSrc;
115 +
116 + if (cropSize && cropSize.length >= 42) {
117 + cropSize = "";
118 + }
119 +
120 + if (cropSize !== "") {
121 + if (cropSize !== false) {
122 + newImgSrc = imgSrc.replace(cropSize, "-150x150");
123 + } else {
124 + newImgSrc = [
125 + imgSrc.slice(0, extIndex),
126 + "-150x150",
127 + ext
128 + ].join("");
129 + }
130 + }
131 +
132 + $img.attr("src", newImgSrc);
133 +
134 + // Restore original if invalid crop size
135 + if (cropSize === false || cropSize === "-450x450") {
136 + $img.attr("src", imgSrc);
137 + }
138 + });
139 + }
140 + });
141 +
142 + // Control certain lightbox behaviors
143 + $wrap.on("onAferAppendSlide.lg onAfterSlide.lg", function () {
144 + const $lightboxDownload = $("#lg-download"),
145 + lightboxControls = $(
146 + "#lg-actual-size, #lg-zoom-in, #lg-zoom-out, #lg-download"
147 + ),
148 + downloadHref = $lightboxDownload.attr("href");
149 +
150 + if ($lightboxDownload.length) {
151 + if (downloadHref.indexOf("wp-content") === -1) {
152 + lightboxControls.addClass("king-addons-hidden-element");
153 + } else {
154 + lightboxControls.removeClass("king-addons-hidden-element");
155 + }
156 + }
157 +
158 + // Hide autoplay if not enabled
159 + if (!lightboxSettings.autoplay) {
160 + $(".lg-autoplay-button").css({
161 + width: "0",
162 + height: "0",
163 + overflow: "hidden"
164 + });
165 + }
166 + });
167 + }
168 +
169 + // Make the entire accordion item clickable
170 + $wrap.css("cursor", "pointer");
171 +
172 + // Handle hover interactions for clickable links
173 + function mediaHoverLink() {
174 + // Avoid linking in the Elementor editor
175 + if (!$("body").hasClass("elementor-editor-active")) {
176 + $elem
177 + .find(".king-addons-img-accordion-media-hover")
178 + .on("click", function (event) {
179 + const isTarget = event.target.className.includes(
180 + "king-addons-img-accordion-media-hover"
181 + );
182 + const thisSettings = JSON.parse(
183 + isTarget
184 + ? $(this).attr("data-settings")
185 + : $(this)
186 + .closest(".king-addons-img-accordion-media-hover")
187 + .attr("data-settings")
188 + );
189 + if (
190 + !$(event.target).hasClass(
191 + "king-addons-img-accordion-item-lightbox"
192 + ) &&
193 + !$(event.target).closest(
194 + ".king-addons-img-accordion-item-lightbox"
195 + ).length
196 + ) {
197 + const itemUrl = thisSettings.activeItem.overlayLink;
198 + const safeUrl = normalizeSafeUrl(itemUrl);
199 + if (safeUrl) {
200 + if (
201 + thisSettings.activeItem.overlayLinkTarget ===
202 + "_blank"
203 + ) {
204 + const w = window.open(safeUrl, "_blank");
205 + if (w && typeof w.focus === "function") {
206 + w.focus();
207 + }
208 + } else {
209 + window.location.href = safeUrl;
210 + }
211 + }
212 + }
213 + });
214 + }
215 + }
216 +
217 + // Interaction type: "hover"
218 + if (settings.activeItem.interaction === "hover") {
219 + mediaHoverLink();
220 +
221 + $accordionItems.on("mouseenter", function () {
222 + if ($(this).hasClass("king-addons-image-accordion-item-grow")) {
223 + return;
224 + }
225 + $accordionItems.removeClass(
226 + "king-addons-image-accordion-item-grow"
227 + );
228 + $accordionItems
229 + .find(".king-addons-animation-wrap")
230 + .removeClass("king-addons-animation-wrap-active");
231 +
232 + $(this).addClass("king-addons-image-accordion-item-grow");
233 + $(this)
234 + .find(".king-addons-animation-wrap")
235 + .addClass("king-addons-animation-wrap-active");
236 + });
237 + $wrap.on("mouseleave", function () {
238 + $accordionItems.removeClass(
239 + "king-addons-image-accordion-item-grow"
240 + );
241 + $accordionItems
242 + .find(".king-addons-animation-wrap")
243 + .removeClass("king-addons-animation-wrap-active");
244 + });
245 +
246 + // Interaction type: "click"
247 + } else if (settings.activeItem.interaction === "click") {
248 + $elem
249 + .find(".king-addons-img-accordion-media-hover")
250 + .removeClass("king-addons-animation-wrap");
251 +
252 + $accordionItems.on(
253 + "click",
254 + ".king-addons-img-accordion-media-hover",
255 + function (event) {
256 + const isTarget = event.target.className.includes(
257 + "king-addons-img-accordion-media-hover"
258 + );
259 + const hasActiveClass = isTarget
260 + ? event.target.className.includes(
261 + "king-addons-animation-wrap-active"
262 + )
263 + : $(this)
264 + .closest(".king-addons-img-accordion-media-hover")
265 + .hasClass("king-addons-animation-wrap-active");
266 +
267 + // If this item is already active, redirect if a link is set
268 + if (
269 + hasActiveClass &&
270 + !$("body").hasClass("elementor-editor-active")
271 + ) {
272 + const thisSettings = JSON.parse(
273 + isTarget
274 + ? $(this).attr("data-settings")
275 + : $(this)
276 + .closest(".king-addons-img-accordion-media-hover")
277 + .attr("data-settings")
278 + );
279 +
280 + if (
281 + !$(event.target).hasClass(
282 + "king-addons-img-accordion-item-lightbox"
283 + ) &&
284 + !$(event.target).closest(
285 + ".king-addons-img-accordion-item-lightbox"
286 + ).length
287 + ) {
288 + const itemUrl = thisSettings.activeItem.overlayLink;
289 + const safeUrl = normalizeSafeUrl(itemUrl);
290 + if (safeUrl) {
291 + if (
292 + thisSettings.activeItem.overlayLinkTarget ===
293 + "_blank"
294 + ) {
295 + const w = window.open(safeUrl, "_blank");
296 + if (w && typeof w.focus === "function") {
297 + w.focus();
298 + }
299 + } else {
300 + window.location.href = safeUrl;
301 + }
302 + }
303 + }
304 + } else {
305 + // Activate this item
306 + $elem
307 + .find(".king-addons-img-accordion-media-hover")
308 + .removeClass("king-addons-animation-wrap king-addons-animation-wrap-active");
309 + $accordionItems.removeClass(
310 + "king-addons-image-accordion-item-grow"
311 + );
312 +
313 + $(this)
314 + .closest(".king-addons-image-accordion-item")
315 + .addClass("king-addons-image-accordion-item-grow");
316 + $(this)
317 + .closest(".king-addons-img-accordion-media-hover")
318 + .addClass("king-addons-animation-wrap-active");
319 + }
320 + }
321 + );
322 + } else {
323 + // If interaction is neither hover nor click
324 + $elem
325 + .find(".king-addons-img-accordion-media-hover")
326 + .removeClass("king-addons-animation-wrap");
327 + }
328 +
329 + // Set default active item
330 + $accordionItems.each(function () {
331 + if ($(this).index() === settings.activeItem.defaultActive - 1) {
332 + setTimeout(() => {
333 + const action =
334 + settings.activeItem.interaction === "click"
335 + ? "click"
336 + : "mouseenter";
337 + $(this)
338 + .find(".king-addons-img-accordion-media-hover")
339 + .trigger(action);
340 + }, 400);
341 + }
342 + });
343 +
344 + // Show the accordion after initialization
345 + $wrapContainer.css("opacity", 1);
346 + }
347 + }),
348 + {
349 + $element: $scope
350 + }
351 + );
352 + }
353 + );
354 + });
355 +})(jQuery);