PageSourceSearch

https://dek-art.ru/bitrix/templates/aspro-priority2/js/custom.js?17764132196421

js dek-art.ru collected 2026-10-04 23:54:59 UTC 6,421 bytes, 199 lines download raw bytes

1
2document.addEventListener('DOMContentLoaded', function () {
3  /* 1. Оборачиваем таблицы в responsive-контейнер */
4  document.querySelectorAll('.tabs.price table').forEach(function (table) {
5    if (!table.parentElement.classList.contains('table-responsive')) {
6      const wrapper = document.createElement('div');
7      wrapper.className = 'table-responsive';
8      table.parentNode.insertBefore(wrapper, table);
9      wrapper.appendChild(table);
10    }
11  });
12
13  /* 2. Добавляем подсказку для горизонтального скролла */
14  document.querySelectorAll('.tabs.price .table-responsive').forEach(function (wrapper) {
15    if (!wrapper.querySelector('.table-scroll-hint')) {
16      const hint = document.createElement('div');
17      hint.className = 'table-scroll-hint';
18      hint.innerHTML = '<span class="table-scroll-hint__arrows">← →</span><span>свайп</span>';
19      wrapper.appendChild(hint);
20    }
21  });
22
23  function updateScrollHints() {
24    const isMobile = window.innerWidth <= 991;
25
26    document.querySelectorAll('.tabs.price .table-responsive').forEach(function (wrapper) {
27      const table = wrapper.querySelector('table');
28      const hint = wrapper.querySelector('.table-scroll-hint');
29      if (!table || !hint) return;
30
31      const hasHorizontalScroll = table.scrollWidth > wrapper.clientWidth + 10;
32
33      if (isMobile && hasHorizontalScroll && wrapper.scrollLeft < 10) {
34        hint.style.display = 'flex';
35        hint.classList.remove('is-hidden');
36      } else {
37        hint.style.display = 'none';
38        hint.classList.add('is-hidden');
39      }
40    });
41  }
42
43  document.querySelectorAll('.tabs.price .table-responsive').forEach(function (wrapper) {
44    wrapper.addEventListener('scroll', function () {
45      const hint = wrapper.querySelector('.table-scroll-hint');
46      if (!hint) return;
47
48      if (wrapper.scrollLeft > 10) {
49        hint.classList.add('is-hidden');
50        setTimeout(function () {
51          hint.style.display = 'none';
52        }, 250);
53      }
54    }, { passive: true });
55  });
56
57  /* 3. Инициализация всех таб-контейнеров */
58  document.querySelectorAll('.tabs.price').forEach(function (tabsBlock) {
59    const tabLinks = tabsBlock.querySelectorAll(':scope > .nav.nav-tabs .nav-link');
60    const panes = tabsBlock.querySelectorAll(':scope > .tab-content > .tab-pane');
61
62    if (!tabLinks.length || !panes.length) return;
63
64    function deactivateAll() {
65      tabLinks.forEach(function (link) {
66        link.classList.remove('active');
67        link.setAttribute('aria-selected', 'false');
68
69        const li = link.closest('.nav-item');
70        if (li) li.classList.remove('active');
71      });
72
73      panes.forEach(function (pane) {
74        pane.classList.remove('active');
75      });
76    }
77
78    function activateTab(link, setHash) {
79      const targetSelector = link.getAttribute('href');
80      if (!targetSelector || targetSelector.charAt(0) !== '#') return;
81
82      const targetPane = tabsBlock.querySelector(':scope > .tab-content > ' + targetSelector);
83      if (!targetPane) return;
84
85      deactivateAll();
86
87      link.classList.add('active');
88      link.setAttribute('aria-selected', 'true');
89
90      const li = link.closest('.nav-item');
91      if (li) li.classList.add('active');
92
93      targetPane.classList.add('active');
94
95      if (setHash) {
96        history.replaceState(null, '', targetSelector);
97      }
98
99      setTimeout(updateScrollHints, 50);
100    }
101
102    tabLinks.forEach(function (link) {
103      link.addEventListener('click', function (e) {
104        e.preventDefault();
105        activateTab(link, false);
106      });
107    });
108
109    let currentActiveLink = tabsBlock.querySelector(':scope > .nav.nav-tabs .nav-link.active');
110    if (!currentActiveLink) {
111      const activeLiLink = tabsBlock.querySelector(':scope > .nav.nav-tabs .nav-item.active .nav-link');
112      if (activeLiLink) currentActiveLink = activeLiLink;
113    }
114    if (!currentActiveLink) {
115      currentActiveLink = tabLinks[0];
116    }
117
118    activateTab(currentActiveLink, false);
119  });
120
121  /* 4. Если в URL есть hash — пробуем открыть соответствующую вкладку */
122  if (window.location.hash) {
123    const hashLink = document.querySelector('.tabs.price .nav-link[href="' + window.location.hash + '"]');
124    if (hashLink) {
125      hashLink.click();
126
127      setTimeout(function () {
128        const target = document.querySelector(window.location.hash);
129        if (target) {
130          target.scrollIntoView({ behavior: 'smooth', block: 'start' });
131        }
132      }, 100);
133    }
134  }
135
136  /* 5. Обновление при загрузке и ресайзе */
137  updateScrollHints();
138  window.addEventListener('resize', updateScrollHints);
139  
140
141  function clearTableHover(table) {
142    table.querySelectorAll('.hover-row, .hover-col, .hover-cell').forEach(function (cell) {
143      cell.classList.remove('hover-row', 'hover-col', 'hover-cell');
144    });
145  }
146
147  function bindCrossHoverForTabsTables() {
148    document.querySelectorAll('.tabs.price table').forEach(function (table) {
149      if (table.dataset.crossReady === 'true') return;
150      table.dataset.crossReady = 'true';
151
152      table.addEventListener('mouseover', function (e) {
153        if (window.innerWidth <= 991) return;
154
155        const cell = e.target.closest('td, th');
156        if (!cell || !table.contains(cell)) return;
157
158        const row = cell.parentElement;
159        if (!row) return;
160
161        const cellsInRow = Array.from(row.children);
162        const colIndex = cellsInRow.indexOf(cell);
163        if (colIndex === -1) return;
164
165        clearTableHover(table);
166
167        Array.from(row.children).forEach(function (c) {
168          c.classList.add('hover-row');
169        });
170
171        table.querySelectorAll('tr').forEach(function (tr) {
172          if (tr.children[colIndex]) {
173            tr.children[colIndex].classList.add('hover-col');
174          }
175        });
176
177        cell.classList.add('hover-cell');
178      });
179
180      table.addEventListener('mouseleave', function () {
181        clearTableHover(table);
182      });
183    });
184  }
185
186  bindCrossHoverForTabsTables();
187
188  window.addEventListener('resize', function () {
189    document.querySelectorAll('.tabs.price table').forEach(function (table) {
190      clearTableHover(table);
191    });
192  });
193
194  setTimeout(bindCrossHoverForTabsTables, 200);
195
196  
197});
198             
199                

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.