实现表格悬停时显示对应商品其他门店库存的Tooltip功能
我来帮你搞定这个悬停Tooltip显示错误的问题!核心问题就是之前的Tooltip没有和当前悬停的SKU做绑定,导致一触发就把所有商品的库存都掏出来了。下面是具体的实现思路和代码示例,完全贴合你的需求:
解决方案核心思路
- 数据按SKU分组存储:从数据库拉取库存时,把每个SKU对应的4个门店库存都存在一起(比如一个对象数组,每个元素对应一个SKU的全量库存)。
- 给库存单元格绑定SKU标识:主表格里每个门店的"In Stock"单元格,都用
data-sku属性和当前行的SKU关联起来,确保悬停时能精准定位到对应商品。 - 动态生成Tooltip内容:每次悬停时,只根据当前SKU筛选出其他3个门店的库存,生成专属的小表格,而不是提前渲染所有商品的库存。
- 权限过滤:始终排除当前用户所属门店的库存,只展示其他门店的数据。
原生HTML+JS实现示例
主表格结构
<!-- 主库存表格(假设当前用户是伦敦门店) --> <table id="inventory-table" border="1" cellpadding="8"> <thead> <tr> <th>SKU</th> <th>商品名称</th> <th>In Stock (London)</th> </tr> </thead> <tbody> <!-- 动态渲染的商品行,每个行对应一个SKU --> <tr> <td>SKU-001</td> <td>无线耳机</td> <td class="stock-cell" data-sku="SKU-001">15</td> </tr> <tr> <td>SKU-002</td> <td>蓝牙音箱</td> <td class="stock-cell" data-sku="SKU-002">8</td> </tr> <tr> <td>SKU-003</td> <td>充电底座</td> <td class="stock-cell" data-sku="SKU-003">22</td> </tr> </tbody> </table> <!-- 全局Tooltip容器,初始隐藏 --> <div id="stock-tooltip" style="display: none; position: absolute; background: #fff; border: 1px solid #ddd; border-radius: 4px; padding: 8px; z-index: 9999; box-shadow: 0 2px 8px rgba(0,0,0,0.15);"></div>
JS逻辑实现
// 模拟从数据库获取的全量库存数据(实际项目中从后端接口获取) const fullInventory = [ { sku: "SKU-001", london: 15, manchester: 22, birmingham: 10, liverpool: 5 }, { sku: "SKU-002", london: 8, manchester: 14, birmingham: 0, liverpool: 18 }, { sku: "SKU-003", london: 22, manchester: 7, birmingham: 19, liverpool: 11 } ]; // 当前用户所属门店(实际从登录态/后端获取) const currentUserStore = "london"; // 获取Tooltip容器 const tooltip = document.getElementById("stock-tooltip"); // 给所有库存单元格绑定悬停事件 document.querySelectorAll(".stock-cell").forEach(cell => { cell.addEventListener("mouseover", function(e) { const targetSku = this.getAttribute("data-sku"); // 找到当前SKU的全量库存数据 const targetInventory = fullInventory.find(item => item.sku === targetSku); if (!targetInventory) return; // 生成其他门店的库存表格HTML let tooltipContent = ` <table border="1" cellpadding="4"> <thead> <tr><th>门店</th><th>库存数量</th></tr> </thead> <tbody> `; // 遍历所有门店,排除当前用户的门店和SKU字段 Object.entries(targetInventory).forEach(([store, stock]) => { if (store !== "sku" && store !== currentUserStore) { // 门店名称首字母大写,提升可读性 const storeName = store.charAt(0).toUpperCase() + store.slice(1); tooltipContent += `<tr><td>${storeName}</td><td>${stock}</td></tr>`; } }); tooltipContent += `</tbody></table>`; // 设置Tooltip内容和位置 tooltip.innerHTML = tooltipContent; tooltip.style.display = "block"; tooltip.style.left = `${e.pageX + 10}px`; tooltip.style.top = `${e.pageY + 10}px`; }); cell.addEventListener("mouseout", function() { tooltip.style.display = "none"; }); });
前端框架(Vue)简化示例
如果你的项目用了Vue这类框架,思路是一样的,只是写法更简洁:
<template> <table border="1" cellpadding="8"> <thead> <tr> <th>SKU</th> <th>商品名称</th> <th>In Stock ({{ currentStore }})</th> </tr> </thead> <tbody> <tr v-for="item in inventoryList" :key="item.sku"> <td>{{ item.sku }}</td> <td>{{ item.productName }}</td> <td @mouseover="showTooltip(item.sku, $event)" @mouseout="hideTooltip" style="cursor: pointer;" > {{ item[currentStore] }} </td> </tr> </tbody> </table> <!-- Tooltip组件 --> <div v-if="isTooltipShow" :style="{ left: tooltipX + 'px', top: tooltipY + 'px' }" class="custom-tooltip" > <table border="1" cellpadding="4"> <tr><th>门店</th><th>库存</th></tr> <tr v-for="(stock, store) in currentSkuStock" :key="store" v-if="store !== currentStore && store !== 'sku' && store !== 'productName'" > <td>{{ store.charAt(0).toUpperCase() + store.slice(1) }}</td> <td>{{ stock }}</td> </tr> </table> </div> </template> <script> export default { data() { return { inventoryList: [], currentStore: "london", isTooltipShow: false, tooltipX: 0, tooltipY: 0, currentSkuStock: {} }; }, methods: { showTooltip(sku, event) { this.currentSkuStock = this.inventoryList.find(item => item.sku === sku); this.isTooltipShow = true; this.tooltipX = event.pageX + 10; this.tooltipY = event.pageY + 10; }, hideTooltip() { this.isTooltipShow = false; } }, mounted() { // 模拟从后端获取数据 this.inventoryList = [ { sku: "SKU-001", productName: "无线耳机", london:15, manchester:22, birmingham:10, liverpool:5 }, { sku: "SKU-002", productName: "蓝牙音箱", london:8, manchester:14, birmingham:0, liverpool:18 }, { sku: "SKU-003", productName: "充电底座", london:22, manchester:7, birmingham:19, liverpool:11 } ]; } }; </script> <style scoped> .custom-tooltip { position: absolute; background: #fff; border: 1px solid #ddd; border-radius: 4px; padding: 8px; z-index: 9999; box-shadow: 0 2px 8px rgba(0,0,0,0.15); } </style>
这样实现后,你悬停任意SKU的库存单元格时,只会弹出该SKU的其他3个门店库存,完美解决之前显示全部商品的问题,同时也满足了不同用户组只能查看自己门店库存的权限要求。
内容的提问来源于stack exchange,提问作者MailBlade
相关产品推荐
相关产品推荐

