smoother touch functionality

This commit is contained in:
Yeghro
2025-01-25 12:18:20 -08:00
parent 82c34be52b
commit 0c53715218

157
script.js
View File

@@ -209,85 +209,126 @@ document.addEventListener('DOMContentLoaded', () => {
</div>`; </div>`;
}); });
// Enhanced touch handling for sidebar // Ensure we're working with valid elements
touchStartX = 0; if (!sidebar || !menuToggle) {
touchStartY = 0; console.error('Required elements not found');
touchEndX = 0; return;
touchEndY = 0; }
isSwiping = false;
// Track touch movements // Single function to handle sidebar state
document.addEventListener('touchstart', (e) => { const toggleSidebar = (show) => {
if (show === undefined) {
sidebar.classList.toggle('active');
} else {
sidebar.classList[show ? 'add' : 'remove']('active');
}
// Update aria-expanded state
menuToggle.setAttribute('aria-expanded', sidebar.classList.contains('active'));
};
// Menu toggle click handler
menuToggle.addEventListener('click', (e) => {
e.stopPropagation();
toggleSidebar();
});
// Delegate sidebar link clicks using event delegation
document.querySelector('.nav-links').addEventListener('click', (e) => {
const link = e.target.closest('a');
if (!link) return;
e.preventDefault();
// Remove active class from all links
document.querySelectorAll('.nav-links a').forEach(l =>
l.classList.remove('active')
);
// Add active class to clicked link
link.classList.add('active');
// Get section name and display it
const section = link.getAttribute('data-section');
displaySection(section, window.parsedResources);
// Close sidebar on mobile
if (window.innerWidth <= 768) {
toggleSidebar(false);
}
});
// Touch handling
let touchStartX = 0;
let touchStartY = 0;
let touchEndX = 0;
let touchEndY = 0;
let isSwiping = false;
const handleTouchStart = (e) => {
touchStartX = e.touches[0].clientX; touchStartX = e.touches[0].clientX;
touchStartY = e.touches[0].clientY; touchStartY = e.touches[0].clientY;
isSwiping = true; isSwiping = true;
}, { passive: true }); };
document.addEventListener('touchmove', (e) => { const handleTouchMove = (e) => {
if (!isSwiping) return; if (!isSwiping) return;
touchEndX = e.touches[0].clientX; touchEndX = e.touches[0].clientX;
touchEndY = e.touches[0].clientY; touchEndY = e.touches[0].clientY;
// Calculate vertical and horizontal distance
const deltaX = touchStartX - touchEndX; const deltaX = touchStartX - touchEndX;
const deltaY = Math.abs(touchStartY - touchEndY); const deltaY = Math.abs(touchStartY - touchEndY);
// If vertical scrolling is more prominent, don't handle swipe
if (deltaY > Math.abs(deltaX)) { if (deltaY > Math.abs(deltaX)) {
isSwiping = false; isSwiping = false;
return; return;
} }
// Prevent default only if horizontal swipe is significant
if (Math.abs(deltaX) > 10) { if (Math.abs(deltaX) > 10) {
e.preventDefault(); e.preventDefault();
} }
}, { passive: false }); };
document.addEventListener('touchend', () => { const handleTouchEnd = () => {
if (!isSwiping) return; if (!isSwiping) return;
const deltaX = touchStartX - touchEndX; const deltaX = touchStartX - touchEndX;
const deltaY = Math.abs(touchStartY - touchEndY); const deltaY = Math.abs(touchStartY - touchEndY);
const swipeThreshold = 50; const swipeThreshold = 50;
// Only handle horizontal swipes
if (Math.abs(deltaX) > swipeThreshold && deltaY < 100) { if (Math.abs(deltaX) > swipeThreshold && deltaY < 100) {
if (deltaX > 0) { toggleSidebar(deltaX < 0);
// Swipe left - close sidebar
sidebar.classList.remove('active');
} else {
// Swipe right - open sidebar
sidebar.classList.add('active');
}
} }
isSwiping = false; isSwiping = false;
}, { passive: true }); };
// Update sidebar link click handling // Add touch event listeners
document.querySelectorAll('.nav-links a').forEach(link => { document.addEventListener('touchstart', handleTouchStart, { passive: true });
link.addEventListener('click', (e) => { document.addEventListener('touchmove', handleTouchMove, { passive: false });
e.preventDefault(); document.addEventListener('touchend', handleTouchEnd, { passive: true });
// Remove active class from all links // Close sidebar when clicking outside
document.querySelectorAll('.nav-links a').forEach(l => document.addEventListener('click', (e) => {
l.classList.remove('active') if (window.innerWidth <= 768 &&
); !sidebar.contains(e.target) &&
!menuToggle.contains(e.target) &&
// Add active class to clicked link sidebar.classList.contains('active')) {
link.classList.add('active'); toggleSidebar(false);
}
// Get section name and display it });
const section = link.getAttribute('data-section');
displaySection(section, window.parsedResources); // Handle window resize
let resizeTimer;
// Close sidebar on mobile window.addEventListener('resize', () => {
if (window.innerWidth <= 768) { clearTimeout(resizeTimer);
sidebar.classList.remove('active'); resizeTimer = setTimeout(() => {
if (window.innerWidth > 768) {
toggleSidebar(true);
} else {
toggleSidebar(false);
} }
}); }, 250);
}); });
}); });
@@ -870,28 +911,4 @@ function applyColorTheme(themeName) {
const cssVar = `--${key.replace(/([A-Z])/g, '-$1').toLowerCase()}`; const cssVar = `--${key.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
root.style.setProperty(cssVar, value); root.style.setProperty(cssVar, value);
}); });
} }
// Mobile menu toggle functionality
menuToggle.addEventListener('click', () => {
sidebar.classList.toggle('active');
});
// Optional: Close sidebar when clicking outside
document.addEventListener('click', (e) => {
if (window.innerWidth <= 768) { // Only on mobile
const isClickInsideSidebar = sidebar.contains(e.target);
const isClickOnMenuToggle = menuToggle.contains(e.target);
if (!isClickInsideSidebar && !isClickOnMenuToggle && sidebar.classList.contains('active')) {
sidebar.classList.remove('active');
}
}
});
// Optional: Close sidebar when pressing Escape key
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && sidebar.classList.contains('active')) {
sidebar.classList.remove('active');
}
});