如何在JS中实现网格Hover时获取行列并添加日历事件
问题解决:日历网格悬停获取行列并显示添加按钮
问题分析
原代码存在几个关键问题:
- jQuery的
hover()方法第一个参数是mouseenter回调,第二个才是mouseleave,你把逻辑写反了; .row和.col是同级元素,.row内部没有.col,所以$(this).find(".col")无法找到目标元素;- 现有网格结构用
.row和.col做分隔线,没有实际的单元格容器,无法直接监听单个单元格的悬停事件。
解决方案
我们需要先给每个网格单元格添加透明的占位容器,这样既能监听悬停,又能显示“+”按钮,同时准确获取行列信息。
1. 修正HTML结构(添加单元格占位)
在.content里添加单元格容器,每个单元格对应一个时间段和日期:
<div class="container-orario h-full relative antialiased w-full"> <div class="days" id="classroom_admin-orario-days"> <div class="filler"></div> <div class="filler"></div> <div class="day">Lun</div> <div class="day">Mar</div> <div class="day">Mer</div> <div class="day">Gio</div> <div class="day">Ven</div> <div class="day">Sab</div> </div> <div class="content" id="classroom_admin-orario-content"> <!-- 时间标签 --> <div class="time" style="grid-row:1">08:00</div> <div class="time" style="grid-row:2">09:00</div> <div class="time" style="grid-row:3">10:00</div> <div class="time" style="grid-row:4">11:00</div> <div class="time" style="grid-row:5">12:00</div> <div class="time" style="grid-row:6">13:00</div> <div class="time" style="grid-row:7">14:00</div> <div class="filler-col"></div> <!-- 单元格占位容器:7行 × 6列 --> <div class="cell" style="grid-column:3;grid-row:1"></div> <div class="cell" style="grid-column:4;grid-row:1"></div> <div class="cell" style="grid-column:5;grid-row:1"></div> <div class="cell" style="grid-column:6;grid-row:1"></div> <div class="cell" style="grid-column:7;grid-row:1"></div> <div class="cell" style="grid-column:8;grid-row:1"></div> <div class="cell" style="grid-column:3;grid-row:2"></div> <div class="cell" style="grid-column:4;grid-row:2"></div> <div class="cell" style="grid-column:5;grid-row:2"></div> <div class="cell" style="grid-column:6;grid-row:2"></div> <div class="cell" style="grid-column:7;grid-row:2"></div> <div class="cell" style="grid-column:8;grid-row:2"></div> <div class="cell" style="grid-column:3;grid-row:3"></div> <div class="cell" style="grid-column:4;grid-row:3"></div> <div class="cell" style="grid-column:5;grid-row:3"></div> <div class="cell" style="grid-column:6;grid-row:3"></div> <div class="cell" style="grid-column:7;grid-row:3"></div> <div class="cell" style="grid-column:8;grid-row:3"></div> <div class="cell" style="grid-column:3;grid-row:4"></div> <div class="cell" style="grid-column:4;grid-row:4"></div> <div class="cell" style="grid-column:5;grid-row:4"></div> <div class="cell" style="grid-column:6;grid-row:4"></div> <div class="cell" style="grid-column:7;grid-row:4"></div> <div class="cell" style="grid-column:8;grid-row:4"></div> <div class="cell" style="grid-column:3;grid-row:5"></div> <div class="cell" style="grid-column:4;grid-row:5"></div> <div class="cell" style="grid-column:5;grid-row:5"></div> <div class="cell" style="grid-column:6;grid-row:5"></div> <div class="cell" style="grid-column:7;grid-row:5"></div> <div class="cell" style="grid-column:8;grid-row:5"></div> <div class="cell" style="grid-column:3;grid-row:6"></div> <div class="cell" style="grid-column:4;grid-row:6"></div> <div class="cell" style="grid-column:5;grid-row:6"></div> <div class="cell" style="grid-column:6;grid-row:6"></div> <div class="cell" style="grid-column:7;grid-row:6"></div> <div class="cell" style="grid-column:8;grid-row:6"></div> <div class="cell" style="grid-column:3;grid-row:7"></div> <div class="cell" style="grid-column:4;grid-row:7"></div> <div class="cell" style="grid-column:5;grid-row:7"></div> <div class="cell" style="grid-column:6;grid-row:7"></div> <div class="cell" style="grid-column:7;grid-row:7"></div> <div class="cell" style="grid-column:8;grid-row:7"></div> <!-- 原有分隔线 --> <div class="col" style="grid-column:3"></div> <div class="col" style="grid-column:4"></div> <div class="col" style="grid-column:5"></div> <div class="col" style="grid-column:6"></div> <div class="col" style="grid-column:7"></div> <div class="col" style="grid-column:8"></div> <div class="row" style="grid-row:1"></div> <div class="row" style="grid-row:2"></div> <div class="row" style="grid-row:3"></div> <div class="row" style="grid-row:4"></div> <div class="row" style="grid-row:5"></div> <div class="row" style="grid-row:6"></div> <div class="row" style="grid-row:7"></div> <!-- EVENT LIST --> <div class="event calendar1" style="grid-column: 3;grid-row: 2/span 2; ">Matematica<br><span class="time-subtitle">08:00 - 10:00</span></div> <div class="event calendar2" style="grid-column: 3;grid-row: 4/span 1;">Sistemi e Reti<br><span class="time-subtitle">10:00 - 11:00</span></div> <div class="event calendar3" style="grid-column: 3;grid-row: 5/span 1;">Educazione Fisica<br><span class="time-subtitle">11:00 - 12:00</span></div> <div class="event calendar4" style="grid-column: 3;grid-row: 6/span 1;">Inglese<br><span class="time-subtitle">12:00 - 13:00</span></div> <div class="event calendar5" style="grid-column: 3;grid-row: 7/span 1;">Italiano<br><span class="time-subtitle">13:00 - 14:00</span></div> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
2. 添加CSS样式(实现悬停显示“+”)
给单元格添加透明背景和悬停样式,同时设置事件层级低于原有事件:
/* 原有CSS保持不变,新增以下内容 */ .cell { position: relative; z-index: 1; /* 低于event的层级,避免遮挡事件 */ } .cell:hover { background-color: rgba(0,0,0,0.05); } .cell:hover::after { content: "+"; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 2em; color: #217346; font-weight: bold; }
3. 修正JavaScript代码(获取行列信息)
直接监听每个.cell的悬停事件,提取对应的网格行列:
// 监听所有单元格的悬停事件 $(".cell").hover(function() { // 获取当前单元格的网格行和列(通过getComputedStyle获取) const style = window.getComputedStyle(this); const gridRow = style.gridRowStart; const gridCol = style.gridColumnStart; // 转换为用户友好的序号(列从1开始对应Lun到Sab) const dayIndex = parseInt(gridCol) - 2; // 因为gridColumn从3开始,对应第1天 const timeIndex = parseInt(gridRow); console.log(`行(时间段): ${timeIndex} 列(星期): ${dayIndex}`); });
关键说明
- 新增的
.cell元素作为透明占位,不会影响原有布局,但能准确捕捉悬停事件; - 通过
getComputedStyle直接读取网格的行列值,比通过DOM索引更可靠,避免DOM结构变化导致的错误; - 悬停时显示的“+”按钮通过CSS伪元素实现,无需额外DOM元素,保持结构简洁。
内容的提问来源于stack exchange,提问作者Matteo
相关产品推荐
相关产品推荐

