PageSourceSearch

https://www.gantuning.ru/blog/wp-content/themes/tuningblog/app/js/script.js?ver=0.0.2

js gantuning.ru collected 2026-10-07 23:02:47 UTC 10,213 bytes, 329 lines download raw bytes

1if (document.getElementById("toggleTagsBtn")) {
2  document.addEventListener("DOMContentLoaded", function () {
3    const btn = document.getElementById("toggleTagsBtn");
4    const container = document.getElementById("tagsContainer");
5
6    btn.addEventListener("click", function () {
7      container.classList.toggle("open");
8      btn.textContent = container.classList.contains("open")
9        ? "Скрыть теги ▲"
10        : "Раскрыть теги ▼";
11    });
12  });
13}
14
15document.addEventListener("DOMContentLoaded", function () {
16  const sticky = document.querySelector(".single-pc");
17  const moreOptions = document.querySelector(".more-options");
18  const bottomTrigger = document.querySelector("#bt-cta");
19
20  if (!sticky || !moreOptions || !bottomTrigger) return;
21
22  const topOffset = 50; // stick when 50px from top
23  const stickyOffset = sticky.offsetTop;
24
25  window.addEventListener("scroll", () => {
26    const scrollY = window.scrollY || window.pageYOffset;
27    const moreRect = moreOptions.getBoundingClientRect();
28    const stickyHeight = sticky.offsetHeight;
29    const bottomRect = bottomTrigger.getBoundingClientRect();
30
31    // bottomReached when sticky bottom touches top of #bt-cta
32    const bottomReached = bottomRect.top <= stickyHeight + topOffset;
33
34    if (
35      scrollY + topOffset >= stickyOffset &&
36      moreRect.bottom < 0 &&
37      !bottomReached
38    ) {
39      sticky.classList.add("sticky-fixed");
40    } else {
41      sticky.classList.remove("sticky-fixed");
42    }
43  });
44});
45
46if (document.getElementById("copyLinkBtn")) {
47  document.addEventListener("DOMContentLoaded", function () {
48    const copyBtn = document.getElementById("copyLinkBtn");
49    if (!copyBtn) return; // safety check
50
51    const copyMsg = document.querySelector(".copymessage");
52
53    copyBtn.addEventListener("click", function () {
54      const url = copyBtn.getAttribute("data-url");
55
56      // Use clipboard API (supported in most modern browsers)
57      if (navigator.clipboard && window.isSecureContext) {
58        navigator.clipboard
59          .writeText(url)
60          .then(() => showCopySuccess())
61          .catch(() => showCopyError());
62      } else {
63        // Fallback for older browsers or non-HTTPS
64        const textarea = document.createElement("textarea");
65        textarea.value = url;
66        document.body.appendChild(textarea);
67        textarea.select();
68        try {
69          document.execCommand("copy");
70          showCopySuccess();
71        } catch (err) {
72          showCopyError();
73        }
74        document.body.removeChild(textarea);
75      }
76    });
77
78    function showCopySuccess() {
79      copyMsg.innerHTML = "Ссылка скопирована";
80      copyMsg.style.color = "#2ecc71";
81      setTimeout(() => {
82        copyMsg.innerHTML = "Копировать ссылку";
83        copyMsg.style.color = "";
84      }, 2000);
85    }
86
87    function showCopyError() {
88      copyMsg.innerHTML = "Ошибка копирования";
89      copyMsg.style.color = "#e74c3c";
90    }
91  });
92}
93// Back to top btn
94
95if (document.getElementById("backToTop")) {
96  document.addEventListener("DOMContentLoaded", () => {
97    const backToTop = document.getElementById("backToTop");
98
99    window.addEventListener("scroll", () => {
100      if (window.scrollY > 300) {
101        backToTop.classList.add("show");
102      } else {
103        backToTop.classList.remove("show");
104      }
105    });
106
107    backToTop.addEventListener("click", () => {
108      window.scrollTo({
109        top: 0,
110        behavior: "smooth",
111      });
112    });
113  });
114}
115// Side menu
116
117jQuery(document).ready(function ($) {
118  function loadSlider() {
119    const $selimslider = jQuery(".banner-slider__slider");
120
121    $selimslider.slick({
122      dots: true,
123      infinite: false,
124      arrows: false,
125      centerMode: false,
126      slidesToShow: 1,
127      slidesToScroll: 1,
128      autoplay: true,
129      autoplaySpeed: 4000,
130      speed: 500,
131      prevArrow: false,
132      nextArrow: false,
133    });
134  }
135
136  loadSlider();
137
138  // Apply mask function
139  if ('input[type="tel"]') {
140    function applyPhoneMask() {
141      $('input[type="tel"]').each(function () {
142        IMask(this, {
143          mask: "+{7} (000) 000-00-00",
144          lazy: false,
145        });
146      });
147    }
148
149    // Run on load
150    applyPhoneMask();
151
152    // Run after CF7 AJAX replaces form
153    document.addEventListener("wpcf7mailsent", applyPhoneMask);
154    document.addEventListener("wpcf7invalid", applyPhoneMask);
155    document.addEventListener("wpcf7submit", applyPhoneMask);
156  }
157
158  $(".form-modal").on("click", function () {
159    if ($(this).hasClass("offer-prop")) {
160      $(".bt-offer").hide();
161      $(".bt-post-offer").show();
162    } else {
163      $(".bt-offer").show();
164      $(".bt-post-offer").hide();
165    }
166    // else do nothing
167  });
168
169  $(".scroll-btn").on("click", function () {
170    const target = $(this).data("target"); // get the target ID
171    if ($(target).length) {
172      $("html, body").animate(
173        {
174          scrollTop: $(target).offset().top,
175        },
176        600
177      ); // scroll duration in milliseconds
178    }
179  });
180});
181
182document.addEventListener("DOMContentLoaded", function () {
183  if (document.getElementById("img-modal")) {
184    const modal = document.getElementById("img-modal");
185    const modalImg = document.getElementById("img-modal-img");
186    const overlay = modal.querySelector(".img-modal__overlay");
187    const closeBtn = modal.querySelector(".img-modal__close");
188    const magnifyBtn = document.querySelector(
189      ".bt-custom-solution__modal--magnify"
190    );
191
192    const videoBtn = document.querySelector(".bt-video-modal");
193
194    // Open modal on click
195    document.querySelectorAll(".img-modal-trigger").forEach((img) => {
196      img.addEventListener("click", () => {
197        modalImg.src = img.dataset.full;
198        modal.classList.add("open");
199      });
200    });
201
202    // Open modal on click
203    magnifyBtn.addEventListener("click", () => {
204      // Open modal on click
205      document.querySelectorAll(".img-modal-trigger").forEach((img) => {
206        modalImg.src = img.dataset.full;
207        modal.classList.add("open");
208      });
209    });
210
211    // Get both iframe elements
212    const pcIframe = document.querySelector(".pc-iframe iframe");
213    const mbIframe = document.querySelector(".mb-iframe iframe");
214
215    // Store original src to restore
216    const pcSrc = pcIframe.getAttribute("src");
217    const mbSrc = mbIframe.getAttribute("src");
218
219    const videomodal = document.getElementById("video-modal");
220    const videooverlay = videomodal.querySelector(".img-modal__overlay");
221    const videocloseBtn = videomodal.querySelector(".img-modal__close");
222    // Open Video modal on click
223    videoBtn.addEventListener("click", () => {
224      videomodal.classList.add("open");
225    });
226
227    const closeModal = () => {
228      modal.classList.remove("open");
229      videomodal.classList.remove("open");
230      // Stop completely: remove src
231      pcIframe.src = "";
232      mbIframe.src = "";
233
234      // Restore original src without autoplay
235      setTimeout(() => {
236        pcIframe.src = pcSrc;
237        mbIframe.src = mbSrc;
238      }, 50);
239
240      setTimeout(() => {
241        modalImg.src = ""; // clear image after fade out
242      }, 500); // match transition duration
243    };
244
245    overlay.addEventListener("click", closeModal);
246    closeBtn.addEventListener("click", closeModal);
247
248    videooverlay.addEventListener("click", closeModal);
249    videocloseBtn.addEventListener("click", closeModal);
250    // Close on ESC key
251    document.addEventListener("keydown", (e) => {
252      if (e.key === "Escape" && modal.classList.contains("open")) {
253        closeModal();
254      }
255      if (e.key === "Escape" && videomodal.classList.contains("open")) {
256        closeModal();
257      }
258    });
259  }
260
261  if (document.getElementById("form-modal")) {
262    const formBtn = document.querySelectorAll(".form-modal");
263
264    const formmodal = document.getElementById("form-modal");
265    const formoverlay = formmodal.querySelector(".img-modal__overlay");
266    const formcloseBtn = formmodal.querySelector(".img-modal__close");
267    // Open Video modal on click
268    formBtn.forEach((modal) => {
269      modal.addEventListener("click", () => {
270        formmodal.classList.add("open");
271      });
272    });
273
274    // Close modal on overlay or close button click
275    const closeModal = () => {
276      formmodal.classList.remove("open");
277      setTimeout(() => {
278        modalImg.src = ""; // clear image after fade out
279      }, 500); // match transition duration
280    };
281
282    formoverlay.addEventListener("click", closeModal);
283    formcloseBtn.addEventListener("click", closeModal);
284
285    // Close on ESC key
286    document.addEventListener("keydown", (e) => {
287      if (e.key === "Escape" && formmodal.classList.contains("open")) {
288        closeModal();
289      }
290    });
291  }
292
293  // Cookie
294
295  const consentEl = document.getElementById("cookie-consent");
296  if (consentEl) {
297    const okBtn = consentEl.querySelector(".cookie-consent__ok");
298    const closeBtn = consentEl.querySelector(".cookie-consent__close");
299
300    // Helper functions
301    function setCookie(name, value, days) {
302      const d = new Date();
303      d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000);
304      document.cookie =
305        name + "=" + value + ";path=/;expires=" + d.toUTCString();
306    }
307
308    function getCookie(name) {
309      const v = document.cookie.match("(^|;) ?" + name + "=([^;]*)(;|$)");
310      return v ? v[2] : null;
311    }
312
313    // Show consent if not accepted
314    if (!getCookie("cookie_consent")) {
315      consentEl.classList.add("cookie-consent--active");
316    }
317
318    // OK button
319    okBtn.addEventListener("click", () => {
320      setCookie("cookie_consent", "1", 365);
321      consentEl.classList.remove("cookie-consent--active");
322    });
323
324    // Close button (dismiss without accepting)
325    closeBtn.addEventListener("click", () => {
326      consentEl.classList.remove("cookie-consent--active");
327    });
328  }
329});

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.