1/** 2 * Exit-intent popup â PASS24 3 * Triggers: 4 * 1. mouseout to top of page (desktop) â only after DELAY_MS 5 * 2. After DELAY_MS (15s) on all pages 6 * Shows once per 7 days (cookie) â пÑи ÑоглаÑии на ÑÑнкÑионалÑнÑе cookie; 7 * без него попап показÑваеÑÑÑ Ð¾Ð´Ð¸Ð½ Ñаз за загÑÑÐ·ÐºÑ ÑÑÑаниÑÑ Ð¸ ниÑего не Ñ ÑаниÑ. 8 * Does NOT fire before delay. 9 * Ðе показÑваеÑÑÑ Ð½Ð° мобилÑном (Ñм. MOBILE_MAX_WIDTH). 10 */ 11(function () { 12 'use strict'; 13 14 var COOKIE_NAME = 'p24_exit_shown'; 15 var COOKIE_DAYS = 7; 16 var DELAY_MS = 15000; 17 18 /** 19 * ÐоÑог, ниже коÑоÑого попап не показÑваем. Ðа Ñзком ÑкÑане он закÑÑÐ²Ð°ÐµÑ 20 * веÑÑ Ð²ÑÑпоÑÑ â ÑÑо intrusive interstitial по клаÑÑиÑикаÑии Google, ÑиÑк 21 * Ð´Ð»Ñ Ð¼Ð¾Ð±Ð¸Ð»Ñного ÑанжиÑованиÑ. ÐеÑвÑй ÑÑÐ¸Ð³Ð³ÐµÑ (mouseleave) на мобилÑном и 22 * Ñак не ÑÑабаÑÑваеÑ, поÑÑÐ¾Ð¼Ñ Ð¾ÑклÑÑаеÑÑÑ ÑолÑко ÑаймеÑнÑй показ. 23 */ 24 var MOBILE_MAX_WIDTH = 767; 25 26 function isMobileViewport() { 27 return window.matchMedia('(max-width: ' + MOBILE_MAX_WIDTH + 'px)').matches; 28 } 29 30 function getCookie(name) { 31 var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)')); 32 return match ? match[2] : ''; 33 } 34 35 /** 36 * Ðапомнили ли показ в ÑÑой загÑÑзке ÑÑÑаниÑÑ, когда cookie пиÑаÑÑ Ð½ÐµÐ»ÑзÑ. 37 * 38 * ÐгÑаниÑение ÑаÑÑоÑÑ («Ñаз в 7 дней») â ÑÑнкÑионалÑÐ½Ð°Ñ cookie, и без 39 * ÑоглаÑÐ¸Ñ Ð½Ð° ÑÑнкÑионалÑнÑе она не пиÑеÑÑÑ (SITE-21). СовÑем оÑклÑÑаÑÑ 40 * попап из-за ÑÑого незаÑем: он ÑаÑÑÑ ÑайÑа, а не ÑÑоÑонний ÑеÑÐ²Ð¸Ñ Ð¸ не 41 * ÑеÑевой запÑоÑ. ÐоÑÑÐ¾Ð¼Ñ Ð¿Ñи оÑказе памÑÑÑ ÑжимаеÑÑÑ Ð´Ð¾ одной загÑÑзки 42 * ÑÑÑаниÑÑ â попап покажеÑÑÑ Ð¾Ð´Ð¸Ð½ Ñаз и ниÑего не ÑÐ¾Ñ ÑаниÑ. ÐÑли ÑоглаÑие 43 * пÑидÑÑ Ñже поÑле показа, памÑÑÑ Ð·Ð°Ð¿Ð¸ÑеÑÑÑ Ñогда же (Ñм. markShown). 44 */ 45 var shownThisPage = false; 46 47 function storageAllowed() { 48 return !!(window.P24Consent && window.P24Consent.allowed('functional')); 49 } 50 51 function alreadyShown() { 52 if (shownThisPage) { 53 return true; 54 } 55 return storageAllowed() && getCookie(COOKIE_NAME) === '1'; 56 } 57 58 /** 59 * ÐапомниÑÑ Ð¿Ð¾ÐºÐ°Ð·. 60 * 61 * ÐапиÑÑ Ð¸Ð´ÑÑ ÑеÑез единÑÑвеннÑÑ Ð´Ð²ÐµÑÑ Ñ ÑанилиÑа (SITE-27): каÑегоÑÐ¸Ñ 62 * обÑÑвлена лиÑеÑалом на меÑÑе запиÑи и пÑовеÑÑеÑÑÑ Ð² Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð·Ð°Ð¿Ð¸Ñи. Своего 63 * setCookie() Ñ Ð¼Ð¾Ð´ÑÐ»Ñ Ð±Ð¾Ð»ÑÑе Ð½ÐµÑ â забÑÑÑ Ð¿ÑовеÑÐºÑ ÑÑало неÑем. 64 * 65 * Сама запиÑÑ Ð¶Ð´ÑÑ ÑеÑÐµÐ½Ð¸Ñ ÑеÑез whenAllowed(). Ðопап показÑваеÑÑÑ Ð½Ð° 15-й 66 * ÑекÑнде, Ñо еÑÑÑ Ð¾Ð±ÑÑно ÑанÑÑе, Ñем Ñеловек оÑвеÑÐ¸Ñ Ð±Ð°Ð½Ð½ÐµÑÑ, и ÑÐ°Ð·Ð¾Ð²Ð°Ñ 67 * попÑÑка запиÑи в ÑÑÐ¾Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñ ÑпиÑалаÑÑ Ð±Ñ Ð² оÑказ двеÑи навÑегда: ÑоглаÑие, 68 * данное Ñледом, ÐµÑ Ñже не повÑоÑÑеÑ, и огÑаниÑение «Ñаз в 7 дней» молÑа 69 * пÑевÑаÑалоÑÑ Ð±Ñ Ð² «каждÑÑ Ð·Ð°Ð³ÑÑÐ·ÐºÑ ÑÑÑаниÑÑ» Ñ Ð²ÑÐµÑ , кÑо нажал «ÐÑинÑÑÑ» 70 * поÑле показа. ÐÑи оÑказе fn не вÑполнÑеÑÑÑ Ð²Ð¾Ð²Ñе, а пÑовеÑка каÑегоÑии 71 * внÑÑÑи двеÑи оÑÑаÑÑÑÑ Ð½Ð° меÑÑе â whenAllowed() ÐµÑ Ð½Ðµ заменÑеÑ. 72 */ 73 function markShown() { 74 shownThisPage = true; 75 if (window.P24Consent) { 76 window.P24Consent.whenAllowed('functional', function () { 77 window.P24Consent.set(COOKIE_NAME, '1', COOKIE_DAYS, 'functional'); 78 }); 79 } 80 } 81 82 function isProductOrSolutionPage() { 83 var p = window.location.pathname; 84 return p.indexOf('/products/') === 0 || p.indexOf('/solutions/') === 0; 85 } 86 87 function el(tag, cls, txt) { 88 var e = document.createElement(tag); 89 if (cls) e.className = cls; 90 if (txt !== undefined) e.textContent = txt; 91 return e; 92 } 93 94 function buildDemoVariant(box, close) { 95 var badge = el('div', 'p24-exit-popup__badge', 'ÐеÑплаÑно'); 96 var title = el('h2', 'p24-exit-popup__title', 'ÐоÑмоÑÑиÑе PASS24 вживÑÑ'); 97 var text = el('p', 'p24-exit-popup__text', '30-минÑÑÐ½Ð°Ñ Ð´ÐµÐ¼Ð¾Ð½ÑÑÑаÑÐ¸Ñ Ð¿Ð¾Ð´ Ð²Ð°Ñ Ð¾Ð±ÑÐµÐºÑ â без обÑзаÑелÑÑÑв.'); 98 var cta = el('a', 'p24-btn p24-btn-primary p24-exit-popup__cta', 'ÐапиÑаÑÑÑÑ Ð½Ð° демо'); 99 cta.href = '/demo/'; 100 var skip = el('button', 'p24-exit-popup__skip', 'ÐеÑ, ÑпаÑибо'); 101 skip.addEventListener('click', close); 102 box.appendChild(badge); 103 box.appendChild(title); 104 box.appendChild(text); 105 box.appendChild(cta); 106 box.appendChild(skip); 107 } 108 109 function buildChecklistVariant(box, close) { 110 var badge = el('div', 'p24-exit-popup__badge', 'ÐеÑплаÑнÑй гайд'); 111 var title = el('h2', 'p24-exit-popup__title', 'СкаÑайÑе Ñек-лиÑÑ Ð±ÐµÑплаÑно'); 112 var text = el('p', 'p24-exit-popup__text', '15 пÑнкÑов Ð´Ð»Ñ Ð²ÑбоÑа облаÑной СÐУРâ ÑÐºÐ¾Ð½Ð¾Ð¼Ð¸Ñ 200+ ÑаÑов на поиÑке.'); 113 114 var form = el('form', 'p24-exit-popup__form'); 115 var input = el('input', 'p24-form-input'); 116 input.type = 'email'; 117 input.placeholder = 'ÐÐ°Ñ email'; 118 input.required = true; 119 120 var btn = el('button', 'p24-btn p24-btn-primary', 'ÐолÑÑиÑÑ Ñек-лиÑÑ'); 121 btn.type = 'submit'; 122 123 var consentLabel = el('label', 'p24-form-consent'); 124 var consentBox = document.createElement('input'); 125 consentBox.type = 'checkbox'; 126 consentBox.name = 'consent'; 127 consentBox.required = true; 128 var consentSpan = document.createElement('span'); 129 var consentLink = document.createElement('a'); 130 consentLink.href = '/privacy/'; 131 consentLink.target = '_blank'; 132 consentLink.textContent = 'ÑоглаÑие на\u00A0обÑабоÑÐºÑ Ð¿ÐµÑÑоналÑнÑÑ Ð´Ð°Ð½Ð½ÑÑ '; 133 consentSpan.appendChild(document.createTextNode('Я\u00A0Ð´Ð°Ñ ')); 134 consentSpan.appendChild(consentLink); 135 consentLabel.appendChild(consentBox); 136 consentLabel.appendChild(consentSpan); 137 138 // ÐеобÑзаÑелÑное ÑоглаÑие на Ñекламн
138Ñе ÑообÑÐµÐ½Ð¸Ñ (SITE-24). ÐÑделÑÐ½Ð°Ñ ÑÐµÐ»Ñ 139 // â оÑделÑнÑй ÑекбокÑ: он не required, не оÑмеÑен заÑанее и к ÑоÑÑоÑÐ½Ð¸Ñ 140 // кнопки не пÑивÑзан, оÑказ Ð¾Ñ ÑÐµÐºÐ»Ð°Ð¼Ñ Ð¾ÑпÑавке заÑвки не меÑаеÑ. 141 var adsLabel = el('label', 'p24-form-marketing'); 142 var adsBox = document.createElement('input'); 143 adsBox.type = 'checkbox'; 144 adsBox.name = 'marketing_consent'; 145 adsBox.value = '1'; 146 adsBox.setAttribute('data-p24-marketing-consent', ''); 147 var adsSpan = document.createElement('span'); 148 var adsLink = document.createElement('a'); 149 adsLink.href = '/marketing-consent/'; 150 adsLink.target = '_blank'; 151 adsLink.rel = 'noopener'; 152 adsLink.textContent = 'ÑоглаÑие'; 153 adsSpan.appendChild(document.createTextNode('Я\u00A0Ð´Ð°Ñ ')); 154 adsSpan.appendChild(adsLink); 155 adsSpan.appendChild(document.createTextNode( 156 ' на\u00A0полÑÑение ÑаÑÑÑлки Ñекламно-инÑоÑмаÑионнÑÑ Ð¼Ð°ÑеÑиалов' 157 )); 158 adsLabel.appendChild(adsBox); 159 adsLabel.appendChild(adsSpan); 160 161 // Honeypot: ÑкÑÑÑое поле-ловÑÑка Ð´Ð»Ñ Ð±Ð¾Ñов (единÑй паÑÑеÑн p24-hp). 162 var honeypot = el('input', 'p24-hp'); 163 honeypot.type = 'text'; 164 honeypot.name = 'website'; 165 honeypot.tabIndex = -1; 166 honeypot.setAttribute('autocomplete', 'off'); 167 honeypot.setAttribute('aria-hidden', 'true'); 168 169 form.appendChild(honeypot); 170 form.appendChild(input); 171 form.appendChild(consentLabel); 172 form.appendChild(adsLabel); 173 form.appendChild(btn); 174 175 // Ðнопка вÑклÑÑена, пока не оÑмеÑено ÑоглаÑие на ÐÐн, и гаÑÐ½ÐµÑ Ð¾Ð±ÑаÑно пÑи 176 // ÑнÑÑии Ñлажка (assets/js/consent-gate.js). 177 var consentGate = window.P24ConsentGate.bind(consentBox, btn); 178 179 var successDiv = el('div', 'p24-exit-popup__success'); 180 successDiv.style.display = 'none'; 181 var successText = el('p', '', 'ÐÑпÑавлено! ÐÑовеÑÑÑе поÑÑÑ.'); 182 var successLink = el('a', 'p24-btn p24-btn-secondary', 'ÐÑкÑÑÑÑ Ñек-лиÑÑ'); 183 successLink.href = '/resources/guide-choose-skud/'; 184 successLink.target = '_blank'; 185 successDiv.appendChild(successText); 186 successDiv.appendChild(successLink); 187 188 form.addEventListener('submit', function (e) { 189 e.preventDefault(); 190 var email = input.value.trim(); 191 if (!email) return; 192 193 // ÐÐµÐ¹Ñ ÑоглаÑÐ¸Ñ Ð½Ð° ÐÐн. ФоÑма наÑÑоÑÑаÑ, required бÑаÑÐ·ÐµÑ Ð¿ÑовеÑÑеÑ, 194 // а кнопка до ÑÑого моменÑа вÑклÑÑена, но пÑовеÑка дÑблиÑÑеÑÑÑ Ð·Ð´ÐµÑÑ: 195 // попап живÑÑ Ð½Ð° вÑÐµÑ ÑÑÑаниÑÐ°Ñ , и без Ñвного ÑоглаÑÐ¸Ñ Ð¿Ð¾ÑÑа не должна 196 // ÑÑ Ð¾Ð´Ð¸ÑÑ Ð² CRM ни пÑи ÐºÐ°ÐºÐ¸Ñ ÑÑловиÑÑ . 197 if (!consentGate.isGiven()) { 198 consentLabel.classList.add('has-error'); 199 consentBox.focus(); 200 return; 201 } 202 consentLabel.classList.remove('has-error'); 203 204 // ÐÐµÐ¹Ñ Ð·Ð°Ð½Ð¸Ð¼Ð°ÐµÐ¼ на вÑÐµÐ¼Ñ Ð·Ð°Ð¿ÑоÑа: он же заÑиÑа Ð¾Ñ Ð´Ð²Ð¾Ð¹Ð½Ð¾Ð³Ð¾ ÑабмиÑа и Ð¾Ñ 205 // «оживлениÑ» кнопки, еÑли Ñлажок ÑнимÑÑ Ð¸ поÑÑавÑÑ Ð¾Ð±ÑаÑно во вÑÐµÐ¼Ñ fetch. 206 if (!consentGate.beginSubmit()) return; 207 btn.textContent = 'ÐÑпÑавлÑем...'; 208 209 var data = { 210 email: email, 211 source: 'exit_intent_checklist', 212 consent: true, 213 // Рекламное ÑоглаÑие ÑиÑаеÑÑÑ Ð¸Ð· ÑекбокÑа, а не задаÑÑÑÑ ÐºÐ¾Ð½ÑÑанÑой: 214 // «да» здеÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑавиÑÑ ÑолÑко Ñеловек (SITE-24). 215 marketing_consent: window.P24Marketing.isGiven(form), 216 website: honeypot.value 217 }; 218 window.P24Analytics.enrichFormData(data, function (enriched) { 219 fetch(wpApiSettings.root + 'pass24/v1/download-lead', { 220 method: 'POST', 221 headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': wpApiSettings.nonce }, 222 body: JSON.stringify(enriched), 223 }) 224 .then(function (response) { 225 if (!response.ok) throw new Error('Server error'); 226 form.style.display = 'none'; 227 successDiv.style.display = 'block'; 228 if (typeof ym !== 'undefined') { 229 ym(108384915, 'reachGoal', 'exit_intent_lead'); 230 ym(108384915, 'reachGoal', 'generate_lead'); 231 } 232 }) 233 .catch(function () { 234 // Ðе `disabled = false`: ÑнÑÑое ÑоглаÑие обÑзано оÑÑавиÑÑ ÐºÐ½Ð¾Ð¿ÐºÑ 235 // вÑклÑÑенной и поÑле неÑдаÑной оÑпÑавки. 236 consentGate.endSubmit(); 237 btn.textContent = 'ÐолÑÑиÑÑ Ñек-лиÑÑ'; 238 }); 239 }); 240 }); 241 242 var skip = el('button', 'p24-exit-popup__skip', 'ÐеÑ, ÑпаÑибо'); 243 skip.addEventListener('click', close); 244 245 box.appendChild(badge); 246 box.appendChild(title); 247 box.appendChild(text); 248 box.appendChild(form); 249 box.appendChild(successDiv); 250 box.appendChild(skip); 251 } 252 253 function showPopup() { 254 // ÐÑовеÑка и здеÑÑ, а не ÑолÑко на ÑÑаÑÑе: ÑиÑина могла измениÑÑÑÑ 255 // (повоÑÐ¾Ñ ÑкÑана, ÑеÑайз окна) за 15+ ÑекÑнд до ÑÑабаÑÑÐ²Ð°Ð½Ð¸Ñ ÑаймеÑа. 256 if (isMobileViewport()) return; 257 if (alreadyShown()) return; 258 markShown(); 259 260 var variant = isProductOrSolutionPage() ? 'demo' : 'checklist'; 261 262 var popup = el('div', 'p24-exit-popup'); 263 popup.setAttribute('role', 'dialog'); 264 popup.setAttribute('aria-modal', 'true'); 265
266 var overlay = el('div', 'p24-exit-popup__overlay'); 267 var box = el('div', 'p24-exit-popup__box'); 268 var closeBtn = el('button', 'p24-exit-popup__close', '\u00D7'); 269 closeBtn.setAttribute('aria-label', 'ÐакÑÑÑÑ'); 270 271 function close() { 272 popup.classList.remove('is-visible'); 273 setTimeout(function () { if (popup.parentNode) popup.parentNode.removeChild(popup); }, 300); 274 } 275 276 closeBtn.addEventListener('click', close); 277 overlay.addEventListener('click', close); 278 document.addEventListener('keydown', function escHandler(e) { 279 if (e.key === 'Escape') { close(); document.removeEventListener('keydown', escHandler); } 280 }); 281 282 box.appendChild(closeBtn); 283 284 if (variant === 'demo') { 285 buildDemoVariant(box, close); 286 } else { 287 buildChecklistVariant(box, close); 288 } 289 290 popup.appendChild(overlay); 291 popup.appendChild(box); 292 document.body.appendChild(popup); 293 294 requestAnimationFrame(function () { 295 requestAnimationFrame(function () { popup.classList.add('is-visible'); }); 296 }); 297 } 298 299 document.addEventListener('DOMContentLoaded', function () { 300 if (alreadyShown()) return; 301 // Ðа мобилÑном не заводим ÑаймеÑÑ Ð²Ð¾Ð¾Ð±Ñе â попап Ñам не показÑваеÑÑÑ. 302 if (isMobileViewport()) return; 303 304 var delayPassed = false; 305 306 // Enable triggers only after delay 307 setTimeout(function () { 308 delayPassed = true; 309 }, DELAY_MS); 310 311 // Trigger 1: exit intent (desktop â mouse leaves viewport from top, only after delay) 312 document.addEventListener('mouseleave', function (e) { 313 if (delayPassed && e.clientY <= 0) showPopup(); 314 }); 315 316 // Trigger 2: timed (shows after delay + 15s extra if user hasn't left) 317 setTimeout(showPopup, DELAY_MS + 15000); 318 }); 319})();
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.