实现图片悬停500ms后触发放大、边框变色及添加tracker类
问题描述
我有一个PNG图片画廊,会根据列表(如myList)中的元素数量展示对应数量的PNG图片,本次示例用4张。需求是让用户点击选择图片前必须仔细查看每张图片:当前代码支持鼠标悬停图片时放大、边框变绿标记已查看,还加了tracker类检测是否查看过。
但核心问题是,需要强制用户必须悬停图片至少500ms后,才触发放大、边框变绿及添加tracker类的操作,避免快速滑过就完成标记的作弊行为。目前代码仅在页面加载时强制等500ms,没法对每张图片的悬停做延迟控制,猜测可以用transition-delay,但没找到正确实现方式。
原代码如下:
<html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <style media="screen"> .buttons { width: 50px; height: 50px; /* border: solid 2px black; */ text-align: center; color: black; cursor: pointer; background-color: white; margin: 2px; } #buttonGallery { margin: 10px; padding: 10px; /* border: solid 2px black; */ width: 75px; } .images { width: 50px; cursor: pointer; transition: transform 0.5s; } .images:hover { -ms-transform: scale(2.5); /* IE 9 */ -webkit-transform: scale(2.5); /* Safari 3-8 */ transform: scale(2.5); outline: 2px solid #CECECE; transition-delay: 0.5s; } </style> </head> <body> <script type="text/javascript"> let $buttons = $('<div id="buttonGallery">'); let myList = ["dog.png", "cat.png", "mouse.png", 'horse.png']; var startTime = performance.now() myList.map(function(picture) { let $button = $('<div></div>') .addClass('buttons') .attr('id', 'button_' + picture) .html("<img src='" + picture + "' class='images'></img>") .css("border", "10px solid #CECECE") .css("margin", "10px") .on("mouseenter", function() { var check_mouse = performance.now(); var counter = Math.round(check_mouse - startTime); if (counter > 500) { console.log(counter) $(this).hasClass('tracker'); $(this).addClass('hovered_on'); $(this).css("border", "10px solid #529A84"); } else if (count < 500) { return pass } }) .on("click", function() { console.log("do a thing") }) $buttons.append($button); }); $('body').append($buttons); </script> </body> </html>
解决方案
要实现每张图片悬停500ms后才触发状态变化,需要结合**定时器(setTimeout)和鼠标离开事件(mouseleave)**取消未完成的延迟操作,同时配合CSS的transition-delay控制视觉效果的延迟触发。
修改后的完整代码:
<html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <style media="screen"> .buttons { width: 50px; height: 50px; text-align: center; color: black; cursor: pointer; background-color: white; margin: 2px; border: 10px solid #CECECE; margin: 10px; transition: border-color 0.3s; } #buttonGallery { margin: 10px; padding: 10px; width: 75px; } .images { width: 50px; cursor: pointer; transition: transform 0.5s; transition-delay: 0.5s; /* 放大效果延迟500ms触发 */ } /* 只有当按钮有hovered_on类时,才显示放大效果 */ .buttons.hovered_on .images { -ms-transform: scale(2.5); -webkit-transform: scale(2.5); transform: scale(2.5); outline: 2px solid #CECECE; } .buttons.hovered_on { border-color: #529A84; } </style> </head> <body> <script type="text/javascript"> let $buttons = $('<div id="buttonGallery">'); let myList = ["dog.png", "cat.png", "mouse.png", 'horse.png']; myList.map(function(picture) { let $button = $('<div></div>') .addClass('buttons') .attr('id', 'button_' + picture) .html("<img src='" + picture + "' class='images'></img>") .on("mouseenter", function() { let $this = $(this); // 设置500ms后触发状态变化 $this.data('hoverTimer', setTimeout(function() { $this.addClass('hovered_on tracker'); // 添加tracker类标记已查看 }, 500)); }) .on("mouseleave", function() { let $this = $(this); // 鼠标离开时清除定时器,避免未满足时间就触发 clearTimeout($this.data('hoverTimer')); }) .on("click", function() { // 这里可以判断是否已查看(有tracker类)再执行点击逻辑 if ($(this).hasClass('tracker')) { console.log("执行点击操作"); } else { console.log("请先查看图片至少500ms"); } }); $buttons.append($button); }); $('body').append($buttons); </script> </body> </html>
关键改动说明
CSS部分:
- 将按钮的边框样式移到
.buttons基类,添加border-color过渡效果 - 给
.images添加transition-delay: 0.5s,确保放大效果延迟触发 - 把hover时的样式改为只有当按钮有
hovered_on类时才生效,避免默认hover立即触发
- 将按钮的边框样式移到
JS部分:
- 去掉页面加载时间的判断,改为给每个按钮绑定独立的定时器
mouseenter时启动500ms定时器,时间到后添加hovered_on和tracker类mouseleave时清除该按钮的定时器,防止用户快速滑过仍触发状态变化- 点击事件中增加判断,只有已查看(含
tracker类)的图片才允许执行点击操作
内容的提问来源于stack exchange,提问作者psychcoder
相关产品推荐
相关产品推荐

