You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过jQuery结合GET请求动态设置Tooltip并即时显示?

动态加载AJAX数据实现表格行Tooltip的问题与优化方案

问题背景

我需要通过AJAX请求获取数据,为表格行添加Tooltip,目标是用户悬停在指定表格行上时显示额外信息。当前代码能实现基础功能,但存在一个问题:首次悬停时Tooltip不会立即显示,必须将鼠标移开再悬停才会出现。推测原因是title属性在第一次mouseover事件触发后才通过AJAX请求完成设置,错过了浏览器原生Tooltip的触发时机。

现有代码

JavaScript代码

function tooltip(event) {
    const sor = event.target.closest('tr');
    if (!sor) return;

    const tabla = sor.closest('table');
    const tablaNev = tabla.id.replace('Tabla', '');
    console.log(tablaNev);

    const mezo = Array.from(sor.children).map((cella) => cella.innerText);
    console.log(mezo);

    if (tablaNev === "tablazat0") {
        const id = mezo[0];
        $.get(`/bevetel?id=${id}`, function(data) {
            if (data && data.length > 0) {
                const osszesDarab = data[0].OsszesDarab;
                const osszesBevetel = data[0].OsszesBevetel;
                $(sor).attr(
                    "title",
                    `Összes darab: ${osszesDarab}, Összes bevétel: ${osszesBevetel} Ft`
                );
            }
        });
    }
}

$(document).on('mouseover', '#tablazat0 tbody tr', tooltip);

HTML代码

<div class="row col-12 justify-content-center" style="height: calc(100vh - 100px);">
    <div class="col-lg-5 h-100 mb-5" style="overflow: auto;">
        <h2 id="tablazatCim0" class="tablazatCim"></h2>
        <table id="tablazat0" class="table table-striped table-bordered table-hover table-responsive-xs">
            <thead id="tablazatHead0"></thead>
            <tbody id="tablazatBody0"></tbody>
        </table>
    </div>
    <div class="col-lg-5 h-100 mb-5" style="overflow: auto;">
        <h2 id="tablazatCim1" class="tablazatCim"></h2>
        <table id="tablazat1" class="table table-striped table-bordered table-hover table-responsive-xs">
            <thead id="tablazatHead1"></thead>
            <tbody id="tablazatBody1"></tbody>
        </table>
    </div>
</div>

问题分析

浏览器原生Tooltip的触发逻辑是:在mouseover事件触发时读取元素的title属性并显示提示。首次悬停时,AJAX请求尚未完成,title属性还未设置,因此浏览器无法读取到提示内容;当AJAX请求完成并设置title后,本次mouseover事件的Tooltip触发时机已经错过,必须再次触发mouseover(即移开再悬停)才能显示。

解决方案

方案1:修复原生Tooltip的即时显示问题

核心思路是缓存已加载的数据避免重复请求,并在AJAX完成后,若鼠标仍悬停在该行,手动触发Tooltip的触发逻辑。

修改后的JavaScript代码:

// 缓存已获取的tooltip数据,避免重复AJAX请求
const tooltipCache = {};

function tooltip(event) {
    const sor = event.target.closest('tr');
    if (!sor) return;

    const $sor = $(sor);
    // 检查是否已加载过tooltip数据,避免重复请求
    if ($sor.data('tooltip-loaded')) return;

    const tabla = sor.closest('table');
    const tablaNev = tabla.id.replace('Tabla', '');

    const mezo = Array.from(sor.children).map((cella) => cella.innerText);

    if (tablaNev === "tablazat0") {
        const id = mezo[0];
        // 先检查缓存
        if (tooltipCache[id]) {
            setTooltipContent($sor, tooltipCache[id]);
            return;
        }

        $.get(`/bevetel?id=${id}`, function(data) {
            if (data && data.length > 0) {
                const tooltipData = {
                    osszesDarab: data[0].OsszesDarab,
                    osszesBevetel: data[0].OsszesBevetel
                };
                // 存入缓存
                tooltipCache[id] = tooltipData;
                setTooltipContent($sor, tooltipData);
                
                // 检查鼠标是否仍悬停在该行,若是则手动触发mouseover事件
                if ($sor.is(':hover')) {
                    $sor.trigger('mouseover');
                }
            }
        });
    }
}

function setTooltipContent($element, data) {
    $element.attr(
        "title",
        `Összes darab: ${data.osszesDarab}, Összes bevétel: ${data.osszesBevetel} Ft`
    ).data('tooltip-loaded', true);
}

$(document).on('mouseover', '#tablazat0 tbody tr', tooltip);

方案2:使用自定义Tooltip(推荐)

原生Tooltip的可控性较差,使用自定义Tooltip组件(如jQuery UI Tooltip)可以更灵活地处理动态内容更新,无需依赖原生title属性。

步骤1:引入jQuery UI(若项目未引入)

若项目中尚未使用jQuery UI,需先引入其样式文件和脚本文件(可从官方下载后本地引入)。

步骤2:修改代码实现动态Tooltip

const tooltipCache = {};

// 初始化jQuery UI Tooltip
$(document).tooltip({
    items: '#tablazat0 tbody tr',
    content: function() {
        const $tr = $(this);
        const mezo = Array.from($tr.children()).map(cella => cella.innerText);
        const id = mezo[0];
        
        // 优先使用缓存数据
        if (tooltipCache[id]) {
            return `Összes darab: ${tooltipCache[id].osszesDarab}, Összes bevétel: ${tooltipCache[id].osszesBevetel} Ft`;
        }
        
        // 若未缓存,发起AJAX请求并更新Tooltip内容
        $.get(`/bevetel?id=${id}`, function(data) {
            if (data && data.length > 0) {
                const tooltipData = {
                    osszesDarab: data[0].OsszesDarab,
                    osszesBevetel: data[0].OsszesBevetel
                };
                tooltipCache[id] = tooltipData;
                // 更新当前Tooltip的内容
                $(document).tooltip('option', 'content', 
                    `Összes darab: ${tooltipData.osszesDarab}, Összes bevétel: ${tooltipData.osszesBevetel} Ft`
                );
            }
        });
        
        // 临时显示加载提示
        return 'Betöltés...';
    }
});

优化建议

  • 数据缓存:使用对象缓存已获取的Tooltip数据,避免重复发起AJAX请求,减少服务器压力并提升响应速度。
  • 防抖处理:若用户快速移动鼠标,可添加防抖函数(如setTimeout)延迟触发AJAX请求,避免频繁请求。
  • 预加载数据:如果表格数据是动态渲染的,可在表格渲染完成后批量预加载所有行的Tooltip数据,彻底避免悬停时的等待。
  • 样式定制:自定义Tooltip可以根据项目需求定制样式,提升视觉体验,而原生Tooltip样式无法修改。

内容的提问来源于stack exchange,提问作者koko moko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 02:22:04