| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- /* Tocha — публичный сайт: navbar, scroll-reveal, избранное */
- (function () {
- /* ═══════════════════════════════════
- ИЗБРАННОЕ (localStorage)
- Ключ: tocha_favorites → JSON array of car IDs (numbers)
- ═══════════════════════════════════ */
- var FAV_KEY = 'tocha_favorites';
- function getFavs() {
- try { return JSON.parse(localStorage.getItem(FAV_KEY) || '[]'); }
- catch (e) { return []; }
- }
- function saveFavs(ids) {
- localStorage.setItem(FAV_KEY, JSON.stringify(ids));
- }
- // Переключить избранное для авто c data-car-id
- window.toggleFavorite = function (id, btn) {
- id = parseInt(id, 10);
- var favs = getFavs();
- var idx = favs.indexOf(id);
- if (idx === -1) {
- favs.push(id);
- } else {
- favs.splice(idx, 1);
- }
- saveFavs(favs);
- updateBtn(btn, favs.indexOf(id) !== -1);
- updateNavCounter();
- };
- // Обновить внешний вид кнопки ♡ / ♥
- function updateBtn(btn, active) {
- if (!btn) return;
- btn.classList.toggle('fav-active', active);
- btn.title = active ? 'Убрать из избранного' : 'Добавить в избранное';
- btn.textContent = active ? '♥' : '♡';
- }
- // Подсветить все сердца на странице по текущему состоянию localStorage
- window.markHearts = function () {
- var favs = getFavs();
- document.querySelectorAll('.car-img-fav[data-car-id]').forEach(function (btn) {
- var id = parseInt(btn.getAttribute('data-car-id'), 10);
- updateBtn(btn, favs.indexOf(id) !== -1);
- });
- };
- // Обновить счётчик в навигации и состояние кнопки избранного
- window.updateNavCounter = function () {
- var count = getFavs().length;
- var el = document.getElementById('favNavCount');
- var btn = document.getElementById('navFavBtn');
- if (el) {
- el.textContent = count || '';
- el.style.display = count ? 'inline-flex' : 'none';
- }
- if (btn) {
- btn.classList.toggle('has-items', count > 0);
- }
- };
- /* ═══════════════════════════════════
- ИНИЦИАЛИЗАЦИЯ
- ═══════════════════════════════════ */
- document.addEventListener('DOMContentLoaded', function () {
- /* ── Избранное: подсвечиваем сердца + счётчик ── */
- markHearts();
- updateNavCounter();
- /* ── navbar scroll shadow ── */
- var nb = document.getElementById('navbar');
- if (nb) {
- window.addEventListener('scroll', function () {
- nb.classList.toggle('scrolled', window.scrollY > 24);
- }, { passive: true });
- }
- /* ── burger / мобильное меню ── */
- document.addEventListener('click', function (e) {
- var burger = document.getElementById('burger');
- var nl = document.getElementById('navLinks');
- if (!burger || !nl) return;
- if (burger.contains(e.target)) {
- var open = nl.classList.toggle('nav-open');
- if (open) {
- Object.assign(nl.style, {
- display: 'flex', flexDirection: 'column',
- position: 'absolute', top: '100%', left: '0', right: '0',
- background: 'rgba(255,255,255,.98)',
- padding: '12px 20px', gap: '2px',
- borderBottom: '1px solid #e8e6e0',
- boxShadow: '0 8px 24px rgba(0,0,0,.1)',
- zIndex: '99'
- });
- } else {
- nl.style.cssText = '';
- }
- } else if (!nl.contains(e.target) && nl.classList.contains('nav-open')) {
- nl.classList.remove('nav-open');
- nl.style.cssText = '';
- }
- });
- /* ── scroll reveal (IntersectionObserver) ── */
- /* Пропускаем когда анимации отключены в настройках сайта */
- if (document.body.classList.contains('no-animations')) {
- document.querySelectorAll('.reveal, .reveal-up, .stagger').forEach(function (el) {
- el.classList.add('in');
- });
- } else if ('IntersectionObserver' in window) {
- var io = new IntersectionObserver(function (entries) {
- entries.forEach(function (entry) {
- if (entry.isIntersecting) {
- entry.target.classList.add('in');
- io.unobserve(entry.target);
- }
- });
- }, { threshold: 0.07, rootMargin: '0px 0px -28px 0px' });
- document.querySelectorAll('.reveal, .reveal-up, .stagger').forEach(function (el) {
- var rect = el.getBoundingClientRect();
- if (rect.top < window.innerHeight && rect.bottom > 0) {
- el.classList.add('in');
- } else {
- io.observe(el);
- }
- });
- } else {
- document.querySelectorAll('.reveal, .reveal-up, .stagger').forEach(function (el) {
- el.classList.add('in');
- });
- }
- });
- })();
|