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 / Countdown / 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/Countdown/script.js

158 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use strict";
2 (($) => {
3 $(window).on("elementor/frontend/init", () => {
4 elementorFrontend.hooks.addAction("frontend/element_ready/king-addons-countdown.default", ($scope) => {
5 elementorFrontend.elementsHandler.addHandler(
6 elementorModules.frontend.handlers.Base.extend({
7 onInit() {
8 const $element = this.$element;
9 const countDownWrap = $element
10 .children(".elementor-widget-container")
11 .children(".king-addons-countdown-wrap");
12
13 let countDownInterval = null;
14 const dataInterval = countDownWrap.data("interval");
15 const dataShowAgain = countDownWrap.data("show-again");
16 let endTime = new Date(dataInterval * 1000).getTime();
17
18 // Handle evergreen type
19 if (countDownWrap.data("type") === "evergreen") {
20 const widgetID = $element.attr("data-id");
21 let now = new Date();
22 const settings =
23 JSON.parse(localStorage.getItem("KingAddonsCountdownSettings")) || {};
24
25 // If this widget is saved in localStorage and intervals match, reuse its endTime.
26 if (
27 settings[widgetID] &&
28 dataInterval === settings[widgetID].interval
29 ) {
30 endTime = settings[widgetID].endTime;
31 } else {
32 endTime = now.setSeconds(now.getSeconds() + dataInterval);
33 }
34
35 // Check if show-again time has passed
36 if (endTime + dataShowAgain < Date.now()) {
37 now = new Date();
38 endTime = now.setSeconds(now.getSeconds() + dataInterval);
39 }
40
41 // Save updated settings
42 settings[widgetID] = { interval: dataInterval, endTime };
43 localStorage.setItem(
44 "KingAddonsCountdownSettings",
45 JSON.stringify(settings)
46 );
47 }
48
49 // Initialize and run the countdown
50 initCountDown();
51 countDownInterval = setInterval(initCountDown, 1000);
52
53 function initCountDown() {
54 const timeLeft = endTime - Date.now();
55
56 let numbers = {
57 days: Math.floor(timeLeft / (1000 * 60 * 60 * 24)),
58 hours: Math.floor((timeLeft / (1000 * 60 * 60)) % 24),
59 minutes: Math.floor((timeLeft / 1000 / 60) % 60),
60 seconds: Math.floor((timeLeft / 1000) % 60),
61 };
62
63 // If time is already up
64 if (timeLeft < 0) {
65 numbers = { days: 0, hours: 0, minutes: 0, seconds: 0 };
66 }
67
68 // Update DOM
69 $element.find(".king-addons-countdown-number").each(function () {
70 let number = numbers[$(this).attr("data-item")] || 0;
71
72 if (number.toString().length === 1) {
73 number = `0${number}`;
74 }
75 $(this).text(number);
76
77 // Update label singular/plural
78 const labels = $(this).next();
79 if (
80 labels.length &&
81 !$(this).hasClass("king-addons-countdown-seconds")
82 ) {
83 const labelText = labels.data("text");
84 labels.text(number === "01" ? labelText.singular : labelText.plural);
85 }
86 });
87
88 // When countdown expires
89 if (timeLeft < 0) {
90 clearInterval(countDownInterval);
91 expiredActions();
92 }
93 }
94
95 function expiredActions() {
96 const dataActions = countDownWrap.data("actions");
97 // Skip if in elementor editor
98 if ($("body").hasClass("elementor-editor-active")) return;
99
100 const normalizeSafeUrl = (rawUrl) => {
101 if (!rawUrl || typeof rawUrl !== "string") return null;
102 try {
103 const url = new URL(rawUrl, window.location.href);
104 if (url.protocol === "http:" || url.protocol === "https:") {
105 return url.href;
106 }
107 } catch (e) {
108 // ignore
109 }
110 return null;
111 };
112
113 // Hide the timer
114 if (dataActions.hasOwnProperty("hide-timer")) {
115 countDownWrap.hide();
116 }
117
118 // Hide a specific element
119 if (dataActions.hasOwnProperty("hide-element")) {
120 $(dataActions["hide-element"]).hide();
121 }
122
123 // Show a message
124 if (dataActions.hasOwnProperty("message")) {
125 const messageSelector = ".king-addons-countdown-message";
126 if (
127 !$element
128 .children(".elementor-widget-container")
129 .children(messageSelector).length
130 ) {
131 const $msg = $("<div />", {
132 class: "king-addons-countdown-message",
133 text: String(dataActions["message"] ?? ""),
134 });
135 countDownWrap.after($msg);
136 }
137 }
138
139 // Redirect
140 if (dataActions.hasOwnProperty("redirect")) {
141 const destinationUrl = normalizeSafeUrl(dataActions["redirect"]);
142 if (destinationUrl) {
143 window.location.href = destinationUrl;
144 }
145 }
146
147 // Load a template (show the next .elementor section)
148 if (dataActions.hasOwnProperty("load-template")) {
149 countDownWrap.next(".elementor").show();
150 }
151 }
152 },
153 }),
154 { $element: $scope }
155 );
156 });
157 });
158 })(jQuery);