将onmouseover/onmouseout事件替换为触摸事件的技术求助
相册封面切换:统一适配鼠标与触摸事件的方案
核心思路
利用事件委托将监听器绑定到父容器,复用同一个切换逻辑函数,同时处理桌面端鼠标事件和移动端触摸事件,避免为每个.column单独绑定事件,解决移动端交互无效的问题。
1. 定义通用切换函数
先写一个可复用的核心函数,根据传入的状态(激活/取消)切换对应相册的封面图。建议用HTML data-* 属性存储原始封面和hover插画的地址,让每个相册独立配置,无需硬编码到JS中。
// 切换封面的核心逻辑 function toggleAlbumCover(columnElement, isActive) { const coverImg = columnElement.querySelector('img'); if (!coverImg) return; // 根据状态切换图片地址,读取data属性里的配置 coverImg.src = isActive ? coverImg.dataset.hover : coverImg.dataset.original; }
2. 绑定事件到父容器
找到所有.column的父容器(比如给它加个类album-nav-container),通过事件委托监听鼠标和触摸事件,利用事件冒泡找到触发事件的.column元素,调用切换函数。
const albumNav = document.querySelector('.album-nav-container'); // 桌面端鼠标事件 albumNav.addEventListener('mouseover', (e) => { const targetColumn = e.target.closest('.column'); if (targetColumn) toggleAlbumCover(targetColumn, true); }); albumNav.addEventListener('mouseout', (e) => { const targetColumn = e.target.closest('.column'); if (targetColumn) toggleAlbumCover(targetColumn, false); }); // 移动端触摸事件 albumNav.addEventListener('touchstart', (e) => { // 阻止默认行为,避免触发鼠标事件和页面滚动冲突 e.preventDefault(); const targetColumn = e.target.closest('.column'); if (targetColumn) toggleAlbumCover(targetColumn, true); }); albumNav.addEventListener('touchend', (e) => { e.preventDefault(); const targetColumn = e.target.closest('.column'); if (targetColumn) toggleAlbumCover(targetColumn, false); }); // 处理手指滑过多个相册的情况 albumNav.addEventListener('touchmove', (e) => { const touchPoint = e.touches[0]; // 获取当前触摸位置下的元素 const currentElement = document.elementFromPoint(touchPoint.clientX, touchPoint.clientY); const targetColumn = currentElement?.closest('.column'); // 先重置所有相册的封面 document.querySelectorAll('.column img').forEach(img => { img.src = img.dataset.original; }); // 如果当前触摸到某个相册,切换到它的插画 if (targetColumn) toggleAlbumCover(targetColumn, true); });
3. 调整HTML结构
给每个相册的<img>标签加上data-original(原始封面地址)和data-hover(hover插画地址)属性:
<div class="album-nav-container"> <div class="column"> <img src="album-1-cover.jpg" data-original="album-1-cover.jpg" data-hover="album-1-illustration.jpg" alt="相册1" > <!-- 相册标题等其他内容 --> </div> <div class="column"> <img src="album-2-cover.jpg" data-original="album-2-cover.jpg" data-hover="album-2-illustration.jpg" alt="相册2" > </div> <!-- 更多相册... --> </div>
关键细节说明
- 使用
closest('.column'):不管用户触摸/鼠标悬停的是.column内的图片、标题还是其他子元素,都能准确找到对应的相册容器,避免事件绑定遗漏。 - 触摸事件中
e.preventDefault():防止移动端默认的触摸行为(如页面滚动、双击缩放),同时避免触摸事件触发鼠标事件导致重复切换。 touchmove处理:解决手指在相册间滑动时,只有当前触摸的相册显示插画,其他自动恢复的问题,提升移动端交互体验。
内容的提问来源于stack exchange,提问作者konne
相关产品推荐
相关产品推荐

