MediaWiki:Common.js: различия между версиями
Страница интерфейса MediaWiki
Дополнительные действия
Add_particles_and_interactions |
Shorten_mobile_search_placeholder |
||
| Строка 87: | Строка 87: | ||
input.type = 'search'; | input.type = 'search'; | ||
input.autocomplete = 'off'; | input.autocomplete = 'off'; | ||
input.placeholder = slot.textContent.trim(); | input.placeholder = window.innerWidth < 560 ? 'страна, сервис или мера...' : slot.textContent.trim(); | ||
input.setAttribute('aria-label', 'Поиск по BRICSCompass'); | input.setAttribute('aria-label', 'Поиск по BRICSCompass'); | ||
slot.replaceChildren(input); | slot.replaceChildren(input); | ||
Версия от 22:27, 25 мая 2026
(function () {
'use strict';
function onReady(fn) {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', fn);
return;
}
fn();
}
function loadScript(src, done) {
if (document.querySelector('script[src="' + src + '"]')) {
done();
return;
}
var script = document.createElement('script');
script.src = src;
script.async = true;
script.onload = done;
document.head.appendChild(script);
}
function initParticles() {
var hero = document.querySelector('.bc-hero');
if (!hero || document.getElementById('bc-particles')) {
return;
}
var host = document.createElement('div');
host.id = 'bc-particles';
hero.insertBefore(host, hero.firstChild);
loadScript('https://cdn.jsdelivr.net/npm/particles.js@2.0.0/particles.min.js', function () {
if (!window.particlesJS) {
return;
}
window.particlesJS('bc-particles', {
particles: {
number: { value: 42, density: { enable: true, value_area: 900 } },
color: { value: ['#1d5f9f', '#e40046', '#2f6f73'] },
shape: { type: 'circle' },
opacity: { value: 0.22, random: true },
size: { value: 3, random: true },
line_linked: {
enable: true,
distance: 150,
color: '#1d5f9f',
opacity: 0.14,
width: 1
},
move: {
enable: true,
speed: 1.1,
direction: 'none',
random: true,
straight: false,
out_mode: 'out',
bounce: false
}
},
interactivity: {
detect_on: 'canvas',
events: {
onhover: { enable: true, mode: 'grab' },
onclick: { enable: true, mode: 'push' },
resize: true
},
modes: {
grab: { distance: 150, line_linked: { opacity: 0.26 } },
push: { particles_nb: 3 }
}
},
retina_detect: true
});
});
}
function makeSearchInteractive() {
var slot = document.querySelector('[data-bc-search]');
if (!slot) {
return;
}
var input = document.createElement('input');
input.className = 'bc-search-input';
input.type = 'search';
input.autocomplete = 'off';
input.placeholder = window.innerWidth < 560 ? 'страна, сервис или мера...' : slot.textContent.trim();
input.setAttribute('aria-label', 'Поиск по BRICSCompass');
slot.replaceChildren(input);
slot.classList.add('is-live');
var cards = Array.prototype.slice.call(document.querySelectorAll('.bc-card, .bc-country'));
var tags = Array.prototype.slice.call(document.querySelectorAll('[data-bc-query]'));
function filter(value) {
var query = value.trim().toLowerCase();
cards.forEach(function (card) {
var text = card.textContent.toLowerCase();
var match = !query || text.indexOf(query) !== -1;
card.classList.toggle('is-match', !!query && match);
card.classList.toggle('is-dim', !!query && !match);
});
tags.forEach(function (tag) {
tag.classList.toggle('is-active', query && tag.getAttribute('data-bc-query').toLowerCase() === query);
});
}
input.addEventListener('input', function () {
filter(input.value);
});
tags.forEach(function (tag) {
tag.addEventListener('click', function () {
input.value = tag.getAttribute('data-bc-query') || '';
filter(input.value);
input.focus();
});
});
}
function animateStats() {
var stats = Array.prototype.slice.call(document.querySelectorAll('.bc-stat-value'));
if (!stats.length || !('IntersectionObserver' in window)) {
return;
}
var observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (!entry.isIntersecting) {
return;
}
var node = entry.target;
var target = parseInt(node.textContent.replace(/\D/g, ''), 10);
if (!target || node.getAttribute('data-animated')) {
return;
}
node.setAttribute('data-animated', 'true');
var start = performance.now();
var duration = 900;
function tick(now) {
var progress = Math.min((now - start) / duration, 1);
var eased = 1 - Math.pow(1 - progress, 3);
node.lastChild.nodeValue = String(Math.round(target * eased));
if (progress < 1) {
requestAnimationFrame(tick);
}
}
node.textContent = '0';
requestAnimationFrame(tick);
observer.unobserve(node);
});
}, { threshold: 0.35 });
stats.forEach(function (stat) {
observer.observe(stat);
});
}
onReady(function () {
document.documentElement.classList.add('bc-ready');
initParticles();
makeSearchInteractive();
animateStats();
});
})();