PageSourceSearch

https://static.familyspace.ru/js/all/mobile-tap.js?3603

js familyspace.ru collected 2026-10-02 10:07:09 UTC 2,925 bytes, 59 lines download raw bytes

1/* FamilySpace mobile-tap: превращает CSS-hover-меню в tap-toggle на touch-устройствах.
2   Перехватывает первый tap на пункт с hover-dropdown — добавляет класс .tap-open,
3   CSS-правила раскрывают подменю. Повторный tap на пункте/tap вне/Esc — закрывают.
4   На десктопе (без touch) — ничего не делает, hover работает как раньше. */
5(function () {
6    'use strict';
7    var isTouch = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0);
8    if (!isTouch) return;
9
10    // Элементы с hover-dropdown-поведением, которые надо обрабатывать по tap:
11    // - .list-popup > li           (раскрывает .list-popup-items)
12    // - .menu-item-more            (раскрывает .more-balloon)
13    var TRIGGER_SELECTOR = '.list-popup > li, .menu-item-more';
14
15    function closeAll(exceptEl) {
16        var open = document.querySelectorAll('.tap-open');
17        for (var i = 0; i < open.length; i++) {
18            if (exceptEl && open[i].contains(exceptEl)) continue;
19            open[i].classList.remove('tap-open');
20        }
21        // Особый случай: .more-balloon открывается отдельно (это sibling, не ребёнок)
22        if (!exceptEl || !exceptEl.closest('.menu-item-more, .more-balloon')) {
23            var balloon = document.querySelector('.more-balloon');
24            if (balloon) balloon.classList.remove('tap-open');
25        }
26    }
27
28    function handleTap(e) {
29        var trigger = e.target.closest(TRIGGER_SELECTOR);
30        if (!trigger) {
31            // Тап вне триггеров — закрываем всё
32            closeAll(null);
33            return;
34        }
35        // Клик по ссылке ВНУТРИ уже открытого меню — пропускаем (navigate)
36        var inside = e.target.closest('.list-popup-items, .more-balloon');
37        if (inside) return;
38
39        // Первый тап: открываем. Второй тап: закрываем.
40        var wasOpen = trigger.classList.contains('tap-open');
41        closeAll(trigger);
42        if (!wasOpen) {
43            e.preventDefault();
44            trigger.classList.add('tap-open');
45            // Для .menu-item-more дополнительно добавляем класс на .more-balloon
46            if (trigger.classList.contains('menu-item-more')) {
47                var balloon = document.querySelector('.more-balloon');
48                if (balloon) balloon.classList.add('tap-open');
49            }
50        }
51    }
52
53    function onKey(e) {
54        if (e.key === 'Escape' || e.keyCode === 27) closeAll(null);
55    }
56
57    document.addEventListener('click', handleTap, true);
58    document.addEventListener('keydown', onKey, false);
59})();

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.