鼠标悬停显示下一个元素异常:嵌套div内的box无法触发效果
问题分析与解决方案
为什么第一个.box无法生效?
你的问题出在$(this).next()这个方法的使用上:
next()只能获取当前元素的直接同级下一个元素,但第一个.box被嵌套在两层<div>内部,它的同级元素在当前DOM层级里根本不存在(它的父级是<div>,而这个<div>的兄弟才是包含第二个.box的元素),所以$(this).next()返回的是空对象,自然无法获取到下一个.box里的.test元素。- 第二个和第三个
.box是直接同级的<a>元素,所以next()能正常定位到下一个.box,因此功能正常。
修复方案:基于元素集合索引定位
我们可以先把所有.box元素收集成一个集合,然后通过当前元素在集合中的索引,直接找到下一个.box,完全脱离DOM层级的限制。
修改后的完整代码:
JavaScript
$(function() { // 先收集页面上所有的.box元素 const $allBoxes = $('.box'); $allBoxes.hover( function() { // 获取当前box在集合中的索引 const currentIndex = $allBoxes.index(this); // 检查是否存在下一个box(避免最后一个box越界) if (currentIndex < $allBoxes.length - 1) { // 找到下一个box元素 const $nextBox = $allBoxes.eq(currentIndex + 1); // 获取下一个box内.test的data属性值 const targetText = $nextBox.find('.test').attr('data'); // 在当前box内添加提示框(用class代替id,避免全局重复冲突) $(this).append('<div class="boxText">' + targetText + '</div>'); } }, function() { // 移除当前box内的提示框,而不是全局移除 $(this).find('.boxText').remove(); } ); });
CSS
.test { padding: 75px; background: #eee; float: left; margin: 5px; border: solid 1px #ddd; cursor: pointer; } /* 把id改为class,避免多个提示框的id冲突问题 */ .boxText { position: absolute; bottom: -35px; left: 5px; width: 150px; text-align: center; background: #45719B; color: #FFF; border: solid 1px #26445F; font-family: Arial, Helvetica, sans-serif; padding: 5px 0; } .box { position: relative; float: left; margin: 0; padding: 0; }
HTML(保持不变)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div> <div> <a class="box"> <span class="test" data="first"></span> </a> </div> </div> <a class="box"> <span class="test" data="second"></span> </a> <a class="box"> <span class="test" data="third"></span> </a>
额外优化点说明
- 用class代替id:原来的
#boxText是全局唯一的id,如果多个.box同时触发hover(比如快速移动鼠标),会出现移除错误,改成.boxText并通过当前元素查找移除,更安全。 - 边界判断:添加了
currentIndex < $allBoxes.length - 1的判断,避免最后一个.box悬停时因为找不到下一个元素而报错。 - 使用
find()代替children():children()只能查找直接子元素,find()可以查找所有后代元素,兼容性更强,即使.test嵌套更深也能找到。
内容的提问来源于stack exchange,提问作者john Travor
相关产品推荐
相关产品推荐

