'use strict'; /* ═══════════════════════════════════════════════════════════════════ ОБЩИЕ СКРИПТЫ САЙТА ═══════════════════════════════════════════════════════════════════ Здесь собраны все общие обработчики, которые работают на любой странице сайта: 1. Бургер-меню (мобильная навигация) 2. Год в подвале 3. Кнопка «наверх» 4. Reveal-анимации (появление блоков при прокрутке) 5. Выезжающий слайдер «Что нового в классе» (только на главной) ═══════════════════════════════════════════════════════════════════ */ /* ─── 1. БУРГЕР-МЕНЮ ────────────────────────────────────────────── На экранах шириной меньше 720px меню превращается в бургер. Клик по бургеру разворачивает вертикальный список ссылок. Клик по любой ссылке - сворачивает обратно. */ (function initBurger() { var burger = document.getElementById('burger'); var nav = document.getElementById('nav'); if (!burger || !nav) return; burger.addEventListener('click', function () { var open = nav.classList.toggle('open'); burger.setAttribute('aria-expanded', String(open)); }); nav.addEventListener('click', function (e) { if (e.target.classList.contains('nav-link')) { nav.classList.remove('open'); burger.setAttribute('aria-expanded', 'false'); } }); })(); /* ─── 2. ГОД В ПОДВАЛЕ ──────────────────────────────────────────── Все элементы с классом .js-year автоматически получают текущий год. Это избавляет от необходимости менять год в футере вручную. */ (function initYear() { var year = String(new Date().getFullYear()); document.querySelectorAll('.js-year').forEach(function (el) { el.textContent = year; }); })(); /* ─── 3. КНОПКА «НАВЕРХ» ────────────────────────────────────────── Появляется при прокрутке больше 400px. Клик - плавный скролл в начало страницы. */ (function initToTop() { var toTop = document.querySelector('.to-top'); if (!toTop) return; window.addEventListener('scroll', function () { toTop.classList.toggle('visible', window.scrollY > 400); }, { passive: true }); toTop.addEventListener('click', function () { window.scrollTo({ top: 0, behavior: 'smooth' }); }); })(); /* ─── 4. REVEAL-АНИМАЦИИ ────────────────────────────────────────── Все блоки с классом .reveal изначально скрыты (opacity: 0) и плавно появляются, когда пользователь доскроллит до них. Если IntersectionObserver не поддерживается - показываем сразу. */ (function initReveal() { var els = document.querySelectorAll('.reveal'); if (!els.length) return; if (!('IntersectionObserver' in window)) { els.forEach(function (el) { el.classList.add('visible'); }); return; } var io = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { entry.target.classList.add('visible'); io.unobserve(entry.target); } }); }, { threshold: 0.1 }); els.forEach(function (el) { io.observe(el); }); })(); /* ─── 5. ВЫЕЗЖАЮЩИЙ СЛАЙДЕР «ЧТО НОВОГО В КЛАССЕ» ───────────────── Показывается только на главной странице сайта. По умолчанию свёрнут в вертикальную вкладку у правого края экрана. Клик по вкладке - панель выезжает слева и показывает список новостей. Способы закрыть: крестик, клик по затемнению, клавиша Esc. */ (function initNewsSlider() { function start() { var slider = document.getElementById('newsSlider'); var toggle = document.getElementById('newsToggle'); var closeBtn = document.getElementById('newsClose'); var backdrop = document.getElementById('newsBackdrop'); /* Если на странице нет слайдера - молча выходим */ if (!slider || !toggle) return; console.log('[news-slider] инициализация'); /* Открыть панель */ function open() { slider.classList.add('open'); toggle.setAttribute('aria-expanded', 'true'); /* На время открытия блокируем прокрутку страницы под панелью */ document.body.style.overflow = 'hidden'; } /* Закрыть панель */ function close() { slider.classList.remove('open'); toggle.setAttribute('aria-expanded', 'false'); document.body.style.overflow = ''; } /* Переключатель: если открыто - закрываем, если закрыто - открываем */ function togglePanel() { if (slider.classList.contains('open')) close(); else open(); } /* Обработчики */ toggle.addEventListener('click', togglePanel); if (closeBtn) { closeBtn.addEventListener('click', close); } if (backdrop) { backdrop.addEventListener('click', close); } /* Esc закрывает панель */ document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && slider.classList.contains('open')) close(); }); /* Счётчик новостей на вкладке - сколько карточек в списке */ var countEl = document.getElementById('newsCount'); if (countEl) { var items = slider.querySelectorAll('.news-item'); countEl.textContent = items.length; } /* Скрываем слайдер везде, кроме главной страницы сайта. Проверяем путь: index.html в корне, либо "/", либо пусто. Во всех подпапках (уроки, тесты, backlog) слайдер не нужен. */ var path = window.location.pathname; var isHome = /(^|\/)index\.html$/.test(path) || path === '/' || path.endsWith('/'); var isInSubfolder = /\/(tests|[0-9]+|basy|sosedi|backlog)\//.test(path); if (!isHome || isInSubfolder) { slider.style.display = 'none'; } } /* Запускаем после полной загрузки DOM, чтобы все элементы слайдера уже были в документе */ if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', start); } else { start(); } })();