update astra

This commit is contained in:
alexencom committed 2026-10-31 00:11:26 +03:00
1 parent 9a75e6d45a
commit 6addd97a93
14 files changed
+1635 -508

No files matched your search

+71 -46
View File
@@ -1,44 +1,66 @@
// ===== Cookie Banner =====
// Analytics: use the existing Metrika counter and the supplied GTM container.
// A GTM- identifier is a Tag Manager container, not a GA4 measurement ID.
(function() {
const key = 'olyapka_analytics_v2';
const banner = document.getElementById('cookieBanner');
const acceptBtn = document.getElementById('cookieAccept');
if (!banner || !acceptBtn) return;
const consent = localStorage.getItem('olyapka_cookies_consent');
if (!consent) {
setTimeout(() => banner.classList.add('show'), 800);
} else {
banner.classList.add('hidden');
let choice = null;
try { choice = localStorage.getItem(key); } catch (err) { /* storage may be blocked */ }
window.analyticsAllowed = choice === 'accepted';
function loadAnalytics() {
if (!window.analyticsAllowed || window.analyticsLoaded) return;
window.analyticsLoaded = true;
window.ym = window.ym || function() { (window.ym.a = window.ym.a || []).push(arguments); };
window.ym.l = Date.now();
const metrika = document.createElement('script');
metrika.async = true; metrika.src = 'https://mc.yandex.ru/metrika/tag.js';
document.head.append(metrika);
window.ym(110606131, 'init', {clickmap: true, trackLinks: true, accurateTrackBounce: true, webvisor: true});
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({'gtm.start': Date.now(), event: 'gtm.js'});
const gtm = document.createElement('script');
gtm.async = true; gtm.src = 'https://www.googletagmanager.com/gtm.js?id=GTM-M5HGH586';
document.head.append(gtm);
}
acceptBtn.addEventListener('click', function() {
localStorage.setItem('olyapka_cookies_consent', '1');
function choose(value) {
const wasAllowed = window.analyticsAllowed;
try { localStorage.setItem(key, value); } catch (err) { /* session-only choice */ }
window.analyticsAllowed = value === 'accepted';
banner.hidden = true;
banner.classList.remove('show');
setTimeout(() => banner.classList.add('hidden'), 400);
// Goal for Yandex.Metrika
if (typeof ym !== 'undefined') ym(110606131, 'reachGoal', 'cookie_accept');
if (typeof gtag !== 'undefined') gtag('event', 'cookie_accept');
});
if (wasAllowed && !window.analyticsAllowed) { location.reload(); return; }
loadAnalytics();
}
if (banner) {
if (!choice) { banner.hidden = false; banner.classList.add('show'); }
document.getElementById('cookieAccept').addEventListener('click', () => choose('accepted'));
document.getElementById('cookieDecline').addEventListener('click', () => choose('declined'));
document.getElementById('cookieSettings').addEventListener('click', () => {
banner.hidden = false; banner.classList.add('show');
document.getElementById('cookieAccept').focus();
});
}
loadAnalytics();
})();
// ===== Mobile Menu =====
// Accessible mobile navigation, including Escape and focus return.
(function() {
const burger = document.getElementById('burger');
const nav = document.getElementById('nav');
if (!burger || !nav) return;
burger.addEventListener('click', function() {
burger.classList.toggle('open');
nav.classList.toggle('open');
});
// Close on link click
nav.querySelectorAll('.nav-link').forEach(link => {
link.addEventListener('click', () => {
burger.classList.remove('open');
nav.classList.remove('open');
});
document.documentElement.classList.add('js-menu');
function setOpen(open) {
burger.classList.toggle('open', open);
nav.classList.toggle('open', open);
burger.setAttribute('aria-expanded', String(open));
burger.setAttribute('aria-label', open ? 'Закрыть меню' : 'Открыть меню');
}
burger.addEventListener('click', () => setOpen(burger.getAttribute('aria-expanded') !== 'true'));
nav.addEventListener('click', e => { if (e.target.closest('a')) setOpen(false); });
document.addEventListener('keydown', e => {
if (e.key === 'Escape' && nav.classList.contains('open')) { setOpen(false); burger.focus(); }
});
document.addEventListener('click', e => { if (!nav.contains(e.target) && !burger.contains(e.target)) setOpen(false); });
matchMedia('(max-width: 768px)').addEventListener('change', () => setOpen(false));
})();
// ===== Goal Tracking (Yandex.Metrika + GA) =====
@@ -50,26 +72,15 @@
if (!goal) return;
// Yandex.Metrika
if (typeof ym !== 'undefined') {
if (window.analyticsAllowed && typeof ym !== 'undefined') {
try { ym(110606131, 'reachGoal', goal); } catch(err) {}
}
// Google Analytics
if (typeof gtag !== 'undefined') {
try { gtag('event', goal); } catch(err) {}
}
if (window.analyticsAllowed && window.dataLayer) window.dataLayer.push({event: goal});
});
})();
// ===== Smooth scroll for anchor links =====
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
const target = document.querySelector(this.getAttribute('href'));
if (target) {
e.preventDefault();
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
// Native anchor navigation preserves URL fragments and keyboard focus.
// ===== Portfolio Video Lightbox =====
(function() {
@@ -81,9 +92,15 @@ document.querySelectorAll('a[href^="#"]').forEach(anchor => {
if (!modal || !player || !triggers.length) return;
let lastFocus = null;
const background = Array.from(document.body.children).filter(el => el !== modal && el.tagName !== 'SCRIPT');
let inertStates = [];
modal.setAttribute('inert', '');
function open(src, label) {
lastFocus = document.activeElement;
modal.removeAttribute('inert');
inertStates = background.map(el => el.inert);
background.forEach(el => { el.inert = true; });
title.textContent = label || '';
player.src = src;
modal.classList.add('open');
@@ -101,6 +118,8 @@ document.querySelectorAll('a[href^="#"]').forEach(anchor => {
player.pause();
modal.classList.remove('open');
modal.setAttribute('aria-hidden', 'true');
modal.setAttribute('inert', '');
background.forEach((el, i) => { el.inert = inertStates[i]; });
document.body.classList.remove('video-modal-open');
setTimeout(() => {
if (!modal.classList.contains('open')) {
@@ -139,7 +158,7 @@ document.querySelectorAll('a[href^="#"]').forEach(anchor => {
const v = entry.target;
obs.unobserve(v);
if (v.readyState < 2) {
v.preload = 'auto';
v.preload = 'metadata';
v.load();
}
v.addEventListener('loadeddata', () => {
@@ -169,7 +188,13 @@ document.querySelectorAll('a[href^="#"]').forEach(anchor => {
document.addEventListener('keydown', function(e) {
if (!modal.classList.contains('open')) return;
if (e.key === 'Escape') { close(); return; }
if (e.key === 'Tab') {
const stops = Array.from(modal.querySelectorAll('button, video[controls]'));
const first = stops[0], last = stops[stops.length - 1];
if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
}
if (e.key === ' ' && document.activeElement === player) return; // native handling
if (e.key === 'f' || e.key === 'F') toggleFullscreen();
if ((e.key === 'f' || e.key === 'F') && document.activeElement === player) toggleFullscreen();
});
})();