移动端Hover感知多帧预览滑块失效及代码报错问题求助
问题:基于缩略图的视频预览功能移动端失效,split函数报错
我做了一个桌面端鼠标悬停时轮播多帧图片的视频预览功能,桌面端运行正常,但移动端完全无法工作,控制台还报错。尝试修改代码适配移动端没成功,想搞清楚:
- 怎么让这个功能在移动端正常运行?
- 为什么split函数会报错?
相关代码
jQuery 函数
if (jQuery(window).width() > 470) { jQuery(document).ready(function($){ $('img').on('mouseover', function() { var self = this, i = 0, images = $(this).data('mouseover').split('||'); (function nextImage() { var next = images[i++ % images.length].split('#'); $(self).data('timeout', setTimeout(function() { self.src = next[0]; nextImage(); }, next[1] || 500)); })(); }).on('mouseout', function() { clearTimeout($(this).data('timeout')); this.src = $(this).attr('src'); }); }); } else { jQuery(document).ready(function($){ $('img').on('ontouchstart touchmove', function() { var self = this, i = 0, images = $(this).data('ontouchstart touchmove').split('||'); (function nextImage() { var next = images[i++ % images.length].split('#'); $(self).data('timeout', setTimeout(function() { self.src = next[0]; nextImage(); }, next[1] || 500)); })(); }).on('touchend', function() { clearTimeout($(this).data('timeout')); this.src = $(this).attr('src'); }); }); }
HTML
<img id="img-slider" src="image1.jpg" data-mouseover="image2.jpg||image3.jpg||image4.jpg" />
CSS
#img-slider{ height: 117px; width: 100%; object-fit: cover; opacity: 0; } #img-slider:hover{ opacity: 1; } @media only screen and (max-width: 600px) { #img-slider { height:150px; } }
问题分析与解决方案
一、split报错的直接原因
你移动端代码里有两个致命错误:
- data属性获取错误:
$(this).data('ontouchstart touchmove')完全不对,图片上的自定义属性是data-mouseover,不是事件名称。这里获取到的是undefined,调用split('||')自然会报错——这就是你看到split报错的根源。 - 事件名称错误:
on('ontouchstart touchmove')里的ontouchstart多了前缀on,正确的触摸事件名是touchstart。而且同时绑定touchmove会导致触摸过程中多次触发轮播逻辑,完全没必要。
二、移动端功能失效的其他问题
- 窗口宽度判断只执行一次:页面加载时判断一次窗口宽度,之后如果用户调整窗口大小(比如桌面端缩小到移动端尺寸),逻辑不会自动切换。
- CSS触摸状态未处理:移动端没有
hover状态,初始的opacity:0会导致图片默认不可见,触摸时也没有对应样式切换。
三、修正后的完整代码
1. jQuery 函数(优化适配逻辑)
jQuery(document).ready(function($) { // 封装轮播启动逻辑 function startSlideshow($img) { var self = $img[0], i = 0, images = $img.data('mouseover').split('||'); // 先清除已有定时器,避免重复触发 clearTimeout($img.data('timeout')); (function nextImage() { var next = images[i++ % images.length].split('#'); $img.data('timeout', setTimeout(function() { self.src = next[0]; nextImage(); }, next[1] || 500)); })(); } // 封装停止轮播逻辑 function stopSlideshow($img) { clearTimeout($img.data('timeout')); $img[0].src = $img.attr('src'); } // 统一绑定事件,浏览器自动识别支持的事件类型 $('img').on('mouseover', function() { startSlideshow($(this)); }).on('mouseout', function() { stopSlideshow($(this)); }).on('touchstart', function(e) { // 阻止默认行为避免滚动冲突 e.preventDefault(); startSlideshow($(this)); }).on('touchend touchcancel', function() { stopSlideshow($(this)); }); // 窗口 resize 时自动适配(可选,增强鲁棒性) $(window).on('resize', function() { // 若需根据窗口尺寸调整行为可在此添加逻辑 }); });
2. CSS(修复移动端可见性问题)
#img-slider{ height: 117px; width: 100%; object-fit: cover; /* 初始opacity改为1,避免移动端默认不可见 */ opacity: 1; } /* 桌面端单独保留hover效果 */ @media only screen and (min-width: 471px) { #img-slider{ opacity: 0; } #img-slider:hover{ opacity: 1; } } @media only screen and (max-width: 600px) { #img-slider { height:150px; } }
3. HTML(无需修改)
<img id="img-slider" src="image1.jpg" data-mouseover="image2.jpg||image3.jpg||image4.jpg" />
四、关键优化点说明
- 逻辑封装复用:把启动/停止轮播的代码抽成函数,避免桌面端和移动端重复编写相同逻辑。
- 事件自动适配:同时绑定鼠标事件和触摸事件,不需要通过窗口宽度判断分开绑定,浏览器会自动识别支持的事件类型。
- 修复数据获取:移动端同样使用
data('mouseover')获取图片列表,彻底解决split报错问题。 - CSS分端适配:通过媒体查询区分桌面端和移动端的opacity逻辑,避免移动端图片默认不可见。
- 触摸防冲突:
touchstart时阻止默认行为,避免触摸轮播时页面滚动干扰。
内容的提问来源于stack exchange,提问作者OKASH
相关产品推荐
相关产品推荐

