feat(video-page): add video player page with details and comments

Add new video player page with responsive layout, video details display, and comments section. Includes video player, channel info, like/dislike buttons, and interactive elements. Also add null checks in main script to prevent errors when elements are missing.
This commit is contained in:
2026-02-11 21:46:48 +08:00
parent 7fb4ad915b
commit f6a861977c
5 changed files with 1151 additions and 48 deletions

View File

@@ -487,8 +487,13 @@ const subscriptionsList = document.querySelector('.subscriptions-list');
async function init() {
await loadVideos();
renderVideos();
renderSubscriptions();
// 只有在存在相应元素时才执行
if (videoGrid && shortsGrid) {
renderVideos();
}
if (subscriptionsList) {
renderSubscriptions();
}
bindEvents();
}
@@ -741,65 +746,83 @@ function bindEvents() { // Bind events to the DOM elements
const menuBtn = document.querySelector('.menu-btn');
const sidebar = document.querySelector('.sidebar');
menuBtn.addEventListener('click', () => {
sidebar.classList.toggle('collapsed');
});
if (menuBtn && sidebar) {
menuBtn.addEventListener('click', () => {
sidebar.classList.toggle('collapsed');
});
}
// Search event
searchInput.addEventListener('input', (e) => {
performSearch(e.target.value);
});
if (searchInput) {
searchInput.addEventListener('input', (e) => {
performSearch(e.target.value);
});
}
searchBtn.addEventListener('click', () => {
performSearch(searchInput.value);
});
if (searchBtn) {
searchBtn.addEventListener('click', () => {
performSearch(searchInput ? searchInput.value : '');
});
}
// Close the search results when clicking outside
document.addEventListener('click', (e) => {
if (!e.target.closest('.search-container') && !e.target.closest('.search-results')) {
searchResults.style.display = 'none';
}
});
if (searchResults) {
document.addEventListener('click', (e) => {
if (!e.target.closest('.search-container') && !e.target.closest('.search-results')) {
searchResults.style.display = 'none';
}
});
}
// Category buttons event
categoryBtns.forEach(btn => {
btn.addEventListener('click', () => {
// Remove all active states
categoryBtns.forEach(b => b.classList.remove('active'));
// Add current active state
btn.classList.add('active');
// Update current category
currentCategory = btn.textContent;
// Re-render videos and shorts
renderVideos();
if (categoryBtns.length > 0) {
categoryBtns.forEach(btn => {
btn.addEventListener('click', () => {
// Remove all active states
categoryBtns.forEach(b => b.classList.remove('active'));
// Add current active state
btn.classList.add('active');
// Update current category
currentCategory = btn.textContent;
// Re-render videos and shorts
if (videoGrid && shortsGrid) {
renderVideos();
}
});
});
});
}
// Sidebar navigation buttons event
const navBtns = document.querySelectorAll('.nav-btn');
navBtns.forEach(btn => {
btn.addEventListener('click', () => {
// Remove all active states
navBtns.forEach(b => b.classList.remove('active'));
// Add current active state
btn.classList.add('active');
if (navBtns.length > 0) {
navBtns.forEach(btn => {
btn.addEventListener('click', () => {
// Remove all active states
navBtns.forEach(b => b.classList.remove('active'));
// Add current active state
btn.classList.add('active');
});
});
});
}
// Subscription section expand/collapse event
const subscriptionTitle = document.querySelector('.nav-section-title');
subscriptionTitle.addEventListener('click', () => {
const subscriptionsList = document.querySelector('.subscriptions-list');
const chevron = subscriptionTitle.querySelector('i');
subscriptionsList.classList.toggle('collapsed');
if (subscriptionsList.classList.contains('collapsed')) {
chevron.style.transform = 'rotate(-90deg)';
} else {
chevron.style.transform = 'rotate(0deg)';
}
});
if (subscriptionTitle) {
subscriptionTitle.addEventListener('click', () => {
const subscriptionsList = document.querySelector('.subscriptions-list');
const chevron = subscriptionTitle.querySelector('i');
if (subscriptionsList && chevron) {
subscriptionsList.classList.toggle('collapsed');
if (subscriptionsList.classList.contains('collapsed')) {
chevron.style.transform = 'rotate(-90deg)';
} else {
chevron.style.transform = 'rotate(0deg)';
}
}
});
}
}
// Page load event: initialize the application