MediaWiki:Common.js: различия между версиями
Страница интерфейса MediaWiki
Дополнительные действия
Askell (обсуждение | вклад) Нет описания правки Метка: ручная отмена |
Askell (обсуждение | вклад) Нет описания правки Метка: отменено |
||
| Строка 32: | Строка 32: | ||
}); | }); | ||
}); | }); | ||
// Универсальный фикс для dropdown, переводим раскрытые меню в поток документа | |||
( function () { | |||
function fixDropdown(el) { | |||
if (!el) return; | |||
try { | |||
el.style.position = ''; | |||
el.style.top = ''; | |||
el.style.left = ''; | |||
el.style.right = ''; | |||
el.style.transform = ''; | |||
el.style.zIndex = ''; | |||
el.style.maxHeight = ''; | |||
el.style.overflow = ''; | |||
} catch (e) { /* ignore */ } | |||
} | |||
// На клики по кнопке открывающей меню — удаляем inline-стили у .dropdown-content | |||
document.addEventListener('click', function (e) { | |||
// попытка поймать ближайший .dropdown | |||
var but = e.target.closest && e.target.closest('.dropbtn, .dropdown, .dropdown-toggle, [data-dropdown]'); | |||
if (but) { | |||
// небольшая задержка, чтобы скрипт, открывающий меню, выполнил своё и мы могли почистить | |||
setTimeout(function () { | |||
var dropdowns = document.querySelectorAll('.dropdown, .dropdown.active, .dropdown.open, .menu-column'); | |||
dropdowns.forEach(function (d) { | |||
// исправляем сам контейнер | |||
fixDropdown(d); | |||
// исправляем контент | |||
var c = d.querySelector('.dropdown-content, .menu, .dropdown-menu, .citizen-dropdown__content'); | |||
if (c) fixDropdown(c); | |||
}); | |||
}, 20); | |||
} | |||
}, false); | |||
// При любом модифицировании DOM (на случай, если меню открывает сторонний скрипт) | |||
var observer = new MutationObserver(function (mutations) { | |||
mutations.forEach(function (m) { | |||
if (m.addedNodes && m.addedNodes.length) { | |||
m.addedNodes.forEach(function (node) { | |||
if (!(node instanceof HTMLElement)) return; | |||
if (node.matches('.dropdown, .dropdown-content, .dropdown.active, .dropdown.open, .dropdown-menu')) { | |||
fixDropdown(node); | |||
} | |||
var inner = node.querySelector && (node.querySelector('.dropdown, .dropdown-content, .dropdown.active, .dropdown.open, .dropdown-menu')); | |||
if (inner) fixDropdown(inner); | |||
}); | |||
} | |||
// также пробуем почистить целевые элементы, если у них появились атрибуты стиля | |||
if (m.target && m.target instanceof HTMLElement) { | |||
if (m.target.matches && (m.target.matches('.dropdown, .dropdown-content, .dropdown.active, .dropdown.open, .dropdown-menu'))) { | |||
fixDropdown(m.target); | |||
} | |||
} | |||
}); | |||
}); | |||
observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); | |||
// Очистка для уже открытых при загрузке | |||
window.addEventListener('load', function () { | |||
document.querySelectorAll('.dropdown, .dropdown-content, .dropdown.active, .dropdown.open, .dropdown-menu').forEach(function (el) { | |||
fixDropdown(el); | |||
}); | |||
}); | |||
}() ); | |||
Версия от 16:21, 1 декабря 2025
/* Размещённый здесь код JavaScript будет загружаться пользователям при обращении к каждой странице */
mw.loader.using('mediawiki.util').then(function() {
var isMobile = mw.config.get('skin') === 'minerva';
if (isMobile) {
// Мобильная версия
$('.mobile-hide').hide();
} else {
// Десктопная версия
$('.desktop-hide').hide();
}
});
mw.hook('wikipage.content').add(function($content) {
$content.find('.dropbtn').on('click', function(event) {
event.preventDefault();
var dropdown = $(this).closest('.dropdown');
var content = dropdown.find('.dropdown-content');
// Закрываем все открытые списки
$('.dropdown').not(dropdown).removeClass('active').find('.dropdown-content').css('max-height', '0px');
// Открываем/закрываем текущий список
if (dropdown.hasClass('active')) {
dropdown.removeClass('active');
content.css('max-height', '0px');
} else {
dropdown.addClass('active');
content.css('max-height', content[0].scrollHeight + 'px'); // Автоматическая высота
}
});
});
// Универсальный фикс для dropdown, переводим раскрытые меню в поток документа
( function () {
function fixDropdown(el) {
if (!el) return;
try {
el.style.position = '';
el.style.top = '';
el.style.left = '';
el.style.right = '';
el.style.transform = '';
el.style.zIndex = '';
el.style.maxHeight = '';
el.style.overflow = '';
} catch (e) { /* ignore */ }
}
// На клики по кнопке открывающей меню — удаляем inline-стили у .dropdown-content
document.addEventListener('click', function (e) {
// попытка поймать ближайший .dropdown
var but = e.target.closest && e.target.closest('.dropbtn, .dropdown, .dropdown-toggle, [data-dropdown]');
if (but) {
// небольшая задержка, чтобы скрипт, открывающий меню, выполнил своё и мы могли почистить
setTimeout(function () {
var dropdowns = document.querySelectorAll('.dropdown, .dropdown.active, .dropdown.open, .menu-column');
dropdowns.forEach(function (d) {
// исправляем сам контейнер
fixDropdown(d);
// исправляем контент
var c = d.querySelector('.dropdown-content, .menu, .dropdown-menu, .citizen-dropdown__content');
if (c) fixDropdown(c);
});
}, 20);
}
}, false);
// При любом модифицировании DOM (на случай, если меню открывает сторонний скрипт)
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (m) {
if (m.addedNodes && m.addedNodes.length) {
m.addedNodes.forEach(function (node) {
if (!(node instanceof HTMLElement)) return;
if (node.matches('.dropdown, .dropdown-content, .dropdown.active, .dropdown.open, .dropdown-menu')) {
fixDropdown(node);
}
var inner = node.querySelector && (node.querySelector('.dropdown, .dropdown-content, .dropdown.active, .dropdown.open, .dropdown-menu'));
if (inner) fixDropdown(inner);
});
}
// также пробуем почистить целевые элементы, если у них появились атрибуты стиля
if (m.target && m.target instanceof HTMLElement) {
if (m.target.matches && (m.target.matches('.dropdown, .dropdown-content, .dropdown.active, .dropdown.open, .dropdown-menu'))) {
fixDropdown(m.target);
}
}
});
});
observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });
// Очистка для уже открытых при загрузке
window.addEventListener('load', function () {
document.querySelectorAll('.dropdown, .dropdown-content, .dropdown.active, .dropdown.open, .dropdown-menu').forEach(function (el) {
fixDropdown(el);
});
});
}() );