mirror of
https://github.com/aljazceru/awesome-nostr.git
synced 2025-12-10 14:48:49 +00:00
smoother touch functionality
This commit is contained in:
157
script.js
157
script.js
@@ -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');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user