如何制作具备悬停预览与点击固定功能的Genre下拉菜单?
Alright, let's tackle this Genre dropdown with your specific interaction requirements and integrate it with your existing search functionality. Here's a step-by-step implementation that covers all your needs:
HTML Structure
First, we'll build the core dropdown markup alongside your existing search area and movie display container:
<!-- Place this next to your search input --> <div class="genre-dropdown"> <button class="genre-btn">Genre <span class="dropdown-arrow">▼</span></button> <div class="genre-menu"> <div class="genre-option" data-genre="adventure">冒险</div> <div class="genre-option" data-genre="horror">恐怖</div> <div class="genre-option" data-genre="action">动作</div> <div class="genre-option" data-genre="comedy">喜剧</div> <!-- Add more genres as needed --> </div> </div> <!-- Your existing search input (adjust ID to match your actual code) --> <input type="text" id="movie-search" placeholder="搜索影片标题..."> <!-- Movie display container --> <div class="movies-grid"></div>
CSS Styling
This handles the dropdown visibility, hover states, and selected styling:
.genre-dropdown { position: relative; display: inline-block; margin-right: 1rem; } .genre-btn { padding: 0.5rem 1rem; border: 1px solid #e0e0e0; border-radius: 4px; background: #ffffff; cursor: pointer; display: flex; align-items: center; gap: 0.5rem; } .genre-menu { position: absolute; top: 100%; left: 0; width: 160px; margin-top: 0.25rem; border: 1px solid #e0e0e0; border-top: none; border-radius: 0 0 4px 4px; background: #ffffff; display: none; z-index: 100; } .genre-menu.active { display: block; } .genre-option { padding: 0.5rem 1rem; cursor: pointer; transition: background-color 0.2s; } .genre-option:hover { background-color: #f5f5f5; } .genre-option.selected { background-color: #e8f0fe; font-weight: 600; } /* Basic movie grid styling (adjust to your design) */ .movies-grid { margin-top: 1rem; display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; } .movie-card { padding: 1rem; border: 1px solid #e0e0e0; border-radius: 4px; }
JavaScript Logic
This implements all the required interactions and ties everything together with your search feature:
// Get DOM elements const genreBtn = document.querySelector('.genre-btn'); const genreMenu = document.querySelector('.genre-menu'); const genreOptions = document.querySelectorAll('.genre-option'); const searchInput = document.getElementById('movie-search'); const moviesGrid = document.querySelector('.movies-grid'); // Sample movie data (replace with your actual data source) const movieDatabase = [ { title: '夺宝奇兵:命运转盘', genre: 'adventure' }, { title: '闪灵', genre: 'horror' }, { title: '速度与激情10', genre: 'action' }, { title: '失控玩家', genre: 'comedy' }, { title: '侏罗纪世界3', genre: 'adventure' }, { title: '招魂3', genre: 'horror' } ]; // Toggle dropdown on button click genreBtn.addEventListener('click', () => { genreMenu.classList.toggle('active'); }); // Close dropdown when clicking outside document.addEventListener('click', (e) => { if (!genreBtn.contains(e.target) && !genreMenu.contains(e.target)) { genreMenu.classList.remove('active'); } }); // Handle genre option interactions genreOptions.forEach(option => { // Show movies on hover option.addEventListener('mouseenter', () => { const targetGenre = option.dataset.genre; renderMovies(filterMoviesByGenre(targetGenre)); }); // Fix selected genre on click option.addEventListener('click', () => { // Clear previous selected state genreOptions.forEach(opt => opt.classList.remove('selected')); // Mark current option as selected option.classList.add('selected'); // Render movies for selected genre const targetGenre = option.dataset.genre; renderMovies(filterMoviesByGenre(targetGenre)); // Close dropdown after selection genreMenu.classList.remove('active'); }); }); // Integrate with search functionality searchInput.addEventListener('input', () => { const searchTerm = searchInput.value.toLowerCase().trim(); const selectedGenre = document.querySelector('.genre-option.selected')?.dataset.genre; let filteredMovies = movieDatabase; // Apply genre filter if one is selected if (selectedGenre) { filteredMovies = filterMoviesByGenre(selectedGenre); } // Apply search term filter if (searchTerm) { filteredMovies = filteredMovies.filter(movie => movie.title.toLowerCase().includes(searchTerm) ); } renderMovies(filteredMovies); }); // Helper: Filter movies by genre function filterMoviesByGenre(genre) { return movieDatabase.filter(movie => movie.genre === genre); } // Helper: Render movies to the grid function renderMovies(movies) { moviesGrid.innerHTML = ''; if (movies.length === 0) { moviesGrid.innerHTML = '<p>没有找到匹配的影片</p>'; return; } movies.forEach(movie => { const card = document.createElement('div'); card.className = 'movie-card'; card.textContent = movie.title; moviesGrid.appendChild(card); }); } // Initialize with all movies (optional) renderMovies(movieDatabase);
Key Features Explained:
- Click-only dropdown: The menu only opens/closes when clicking the Genre button, no hover activation.
- Hover preview: Hovering any genre immediately shows its associated movies without selecting it.
- Persistent selection: Clicking a genre marks it as selected and locks the movie display to that genre until another is chosen.
- Search integration: The search feature now works alongside the selected genre—search results will only include movies from the active genre (if one is selected).
内容的提问来源于stack exchange,提问作者SoyBins
相关产品推荐
相关产品推荐

