MediaWiki:Common.js: Unterschied zwischen den Versionen
Aus Lost Dreams Of Tomorrow Wiki
Die Seite wurde geleert. Markierung: Geleert |
Keine Bearbeitungszusammenfassung |
||
| (16 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
// MediaWiki Sidebar Toggle Script - FINALE VERSION | |||
/*------------------------Sidebar Toggle Script ------------------------------------------*/ | |||
(function() { | |||
'use strict'; | |||
var processing = false; // Debounce | |||
function initSidebar() { | |||
var portlets = document.querySelectorAll('#p-Players, #p-World, #p-Items_and_Gear, #p-Guides, #p-Community'); | |||
console.log('Gefundene Portlets:', portlets.length); | |||
portlets.forEach(function(portlet) { | |||
var header = portlet.querySelector('h3'); | |||
var portletBody = portlet.querySelector('.mw-portlet-body'); | |||
if (!header || !portletBody) { | |||
return; | |||
} | |||
// Bereits initialisiert? Skip! | |||
if (header.hasAttribute('data-toggle-ready')) { | |||
return; | |||
} | |||
console.log('Initialisiere:', header.textContent); | |||
header.setAttribute('data-toggle-ready', 'true'); | |||
// Icon hinzufügen | |||
if (!header.querySelector('.toggle-icon')) { | |||
var icon = document.createElement('span'); | |||
icon.className = 'toggle-icon'; | |||
icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>'; | |||
icon.style.marginLeft = '8px'; | |||
icon.style.display = 'inline-block'; | |||
icon.style.transition = 'transform 0.2s ease'; | |||
icon.style.verticalAlign = 'middle'; | |||
header.appendChild(icon); | |||
} | |||
header.style.cursor = 'pointer'; | |||
header.style.userSelect = 'none'; | |||
// Initial Status | |||
var isOpen = !header.classList.contains('closed'); | |||
if (!isOpen) { | |||
portletBody.style.display = 'none'; | |||
var icon = header.querySelector('.toggle-icon'); | |||
icon.style.transform = 'rotate(-90deg)'; | |||
} | |||
// Toggle Funktion mit Debounce | |||
var toggleMenu = function(e) { | |||
e.preventDefault(); | |||
e.stopPropagation(); | |||
e.stopImmediatePropagation(); // WICHTIG! | |||
// Debounce - verhindert Doppel-Klicks | |||
if (processing) { | |||
return; | |||
} | |||
processing = true; | |||
setTimeout(function() { | |||
processing = false; | |||
}, 300); | |||
var icon = header.querySelector('.toggle-icon'); | |||
var body = portlet.querySelector('.mw-portlet-body'); | |||
if (body.style.display === 'none') { | |||
body.style.display = 'block'; | |||
icon.style.transform = 'rotate(0deg)'; | |||
header.classList.add('open'); | |||
header.classList.remove('closed'); | |||
console.log('Geöffnet'); | |||
} else { | |||
body.style.display = 'none'; | |||
icon.style.transform = 'rotate(-90deg)'; | |||
header.classList.add('closed'); | |||
header.classList.remove('open'); | |||
console.log('Geschlossen'); | |||
} | |||
}; | |||
// NUR Click-Event (funktioniert auch auf Mobile) | |||
header.addEventListener('click', toggleMenu, true); | |||
}); | |||
} | |||
if (document.readyState === 'loading') { | |||
document.addEventListener('DOMContentLoaded', initSidebar); | |||
} else { | |||
initSidebar(); | |||
} | |||
})(); | |||
/*------------------------Landing Features------------------------------------------*/ | |||
(function() { | |||
'use strict'; | |||
function initLandingTabs() { | |||
const containers = document.querySelectorAll('.landing-tabs'); | |||
containers.forEach(tabsContainer => { | |||
const wrapper = tabsContainer.closest('.landing-tabs-wrapper'); | |||
if (!wrapper) return; | |||
const tabs = tabsContainer.querySelectorAll('.tab-button'); | |||
const grids = wrapper.parentElement.querySelectorAll('.landing-grid'); | |||
if (tabs.length === 0 || grids.length === 0) return; | |||
// Pfeile hinzufügen | |||
let leftArrow = wrapper.querySelector('.tab-arrow-left'); | |||
let rightArrow = wrapper.querySelector('.tab-arrow-right'); | |||
if (!leftArrow) { | |||
leftArrow = document.createElement('div'); | |||
leftArrow.className = 'tab-arrow tab-arrow-left'; | |||
leftArrow.innerHTML = '‹'; | |||
wrapper.insertBefore(leftArrow, tabsContainer); | |||
} | |||
if (!rightArrow) { | |||
rightArrow = document.createElement('div'); | |||
rightArrow.className = 'tab-arrow tab-arrow-right'; | |||
rightArrow.innerHTML = '›'; | |||
wrapper.appendChild(rightArrow); | |||
} | |||
// Prüfe ob Scrollen nötig ist | |||
function updateArrows() { | |||
const isScrollable = tabsContainer.scrollWidth > tabsContainer.clientWidth; | |||
const scrollLeft = tabsContainer.scrollLeft; | |||
const maxScroll = tabsContainer.scrollWidth - tabsContainer.clientWidth; | |||
if (isScrollable) { | |||
// Linker Pfeil | |||
if (scrollLeft <= 5) { | |||
leftArrow.classList.remove('visible'); | |||
} else { | |||
leftArrow.classList.add('visible'); | |||
leftArrow.classList.remove('disabled'); | |||
} | |||
// Rechter Pfeil | |||
if (scrollLeft >= maxScroll - 5) { | |||
rightArrow.classList.remove('visible'); | |||
} else { | |||
rightArrow.classList.add('visible'); | |||
rightArrow.classList.remove('disabled'); | |||
} | |||
} else { | |||
leftArrow.classList.remove('visible'); | |||
rightArrow.classList.remove('visible'); | |||
} | |||
} | |||
// Scroll-Funktion | |||
leftArrow.addEventListener('click', () => { | |||
tabsContainer.scrollBy({ left: -200, behavior: 'smooth' }); | |||
}); | |||
rightArrow.addEventListener('click', () => { | |||
tabsContainer.scrollBy({ left: 200, behavior: 'smooth' }); | |||
}); | |||
tabsContainer.addEventListener('scroll', updateArrows); | |||
window.addEventListener('resize', updateArrows); | |||
// Tab-Klick-Handler | |||
tabs.forEach(tab => { | |||
if (tab.hasAttribute('data-tab-ready')) return; | |||
tab.setAttribute('data-tab-ready', 'true'); | |||
tab.addEventListener('click', function() { | |||
tabs.forEach(t => t.classList.remove('active')); | |||
this.classList.add('active'); | |||
grids.forEach(g => g.classList.remove('active')); | |||
const targetGrid = document.getElementById(this.dataset.tab); | |||
if (targetGrid) { | |||
targetGrid.classList.add('active'); | |||
} | |||
}); | |||
}); | |||
// Initial update | |||
updateArrows(); | |||
setTimeout(updateArrows, 100); | |||
}); | |||
} | |||
if (document.readyState === 'loading') { | |||
document.addEventListener('DOMContentLoaded', initLandingTabs); | |||
} else { | |||
initLandingTabs(); | |||
} | |||
setTimeout(initLandingTabs, 500); | |||
})(); | |||
// jQuery ONLY für ANDERE sidebar-collapsible (NICHT deine Portlets!) | |||
if (typeof jQuery !== 'undefined') { | |||
$(document).ready(function() { | |||
// NUR für Elemente die NICHT #p-Players, #p-World, etc. sind | |||
$('.sidebar-collapsible').not('#p-Players h3, #p-World h3, #p-Items_and_Gear h3, #p-Guides h3, #p-Community h3').click(function(e) { | |||
e.preventDefault(); | |||
$(this).toggleClass('closed'); | |||
$(this).next('.mw-portlet-body, ul').slideToggle(200); | |||
}); | |||
if (window.innerWidth <= 850) { | |||
$('#mw-sidebar-checkbox:checked ~ .mw-sidebar').on('click', function(e) { | |||
if (e.target === this) { | |||
$('#mw-sidebar-checkbox').prop('checked', false); | |||
} | |||
}); | |||
} | |||
}); | |||
} | |||
/*------------------------ World Carousel Drag & Drop Script ------------------------*/ | |||
(function() { | |||
'use strict'; | |||
function initWorldCarousel() { | |||
const tracks = document.querySelectorAll('.carousel-track'); | |||
if (tracks.length === 0) { | |||
return; | |||
} | |||
tracks.forEach(function(track) { | |||
if (track.hasAttribute('data-carousel-ready')) { | |||
return; | |||
} | |||
track.setAttribute('data-carousel-ready', 'true'); | |||
let isDown = false; | |||
let startX; | |||
let scrollLeft; | |||
track.addEventListener('mousedown', function(e) { | |||
isDown = true; | |||
track.style.cursor = 'grabbing'; | |||
startX = e.pageX - track.offsetLeft; | |||
scrollLeft = track.scrollLeft; | |||
}); | |||
track.addEventListener('mouseleave', function() { | |||
isDown = false; | |||
track.style.cursor = 'grab'; | |||
}); | |||
track.addEventListener('mouseup', function() { | |||
isDown = false; | |||
track.style.cursor = 'grab'; | |||
}); | |||
track.addEventListener('mousemove', function(e) { | |||
if (!isDown) return; | |||
e.preventDefault(); | |||
const x = e.pageX - track.offsetLeft; | |||
const walk = (x - startX) * 2; | |||
track.scrollLeft = scrollLeft - walk; | |||
}); | |||
// Touch Support | |||
let touchStartX = 0; | |||
let touchScrollLeft = 0; | |||
track.addEventListener('touchstart', function(e) { | |||
touchStartX = e.touches[0].pageX; | |||
touchScrollLeft = track.scrollLeft; | |||
}, {passive: true}); | |||
track.addEventListener('touchmove', function(e) { | |||
const x = e.touches[0].pageX; | |||
const walk = (touchStartX - x) * 1.5; | |||
track.scrollLeft = touchScrollLeft + walk; | |||
}, {passive: true}); | |||
}); | |||
} | |||
if (document.readyState === 'loading') { | |||
document.addEventListener('DOMContentLoaded', initWorldCarousel); | |||
} else { | |||
initWorldCarousel(); | |||
} | |||
setTimeout(initWorldCarousel, 500); | |||
})(); | |||
Aktuelle Version vom 12. Januar 2026, 02:29 Uhr
// MediaWiki Sidebar Toggle Script - FINALE VERSION
/*------------------------Sidebar Toggle Script ------------------------------------------*/
(function() {
'use strict';
var processing = false; // Debounce
function initSidebar() {
var portlets = document.querySelectorAll('#p-Players, #p-World, #p-Items_and_Gear, #p-Guides, #p-Community');
console.log('Gefundene Portlets:', portlets.length);
portlets.forEach(function(portlet) {
var header = portlet.querySelector('h3');
var portletBody = portlet.querySelector('.mw-portlet-body');
if (!header || !portletBody) {
return;
}
// Bereits initialisiert? Skip!
if (header.hasAttribute('data-toggle-ready')) {
return;
}
console.log('Initialisiere:', header.textContent);
header.setAttribute('data-toggle-ready', 'true');
// Icon hinzufügen
if (!header.querySelector('.toggle-icon')) {
var icon = document.createElement('span');
icon.className = 'toggle-icon';
icon.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>';
icon.style.marginLeft = '8px';
icon.style.display = 'inline-block';
icon.style.transition = 'transform 0.2s ease';
icon.style.verticalAlign = 'middle';
header.appendChild(icon);
}
header.style.cursor = 'pointer';
header.style.userSelect = 'none';
// Initial Status
var isOpen = !header.classList.contains('closed');
if (!isOpen) {
portletBody.style.display = 'none';
var icon = header.querySelector('.toggle-icon');
icon.style.transform = 'rotate(-90deg)';
}
// Toggle Funktion mit Debounce
var toggleMenu = function(e) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation(); // WICHTIG!
// Debounce - verhindert Doppel-Klicks
if (processing) {
return;
}
processing = true;
setTimeout(function() {
processing = false;
}, 300);
var icon = header.querySelector('.toggle-icon');
var body = portlet.querySelector('.mw-portlet-body');
if (body.style.display === 'none') {
body.style.display = 'block';
icon.style.transform = 'rotate(0deg)';
header.classList.add('open');
header.classList.remove('closed');
console.log('Geöffnet');
} else {
body.style.display = 'none';
icon.style.transform = 'rotate(-90deg)';
header.classList.add('closed');
header.classList.remove('open');
console.log('Geschlossen');
}
};
// NUR Click-Event (funktioniert auch auf Mobile)
header.addEventListener('click', toggleMenu, true);
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initSidebar);
} else {
initSidebar();
}
})();
/*------------------------Landing Features------------------------------------------*/
(function() {
'use strict';
function initLandingTabs() {
const containers = document.querySelectorAll('.landing-tabs');
containers.forEach(tabsContainer => {
const wrapper = tabsContainer.closest('.landing-tabs-wrapper');
if (!wrapper) return;
const tabs = tabsContainer.querySelectorAll('.tab-button');
const grids = wrapper.parentElement.querySelectorAll('.landing-grid');
if (tabs.length === 0 || grids.length === 0) return;
// Pfeile hinzufügen
let leftArrow = wrapper.querySelector('.tab-arrow-left');
let rightArrow = wrapper.querySelector('.tab-arrow-right');
if (!leftArrow) {
leftArrow = document.createElement('div');
leftArrow.className = 'tab-arrow tab-arrow-left';
leftArrow.innerHTML = '‹';
wrapper.insertBefore(leftArrow, tabsContainer);
}
if (!rightArrow) {
rightArrow = document.createElement('div');
rightArrow.className = 'tab-arrow tab-arrow-right';
rightArrow.innerHTML = '›';
wrapper.appendChild(rightArrow);
}
// Prüfe ob Scrollen nötig ist
function updateArrows() {
const isScrollable = tabsContainer.scrollWidth > tabsContainer.clientWidth;
const scrollLeft = tabsContainer.scrollLeft;
const maxScroll = tabsContainer.scrollWidth - tabsContainer.clientWidth;
if (isScrollable) {
// Linker Pfeil
if (scrollLeft <= 5) {
leftArrow.classList.remove('visible');
} else {
leftArrow.classList.add('visible');
leftArrow.classList.remove('disabled');
}
// Rechter Pfeil
if (scrollLeft >= maxScroll - 5) {
rightArrow.classList.remove('visible');
} else {
rightArrow.classList.add('visible');
rightArrow.classList.remove('disabled');
}
} else {
leftArrow.classList.remove('visible');
rightArrow.classList.remove('visible');
}
}
// Scroll-Funktion
leftArrow.addEventListener('click', () => {
tabsContainer.scrollBy({ left: -200, behavior: 'smooth' });
});
rightArrow.addEventListener('click', () => {
tabsContainer.scrollBy({ left: 200, behavior: 'smooth' });
});
tabsContainer.addEventListener('scroll', updateArrows);
window.addEventListener('resize', updateArrows);
// Tab-Klick-Handler
tabs.forEach(tab => {
if (tab.hasAttribute('data-tab-ready')) return;
tab.setAttribute('data-tab-ready', 'true');
tab.addEventListener('click', function() {
tabs.forEach(t => t.classList.remove('active'));
this.classList.add('active');
grids.forEach(g => g.classList.remove('active'));
const targetGrid = document.getElementById(this.dataset.tab);
if (targetGrid) {
targetGrid.classList.add('active');
}
});
});
// Initial update
updateArrows();
setTimeout(updateArrows, 100);
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initLandingTabs);
} else {
initLandingTabs();
}
setTimeout(initLandingTabs, 500);
})();
// jQuery ONLY für ANDERE sidebar-collapsible (NICHT deine Portlets!)
if (typeof jQuery !== 'undefined') {
$(document).ready(function() {
// NUR für Elemente die NICHT #p-Players, #p-World, etc. sind
$('.sidebar-collapsible').not('#p-Players h3, #p-World h3, #p-Items_and_Gear h3, #p-Guides h3, #p-Community h3').click(function(e) {
e.preventDefault();
$(this).toggleClass('closed');
$(this).next('.mw-portlet-body, ul').slideToggle(200);
});
if (window.innerWidth <= 850) {
$('#mw-sidebar-checkbox:checked ~ .mw-sidebar').on('click', function(e) {
if (e.target === this) {
$('#mw-sidebar-checkbox').prop('checked', false);
}
});
}
});
}
/*------------------------ World Carousel Drag & Drop Script ------------------------*/
(function() {
'use strict';
function initWorldCarousel() {
const tracks = document.querySelectorAll('.carousel-track');
if (tracks.length === 0) {
return;
}
tracks.forEach(function(track) {
if (track.hasAttribute('data-carousel-ready')) {
return;
}
track.setAttribute('data-carousel-ready', 'true');
let isDown = false;
let startX;
let scrollLeft;
track.addEventListener('mousedown', function(e) {
isDown = true;
track.style.cursor = 'grabbing';
startX = e.pageX - track.offsetLeft;
scrollLeft = track.scrollLeft;
});
track.addEventListener('mouseleave', function() {
isDown = false;
track.style.cursor = 'grab';
});
track.addEventListener('mouseup', function() {
isDown = false;
track.style.cursor = 'grab';
});
track.addEventListener('mousemove', function(e) {
if (!isDown) return;
e.preventDefault();
const x = e.pageX - track.offsetLeft;
const walk = (x - startX) * 2;
track.scrollLeft = scrollLeft - walk;
});
// Touch Support
let touchStartX = 0;
let touchScrollLeft = 0;
track.addEventListener('touchstart', function(e) {
touchStartX = e.touches[0].pageX;
touchScrollLeft = track.scrollLeft;
}, {passive: true});
track.addEventListener('touchmove', function(e) {
const x = e.touches[0].pageX;
const walk = (touchStartX - x) * 1.5;
track.scrollLeft = touchScrollLeft + walk;
}, {passive: true});
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initWorldCarousel);
} else {
initWorldCarousel();
}
setTimeout(initWorldCarousel, 500);
})();