讲讲下面的鼠标划入划出事件是如何实现的
js代码:
<script>
//鼠标滑出事件
function mouseOver(obj){
obj.className="appliance js_toggle relative hover"; //设置当前事件对象样式
var menu=obj.childNodes; //寻找该事件子节点(商品子类别)
menu[3].style.display='block'; //设置子节点显示
}
//鼠标滑入事件
function mouseOut(obj){
obj.className="appliance js_toggle relative"; //设置当前事件对象样式
var menu=obj.childNodes; //寻找该事件子节点(商品子类别)
menu[3].style.display='none'; //设置子节点隐藏
}
</script>
相关的html代码:
<li class="appliance js_toggle relative " onmouseover="mouseOver(this)" onmouseout="mouseOut(this)" > <div class="category-info"> <h3 class="category-name b-category-name"><i><img src="images/cake.png"></i><a class="ml-22" title="家用电器">家用电器</a></h3> <em>></em></div> <div class="menu-item menu-in top" > <div class="area-in"> <div class="area-bg"> <div class="menu-srot"> <div class="sort-side"> <dl class="dl-sort"> <dt><span >生活电器</span></dt> <dd><a href="shopInfo.html"><span>取暖电器</span></a></dd> <dd><a href="shopInfo.html"><span>吸尘器</span></a></dd> <dd><a href="shopInfo.html"><span>净化器</span></a></dd> <dd><a href="shopInfo.html"><span>扫地机器人</span></a></dd> <dd><a href="shopInfo.html"><span>加湿器</span></a></dd> <dd><a href="shopInfo.html"><span>熨斗</span></a></dd> <dd><a href="shopInfo.html"><span>电风扇</span></a></dd> <dd><a href="shopInfo.html"><span>冷风扇</span></a></dd> <dd><a href="shopInfo.html"><span>插座</span></a></dd> </dl> <dl class="dl-sort"> <dt><span >厨房小电</span></dt> <dd><a href="#"><span>电饭煲</span></a></dd> <dd><a href="#"><span>微波炉</span></a></dd> <dd><a href="#"><span>电烤箱</span></a></dd> <dd><a href="#"><span>电磁炉</span></a></dd> <dd><a href="#"><span>电压力锅</span></a></dd> <dd><a href="#"><span>豆浆机</span></a></dd> <dd><a href="#"><span>咖啡机</span></a></dd> <dd><a href="#"><span>面包机</span></a></dd> <dd><a href="#"><span>榨汁机</span></a></dd> </dl> </div> </div> </div> </div> </div> <b class="arrow"></b> </li>
鼠标划入划出事件实现详解
这是一个典型的导航菜单二级下拉效果。当鼠标滑入“家用电器”菜单项时,显示下方商品子类别;鼠标滑出时隐藏。
一、整体工作原理
text
用户鼠标划入 → onmouseover 触发 → mouseOver() 执行 → 显示子菜单 用户鼠标划出 → onmouseout 触发 → mouseOut() 执行 → 隐藏子菜单
二、HTML 结构分析
关键部分是一个 <li> 元素,它代表整个菜单项(包括主标题和子菜单):
html
<li class="appliance js_toggle relative" onmouseover="mouseOver(this)" onmouseout="mouseOut(this)"> <!-- 主菜单内容(家用电器标题) --> <div class="category-info"> <h3 class="category-name"> <i><img src="images/cake.png"></i> <a class="ml-22" title="家用电器">家用电器</a> </h3> <em>></em> </div> <!-- 子菜单内容(商品子类别) --> <div class="menu-item menu-in top"> <!-- 各种电器分类列表... --> </div> <b class="arrow"></b></li>
三、JS 代码逐行详解
1、mouseOver 函数(鼠标划入时)
javascript
function mouseOver(obj){定义一个名为
mouseOver的函数obj是参数,接收触发事件的元素对象这里的
obj就是<li>元素本身(因为 HTML 中写的是onmouseover="mouseOver(this)")
javascript
obj.className="appliance js_toggle relative hover";
修改
<li>元素的class属性值原类名:
appliance js_toggle relative新类名:
appliance js_toggle relative hover添加了
hover类,通常 CSS 中会给.hover类设置特殊样式(如背景色变化)这行实现了主菜单项的高亮效果
javascript
var menu=obj.childNodes;
obj.childNodes:获取<li>元素的所有子节点子节点包括:
div.category-info(主菜单标题)div.menu-item(子菜单内容)b.arrow(箭头图标)以及可能的文本节点(换行符、空格)
注意:
childNodes会包含文本节点,而children只包含元素节点
javascript
menu[3].style.display='block';
menu[3]:取子节点集合中的第 4 个元素(索引从 0 开始)根据 DOM 结构,
menu[3]应该是div.menu-item(子菜单容器)style.display='block':将子菜单的 CSSdisplay属性设为block,使其显示出来
2、mouseOut 函数(鼠标划出时)
javascript
function mouseOut(obj){
obj.className="appliance js_toggle relative";将
<li>的类名恢复为原来的值移除
hover类,取消高亮效果
javascript
var menu=obj.childNodes; menu[3].style.display='none';
获取子节点,找到子菜单容器
style.display='none':将子菜单隐藏起来
四、menu[3] 索引的详细说明
menu[3] 为什么是 div.menu-item?让我们分析子节点列表:
html
<li> ↕ 可能存在文本节点(换行符/空格) <div class="category-info">...</div> ← 索引 0 或 1 ↕ 可能存在文本节点 <div class="menu-item">...</div> ← 索引 3(假设有文本节点) ↕ 可能存在文本节点 <b class="arrow"></b></li>
注意:childNodes 会包含换行符等文本节点,所以索引位置依赖于 HTML 的格式化。如果 HTML 没有多余空格,menu[1] 可能就是子菜单。
更稳妥的写法
javascript
// 推荐:使用 querySelector 直接查找,不依赖索引function mouseOver(obj){
obj.className = "appliance js_toggle relative hover";
var menu = obj.querySelector('.menu-item');
if(menu) menu.style.display = 'block';}五、事件绑定方式
HTML 中的内联事件绑定:
html
<li onmouseover="mouseOver(this)" onmouseout="mouseOut(this)">
onmouseover:鼠标划入时触发onmouseout:鼠标划出时触发this:指向当前<li>元素本身
等价于 JavaScript 绑定:
javascript
var li = document.querySelector('li');li.onmouseover = function() { mouseOver(this); };li.onmouseout = function() { mouseOut(this); };六、完整执行流程图
text
┌─────────────────────────────────────────────────────────┐ │ 初始状态 │ │ ┌─────────────────────────────────────────────────────┐│ │ │ 家用电器 > ││ │ └─────────────────────────────────────────────────────┘│ │ ┌─────────────────────────────────────────────────────┐│ │ │ 子菜单 (display: none) → 不可见 ││ │ └─────────────────────────────────────────────────────┘│ └─────────────────────────────────────────────────────────┘ ↓ 用户鼠标划入 ↓ ┌─────────────────────────────────────────────────────────┐ │ onmouseover 触发 → mouseOver() │ │ 1. 添加 hover 类 → 背景高亮 │ │ 2. menu[3].style.display = 'block' → 子菜单显示 │ └─────────────────────────────────────────────────────────┘ ↓ 用户鼠标划出 ↓ ┌─────────────────────────────────────────────────────────┐ │ onmouseout 触发 → mouseOut() │ │ 1. 移除 hover 类 → 取消高亮 │ │ 2. menu[3].style.display = 'none' → 子菜单隐藏 │ └─────────────────────────────────────────────────────────┘
七、潜在问题及改进建议
| 问题 | 说明 | 改进方案 |
|---|---|---|
| 索引依赖 | menu[3] 依赖于 HTML 格式,容易出错 | 使用 querySelector('.menu-item') |
| 文本节点干扰 | 换行符会被当作文本节点 | 使用 children 代替 childNodes |
| CSS 类名硬编码 | 类名写在 JS 中,维护不便 | 使用 classList.add/remove |
改进后的代码:
javascript
function mouseOver(obj){
obj.classList.add('hover');
var menu = obj.querySelector('.menu-item');
if(menu) menu.style.display = 'block';}function mouseOut(obj){
obj.classList.remove('hover');
var menu = obj.querySelector('.menu-item');
if(menu) menu.style.display = 'none';}八、总结
| 事件 | 函数 | 主要操作 |
|---|---|---|
onmouseover | mouseOver() | 添加 hover 类 + 显示子菜单 |
onmouseout | mouseOut() | 移除 hover 类 + 隐藏子菜单 |
核心原理:通过修改子菜单的 display 属性值(block/none)来控制其显示和隐藏,同时通过添加/移除 hover 类来实现主菜单的高亮效果