MediaWiki:Common.js: Difference between revisions
From Ultimate Dragon Ball Online Wiki
Ravenalien (talk | contribs) Created page with "→Any JavaScript here will be loaded for all users on every page load.: →Tab Navigation System for UltimateDBOWiki: (function() { 'use strict'; // Initialize when document is ready $(document).ready(function() { initializeTabs(); }); function initializeTabs() { // Find all tab containers on the page $('.tab-navigation').each(function(index) { var tabContainerId = 'tab-container-' + index;..." |
Ravenalien (talk | contribs) No edit summary |
||
| Line 1: | Line 1: | ||
/* Any JavaScript here will be loaded for all users on every page load. */ | /* Any JavaScript here will be loaded for all users on every page load. */ | ||
/* Tab Navigation System | /* Tab Navigation System*/ | ||
(function() { | (function() { | ||
'use strict'; | 'use strict'; | ||
| Line 7: | Line 7: | ||
$(document).ready(function() { | $(document).ready(function() { | ||
initializeTabs(); | initializeTabs(); | ||
initializeSubTabs(); | |||
}); | }); | ||
| Line 16: | Line 17: | ||
var $container = $('#' + tabContainerId); | var $container = $('#' + tabContainerId); | ||
var $tabButtons = $container.find('.tab-button'); | var $tabButtons = $container.find('> .tab-nav > .tab-button'); | ||
var $tabPanes = $container.find('.tab-pane'); | var $tabPanes = $container.find('> .tab-content > .tab-pane'); | ||
// Add click handlers to tab buttons | // Add click handlers to tab buttons | ||
| Line 25: | Line 26: | ||
// Remove active class from all buttons and panes in this container | // Remove active class from all buttons and panes in this container | ||
$container.find('.tab-button').removeClass('active'); | $container.find('> .tab-nav > .tab-button').removeClass('active'); | ||
$container.find('.tab-pane').removeClass('active'); | $container.find('> .tab-content > .tab-pane').removeClass('active'); | ||
// Add active class to clicked button and corresponding pane | // Add active class to clicked button and corresponding pane | ||
$this.addClass('active'); | $this.addClass('active'); | ||
$container.find('#' + targetId).addClass('active'); | $container.find('#' + targetId).addClass('active'); | ||
// If this tab has a sub-tab that's active, ensure it's visible | |||
var $activeSubTab = $container.find('#' + targetId + ' .sub-tab-navigation .tab-button.active'); | |||
if ($activeSubTab.length) { | |||
$activeSubTab.trigger('click'); | |||
} | |||
}); | |||
}); | |||
} | |||
// Initialize nested sub-tabs | |||
function initializeSubTabs() { | |||
$('.sub-tab-navigation').each(function(index) { | |||
var subTabContainerId = 'sub-tab-container-' + index; | |||
$(this).attr('id', subTabContainerId); | |||
var $container = $('#' + subTabContainerId); | |||
var $tabButtons = $container.find('> .tab-nav > .tab-button'); | |||
var $tabPanes = $container.find('> .tab-content > .tab-pane'); | |||
// Add click handlers to tab buttons | |||
$tabButtons.on('click', function() { | |||
var $this = $(this); | |||
var targetId = $this.data('target'); | |||
// Remove active class from all buttons and panes in this container | |||
$container.find('> .tab-nav > .tab-button').removeClass('active'); | |||
$container.find('> .tab-content > .tab-pane').removeClass('active'); | |||
// Add active class to clicked button and corresponding pane | |||
$this.addClass('active'); | |||
$container.find('#' + targetId).addClass('active'); | |||
// Store the active tab state in session storage for persistence | |||
try { | |||
sessionStorage.setItem('activeSubTab-' + subTabContainerId, targetId); | |||
} catch (e) { | |||
console.log('Unable to save tab state to session storage'); | |||
} | |||
}); | }); | ||
// Check if there's a stored active tab | |||
try { | |||
var activeTabId = sessionStorage.getItem('activeSubTab-' + subTabContainerId); | |||
if (activeTabId) { | |||
$container.find('.tab-button[data-target="' + activeTabId + '"]').trigger('click'); | |||
} | |||
} catch (e) { | |||
console.log('Unable to retrieve tab state from session storage'); | |||
} | |||
}); | }); | ||
} | } | ||
| Line 66: | Line 116: | ||
$(this).css('box-shadow', ''); | $(this).css('box-shadow', ''); | ||
}); | }); | ||
}); | |||
})(); | |||
/* Fix TOC positioning with tabs */ | |||
(function() { | |||
'use strict'; | |||
$(document).ready(function() { | |||
// If both TOC and tab navigation exist on the page | |||
if ($('#toc').length && $('.tab-navigation').length) { | |||
// Add clearfix to TOC | |||
$('#toc').addClass('clearfix'); | |||
// Ensure TOC is above tab content in z-index | |||
$('#toc').css('position', 'relative'); | |||
$('#toc').css('z-index', '2'); | |||
} | |||
}); | |||
})(); | |||
/* Improve Mobile Experience */ | |||
(function() { | |||
'use strict'; | |||
$(document).ready(function() { | |||
// Check if we're on a mobile device | |||
var isMobile = window.matchMedia("only screen and (max-width: 768px)").matches; | |||
if (isMobile) { | |||
// Make tab navigation scrollable on mobile | |||
$('.tab-nav').css({ | |||
'overflow-x': 'auto', | |||
'white-space': 'nowrap', | |||
'-webkit-overflow-scrolling': 'touch' | |||
}); | |||
// Ensure tab buttons don't wrap | |||
$('.tab-button').css({ | |||
'display': 'inline-block', | |||
'float': 'none' | |||
}); | |||
// Add slight delay to image hover effects for better mobile experience | |||
$('.thumbimage').each(function() { | |||
var $this = $(this); | |||
$this.on('touchstart', function() { | |||
$this.css('transform', 'scale(1.05)'); | |||
$this.css('transition', 'transform 0.3s ease'); | |||
$this.css('box-shadow', '0 8px 16px rgba(0,0,0,0.2)'); | |||
setTimeout(function() { | |||
$this.css('transform', ''); | |||
$this.css('box-shadow', ''); | |||
}, 1000); | |||
}); | |||
}); | |||
} | |||
}); | |||
})(); | |||
/* Save tab state across page loads */ | |||
(function() { | |||
'use strict'; | |||
$(document).ready(function() { | |||
// Check if we should restore tab states | |||
try { | |||
var pageTabState = sessionStorage.getItem('pageTabState-' + window.location.pathname); | |||
if (pageTabState) { | |||
var tabStates = JSON.parse(pageTabState); | |||
// Restore main tab states | |||
if (tabStates.mainTabs) { | |||
$.each(tabStates.mainTabs, function(containerId, activeTabId) { | |||
$('#' + containerId + ' > .tab-nav > .tab-button[data-target="' + activeTabId + '"]').trigger('click'); | |||
}); | |||
} | |||
// Restore sub tab states | |||
if (tabStates.subTabs) { | |||
$.each(tabStates.subTabs, function(containerId, activeTabId) { | |||
$('#' + containerId + ' > .tab-nav > .tab-button[data-target="' + activeTabId + '"]').trigger('click'); | |||
}); | |||
} | |||
} | |||
} catch (e) { | |||
console.log('Error restoring tab state:', e); | |||
} | |||
// Setup save on tab change | |||
$('.tab-button').on('click', function() { | |||
saveTabStates(); | |||
}); | |||
function saveTabStates() { | |||
try { | |||
var tabStates = { | |||
mainTabs: {}, | |||
subTabs: {} | |||
}; | |||
// Save main tab states | |||
$('.tab-navigation').each(function() { | |||
var id = $(this).attr('id'); | |||
var activeTabId = $(this).find('> .tab-nav > .tab-button.active').data('target'); | |||
tabStates.mainTabs[id] = activeTabId; | |||
}); | |||
// Save sub tab states | |||
$('.sub-tab-navigation').each(function() { | |||
var id = $(this).attr('id'); | |||
var activeTabId = $(this).find('> .tab-nav > .tab-button.active').data('target'); | |||
tabStates.subTabs[id] = activeTabId; | |||
}); | |||
sessionStorage.setItem('pageTabState-' + window.location.pathname, JSON.stringify(tabStates)); | |||
} catch (e) { | |||
console.log('Error saving tab state:', e); | |||
} | |||
} | |||
}); | }); | ||
})(); | })(); | ||
Revision as of 05:57, 26 February 2025
/* Any JavaScript here will be loaded for all users on every page load. */
/* Tab Navigation System*/
(function() {
'use strict';
// Initialize when document is ready
$(document).ready(function() {
initializeTabs();
initializeSubTabs();
});
function initializeTabs() {
// Find all tab containers on the page
$('.tab-navigation').each(function(index) {
var tabContainerId = 'tab-container-' + index;
$(this).attr('id', tabContainerId);
var $container = $('#' + tabContainerId);
var $tabButtons = $container.find('> .tab-nav > .tab-button');
var $tabPanes = $container.find('> .tab-content > .tab-pane');
// Add click handlers to tab buttons
$tabButtons.on('click', function() {
var $this = $(this);
var targetId = $this.data('target');
// Remove active class from all buttons and panes in this container
$container.find('> .tab-nav > .tab-button').removeClass('active');
$container.find('> .tab-content > .tab-pane').removeClass('active');
// Add active class to clicked button and corresponding pane
$this.addClass('active');
$container.find('#' + targetId).addClass('active');
// If this tab has a sub-tab that's active, ensure it's visible
var $activeSubTab = $container.find('#' + targetId + ' .sub-tab-navigation .tab-button.active');
if ($activeSubTab.length) {
$activeSubTab.trigger('click');
}
});
});
}
// Initialize nested sub-tabs
function initializeSubTabs() {
$('.sub-tab-navigation').each(function(index) {
var subTabContainerId = 'sub-tab-container-' + index;
$(this).attr('id', subTabContainerId);
var $container = $('#' + subTabContainerId);
var $tabButtons = $container.find('> .tab-nav > .tab-button');
var $tabPanes = $container.find('> .tab-content > .tab-pane');
// Add click handlers to tab buttons
$tabButtons.on('click', function() {
var $this = $(this);
var targetId = $this.data('target');
// Remove active class from all buttons and panes in this container
$container.find('> .tab-nav > .tab-button').removeClass('active');
$container.find('> .tab-content > .tab-pane').removeClass('active');
// Add active class to clicked button and corresponding pane
$this.addClass('active');
$container.find('#' + targetId).addClass('active');
// Store the active tab state in session storage for persistence
try {
sessionStorage.setItem('activeSubTab-' + subTabContainerId, targetId);
} catch (e) {
console.log('Unable to save tab state to session storage');
}
});
// Check if there's a stored active tab
try {
var activeTabId = sessionStorage.getItem('activeSubTab-' + subTabContainerId);
if (activeTabId) {
$container.find('.tab-button[data-target="' + activeTabId + '"]').trigger('click');
}
} catch (e) {
console.log('Unable to retrieve tab state from session storage');
}
});
}
})();
/* Add Tooltip functionality for map links */
(function() {
'use strict';
$(document).ready(function() {
$('span.material-button a').each(function() {
var href = $(this).attr('href');
if (href && href.indexOf('world-map') !== -1) {
$(this).parent().attr('title', 'Click to view location on map');
// Optional: Add map icon
$(this).prepend('<span class="map-icon">🗺️ </span>');
}
});
});
})();
/* Enhanced Image Previews */
(function() {
'use strict';
$(document).ready(function() {
$('.thumbimage').on('mouseenter', function() {
$(this).css('transform', 'scale(1.05)');
$(this).css('transition', 'transform 0.3s ease');
$(this).css('box-shadow', '0 8px 16px rgba(0,0,0,0.2)');
}).on('mouseleave', function() {
$(this).css('transform', '');
$(this).css('box-shadow', '');
});
});
})();
/* Fix TOC positioning with tabs */
(function() {
'use strict';
$(document).ready(function() {
// If both TOC and tab navigation exist on the page
if ($('#toc').length && $('.tab-navigation').length) {
// Add clearfix to TOC
$('#toc').addClass('clearfix');
// Ensure TOC is above tab content in z-index
$('#toc').css('position', 'relative');
$('#toc').css('z-index', '2');
}
});
})();
/* Improve Mobile Experience */
(function() {
'use strict';
$(document).ready(function() {
// Check if we're on a mobile device
var isMobile = window.matchMedia("only screen and (max-width: 768px)").matches;
if (isMobile) {
// Make tab navigation scrollable on mobile
$('.tab-nav').css({
'overflow-x': 'auto',
'white-space': 'nowrap',
'-webkit-overflow-scrolling': 'touch'
});
// Ensure tab buttons don't wrap
$('.tab-button').css({
'display': 'inline-block',
'float': 'none'
});
// Add slight delay to image hover effects for better mobile experience
$('.thumbimage').each(function() {
var $this = $(this);
$this.on('touchstart', function() {
$this.css('transform', 'scale(1.05)');
$this.css('transition', 'transform 0.3s ease');
$this.css('box-shadow', '0 8px 16px rgba(0,0,0,0.2)');
setTimeout(function() {
$this.css('transform', '');
$this.css('box-shadow', '');
}, 1000);
});
});
}
});
})();
/* Save tab state across page loads */
(function() {
'use strict';
$(document).ready(function() {
// Check if we should restore tab states
try {
var pageTabState = sessionStorage.getItem('pageTabState-' + window.location.pathname);
if (pageTabState) {
var tabStates = JSON.parse(pageTabState);
// Restore main tab states
if (tabStates.mainTabs) {
$.each(tabStates.mainTabs, function(containerId, activeTabId) {
$('#' + containerId + ' > .tab-nav > .tab-button[data-target="' + activeTabId + '"]').trigger('click');
});
}
// Restore sub tab states
if (tabStates.subTabs) {
$.each(tabStates.subTabs, function(containerId, activeTabId) {
$('#' + containerId + ' > .tab-nav > .tab-button[data-target="' + activeTabId + '"]').trigger('click');
});
}
}
} catch (e) {
console.log('Error restoring tab state:', e);
}
// Setup save on tab change
$('.tab-button').on('click', function() {
saveTabStates();
});
function saveTabStates() {
try {
var tabStates = {
mainTabs: {},
subTabs: {}
};
// Save main tab states
$('.tab-navigation').each(function() {
var id = $(this).attr('id');
var activeTabId = $(this).find('> .tab-nav > .tab-button.active').data('target');
tabStates.mainTabs[id] = activeTabId;
});
// Save sub tab states
$('.sub-tab-navigation').each(function() {
var id = $(this).attr('id');
var activeTabId = $(this).find('> .tab-nav > .tab-button.active').data('target');
tabStates.subTabs[id] = activeTabId;
});
sessionStorage.setItem('pageTabState-' + window.location.pathname, JSON.stringify(tabStates));
} catch (e) {
console.log('Error saving tab state:', e);
}
}
});
})();