1document.addEventListener('DOMContentLoaded', function () { 2 var buttons = document.querySelectorAll('.super_get_quote_button'); 3 var modalEl = document.getElementById('fixed_feedback'); 4 5 if (!modalEl || buttons.length === 0) return; 6 7 var modal = bootstrap.Modal.getOrCreateInstance(modalEl); 8 9 buttons.forEach(function (btn) { 10 btn.addEventListener('click', function (e) { 11 e.preventDefault(); 12 modal.show(); 13 }); 14 }); 15}); 16 17document.addEventListener("DOMContentLoaded", function () { 18 document.querySelectorAll(".has_video").forEach(function (el) { 19 el.addEventListener("click", function () { 20 const modalId = el.getAttribute("data-modal"); 21 const modalEl = document.getElementById(modalId); 22 if (modalEl) { 23 const modal = new bootstrap.Modal(modalEl); 24 modal.show(); 25 } 26 }); 27 }); 28}); 29document.addEventListener('DOMContentLoaded', () => { 30 // ç嬿æ modal ç show å hide äºä»¶ 31 document.querySelectorAll('.modal').forEach(modal => { 32 // ç¼ååå§ src å° data-src ä¸ï¼åªå䏿¬¡ï¼ 33 const iframe = modal.querySelector('iframe'); 34 if (iframe && !iframe.dataset.src) { 35 iframe.dataset.src = iframe.src; 36 } 37 38 // æ¨¡ææ¡å ³éæ¶æ¸ ç©º srcï¼è®© iframe 失æ 39 modal.addEventListener('hide.bs.modal', () => { 40 const iframe = modal.querySelector('iframe'); 41 if (iframe && iframe.src) { 42 iframe.src = ''; 43 } 44 }); 45 46 // æ¨¡ææ¡æå¼æ¶æ¢å¤åå§ src 47 modal.addEventListener('show.bs.modal', () => { 48 const iframe = modal.querySelector('iframe'); 49 if (iframe && iframe.dataset.src) { 50 iframe.src = iframe.dataset.src; 51 } 52 }); 53 }); 54}); 55document.addEventListener("DOMContentLoaded", function () { 56 document.querySelectorAll(".super_edit_button").forEach(function (el) { 57 el.addEventListener("click", function () { 58 const modalId = el.getAttribute("data-modal"); 59 const modalEl = document.getElementById(modalId); 60 if (modalEl) { 61 const modal = new bootstrap.Modal(modalEl); 62 modal.show(); 63 } 64 }); 65 }); 66}); 67$(document).off("focusin.bs.modal"); 68 69function updateFormWithGeoData(data) { 70 // console.log(data); 71 $(".feedback").each(function () { 72 // console.log(data.ip); 73 $(this) 74 .find('input[name="device-type"]') 75 .val(/Mobi|Android/i.test(navigator.userAgent) ? "Mobile" : "PC"); 76 $(this).find('input[name="userip"]').val(data.ip); 77 $(this).find('input[name="ip2country"]').val(data.country_name); 78 $(this) 79 .find('input[name="ip2city"]') 80 .val( 81 data.continent_name + 82 "--" + 83 data.country_name + 84 "--" + 85 data.state_prov + 86 "--" + 87 data.district + 88 "--" + 89 data.city 90 ); 91 $(this).find('input[name="ip2calling_code"]').val(data.calling_code); 92 $(this).find('input[name="phone"]').val(data.calling_code); 93 $(this).find('input[name="country"]').val(data.country_name); 94 $(this).find('input[name="page_url"]').val(window.location.href); 95 }); 96} 97document.addEventListener("DOMContentLoaded", () => { 98 let geoData = localStorage.getItem("geoData"); 99 if (geoData) { 100 geoData = JSON.parse(geoData); 101 // if (geoData.country_name == "China") { 102 // if (window.location.pathname !== "/404") { 103 // window.location = "/404"; 104 // } 105 // } 106 updateFormWithGeoData(geoData); 107 } else { 108 // å¦ææ²¡æç¼åæ°æ®ï¼ååèµ· API 请æ±è·å 109 fetch( 110 "https://api.ipgeolocation.io/ipgeo?apiKey=8c66569730c747febd2b69490a7eaa42&fields=continent_name,country_name,state_prov,district,city,calling_code" 111 ) 112 .then((response) => response.json()) 113 .then((data) => { 114 localStorage.setItem("geoData", JSON.stringify(data)); 115 // if (data.country_name == "China") { 116 // if (window.location.pathname !== "/404") { 117 // window.location = "/404"; 118 // } 119 // } 120 updateFormWithGeoData(data); 121 }) 122 .catch((error) => { 123 console.error("Error fetching geo data:", error); 124 }); 125 } 126}); 127// æ°åéå¢å¨ç» 128document.addEventListener("DOMContentLoaded", () => { 129 const counters = document.querySelectorAll(".counter"); 130 131 const animateCounters = () => {
132 counters.forEach((counter) => { 133 if (counter.dataset.animated) return; 134 135 const countValue = counter.getAttribute("data-count").trim(); 136 137 // æ£åæåæ°åé¨åååä½åç¼ï¼å æ¬ m+ãk+ã% çï¼ 138 const match = countValue.match(/^([\d\.]+)(.*)$/); 139 if (!match) return; // æ æ³å¹é æ¶è·³è¿ 140 141 const [_, numberStr, suffix] = match; 142 const target = parseFloat(numberStr); 143 if (isNaN(target)) return; // 䏿¯æææ°ååè·³è¿ 144 145 let current = 0; 146 const increment = target / 100; 147 148 const updateCounter = () => { 149 if (current < target) { 150 current += increment; 151 counter.textContent = Math.ceil(current) + suffix; 152 requestAnimationFrame(updateCounter); 153 } else { 154 counter.textContent = target + suffix; 155 counter.dataset.animated = "true"; 156 } 157 }; 158 159 // è¿å ¥å¯è§åºåæè§¦åå¨ç» 160 const rect = counter.getBoundingClientRect(); 161 if (rect.top < window.innerHeight && rect.bottom >= 0) { 162 updateCounter(); 163 } 164 }); 165 }; 166 167 window.addEventListener("scroll", animateCounters); 168 window.addEventListener("load", animateCounters); 169}); 170 171 172 173 174 175 176 177class FocusCarousel { 178 constructor(container) { 179 this.container = typeof container === 'string' ? document.getElementById(container) : container; 180 this.track = this.container.querySelector('.slider-track'); 181 this.prevBtn = this.container.querySelector('.prevBtn'); 182 this.nextBtn = this.container.querySelector('.nextBtn'); 183 this.isAnimating = false; 184 185 // ç»å®äºä»¶ 186 this.nextBtn.addEventListener('click', () => this.slideNext()); 187 this.prevBtn.addEventListener('click', () => this.slidePrev()); 188 189 window.addEventListener('resize', () => this.updateMargins(true)); 190 191 this.updateMargins(true); 192 } 193 194 getItemWidth() { 195 const firstItem = this.track.querySelector('.slider-item'); 196 return firstItem ? firstItem.getBoundingClientRect().width : 300; 197 } 198 199 updateMargins(immediate = false) { 200 const items = this.track.querySelectorAll('.slider-item'); 201 const itemWidth = this.getItemWidth(); 202 const halfWidth = itemWidth / 2; 203 204 items.forEach(item => { 205 item.classList.remove('active'); 206 item.style.transition = immediate ? 'none' : 'margin-left 0.6s ease, transform 0.6s ease, z-index 0.6s ease'; 207 item.style.zIndex = 1; 208 }); 209 210 if (items.length === 0) return; 211 212 items[0].classList.add('active'); 213 items[0].style.zIndex = 10; 214 215 items.forEach((item, i) => { 216 if (i === 0 || i === 1) { 217 item.style.marginLeft = '0px'; 218 } else { 219 item.style.marginLeft = `-${halfWidth}px`; 220 } 221 }); 222 } 223 224 slideNext() { 225 if (this.isAnimating) return; 226 this.isAnimating = true; 227 228 const itemWidth = this.getItemWidth(); 229 const halfWidth = itemWidth / 2; 230 const items = this.track.querySelectorAll('.slider-item'); 231 if (items.length < 3) { 232 this.isAnimating = false; 233 return; 234 } 235 236 const activeItem = items[0]; 237 const thirdItem = items[2]; 238 239 const duration = 600; 240 const startTime = performance.now(); 241 242 const animate = (time) => { 243 let elapsed = time - startTime; 244 let progress = Math.min(elapsed / duration, 1); 245 246 activeItem.style.marginLeft = `${-itemWidth * progress}px`; 247 thirdItem.style.marginLeft = `${-halfWidth * (1 - progress)}px`; 248 249 if (progress < 1) { 250 requestAnimationFrame(animate); 251 } else { 252 const first = this.track.children[0]; 253 this.track.appendChild(first); 254 this.updateMargins(true); 255 this.isAnimating = false; 256 } 257 }; 258 259 requestAnimationFrame(animate); 260 } 261 262 slidePrev() { 263 if (this.isAnimating) return; 264 this.isAnimating = true; 265 266 const itemWidth = this.getItemWidth(); 267 const halfWidth = itemWidth / 2; 268 const items = this.track.querySelectorAll('.slider-item'); 269 if (items.length < 3) { 270 this.isAnimating = false; 271 return; 272 } 273 274 const last = this.track.children[this.track.children.length - 1]; 275 this.track.insertBefore(last, this.track.children[0]); 276 this.updateMargins(true); 277 278 const itemsAfter = this.track.querySelectorAll('.slider-item'); 279 const activeItem = itemsAfter[0]; 280 const thirdItem = itemsAfter[2]; 281 282 activeItem.style.marginLeft = `-${itemWidth}px`; 283 thirdItem.style.marginLeft = '0px'; 284 285 const duration = 600; 286 const startTime = performance.now(); 287 288 const animate = (time) => {
289 let elapsed = time - startTime; 290 let progress = Math.min(elapsed / duration, 1); 291 292 activeItem.style.marginLeft = `${-itemWidth + itemWidth * progress}px`; 293 thirdItem.style.marginLeft = `${-halfWidth * progress}px`; 294 295 if (progress < 1) { 296 requestAnimationFrame(animate); 297 } else { 298 this.updateMargins(true); 299 this.isAnimating = false; 300 } 301 }; 302 303 requestAnimationFrame(animate); 304 } 305} 306 307 308 309document.addEventListener('DOMContentLoaded', function () { 310 document.querySelectorAll('.with-hidden-more').forEach(function (el) { 311 el.addEventListener('click', function () { 312 el.classList.toggle('expanded'); 313 }); 314 }); 315});
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.