<style>
/*Стиль для выделенного пункта*/
.uc-main-menu a.active-anchor {
color: #ffffff !important;
font-weight: 600;
text-decoration: underline !important;
}
.uc-main-menu a {
transition: all 0.2s ease-in-out;
}
</style>
<script>
(function() {
'use strict';
let menuLinks = [];
let anchors = [];
let menuContainers = [];
let ticking = false;
let resizeTimeout;
let offset = 20;
let currentPageUrl = '';
function init() {
currentPageUrl = window.location.pathname;
findMenuContainers();
findAnchors();
setupEventListeners();
setInitialActiveAnchor();
}
function findMenuContainers() {
menuContainers = document.querySelectorAll('.uc-main-menu');
if (menuContainers.length === 0) {
return;
}
menuLinks = [];
menuContainers.forEach(container => {
const links = container.querySelectorAll('a');
links.forEach(link => {
const href = link.getAttribute('href');
if (!href) return;
if (href.startsWith('#')) {
menuLinks.push({
element: link,
anchorName: href.substring(1),
type: 'anchor'
});
} else {
try {
const linkUrl = new URL(href, window.location.origin);
if (linkUrl.pathname === currentPageUrl) {
menuLinks.push({
element: link,
anchorName: null,
type: 'page'
});
}
} catch (e) {
if (href === currentPageUrl) {
menuLinks.push({
element: link,
anchorName: null,
type: 'page'
});
}
}
}
});
});
}
function findAnchors() {
anchors = [];
const anchorNames = [...new Set(menuLinks
.filter(link => link.type === 'anchor')
.map(link => link.anchorName))];
anchorNames.forEach(name => {
let element = document.getElementById(name);
if (!element) {
element = document.querySelector(`a[name="${name}"], [name="${name}"]`);
}
if (element) {
anchors.push({
name: name,
element: element
});
}
});
}
function setupEventListeners() {
window.addEventListener('scroll', function() {
if (!ticking) {
window.requestAnimationFrame(function() {
updateActiveAnchor();
ticking = false;
});
ticking = true;
}
});
window.addEventListener('resize', function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function() {
updateActiveAnchor();
}, 150);
});
}
function setInitialActiveAnchor() {
if (window.location.hash) {
const hash = window.location.hash.substring(1);
const anchor = anchors.find(a => a.name === hash);
if (anchor) {
setTimeout(() => {
updateActiveAnchor();
}, 100);
return;
}
}
setTimeout(updateActiveAnchor, 100);
}
function updateActiveAnchor() {
if (menuLinks.length === 0) return;
const scrollPosition = window.scrollY;
let activeAnchor = null;
for (let i = anchors.length - 1; i >= 0; i--) {
const anchor = anchors[i];
const rect = anchor.element.getBoundingClientRect();
const absoluteTop = rect.top + scrollPosition;
if (absoluteTop - offset <= scrollPosition) {
activeAnchor = anchor;
break;
}
}
updateMenuClasses(activeAnchor);
}
function updateMenuClasses(activeAnchor) {
menuLinks.forEach(link => {
link.element.classList.remove('active-anchor');
});
if (activeAnchor) {
menuLinks.forEach(link => {
if (link.type === 'anchor' && link.anchorName === activeAnchor.name) {
link.element.classList.add('active-anchor');
}
});
} else {
const pageLinks = menuLinks.filter(link => link.type === 'page');
if (pageLinks.length > 0) {
pageLinks.forEach(link => {
link.element.classList.add('active-anchor');
});
}
}
}
function reinit() {
currentPageUrl = window.location.pathname;
findMenuContainers();
findAnchors();
updateActiveAnchor();
}
function setOffset(newOffset) {
offset = newOffset;
updateActiveAnchor();
}
if (window.MutationObserver) {
const observer = new MutationObserver(function(mutations) {
let shouldReinit = false;
mutations.forEach(mutation => {
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
shouldReinit = true;
}
});
if (shouldReinit) {
reinit();
}
});
if (document.body) {
observer.observe(document.body, {
childList: true,
subtree: true
});
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
window.UCMainMenu = {
reinit: reinit,
update: updateActiveAnchor,
setOffset: setOffset
};
})();
</script>