使用 AJAX 的引导工具提示(再一次)

Posted

技术标签:

【中文标题】使用 AJAX 的引导工具提示(再一次)【英文标题】:Bootstrap Tooltips with AJAX (One More Time) 【发布时间】:2016-09-07 01:40:26 【问题描述】:

平凡的常见用例

我想要一个工具提示,它在鼠标悬停时立即显示加载的 GIF,该 GIF 被 AJAX 成功回调产生的 html 替换。 AJAX 工具提示的错误答案几乎与在线提出这个确切问题的人一样多。特别是,我一直在为this、this,尤其是here 的几个答案建模。

对于所有这些解决方案,即使是那些专门声称要解决该问题的解决方案,我一直遇到的问题是工具提示有时会出现较晚并且无法消失。这也不是库问题,因为我过去在使用 jQuery-UI 工具提示时遇到过同样的问题。

jQuery v2.2.3 引导程序 v3.3.6

之前用 jQuery 1 尝试过,遇到了同样的问题:

jQuery v1.12.3

我的页面也依赖于 jQuery Datatables v1.10.11 库,但这与工具提示问题是正交的,除了我的特定用例会生成更多更快的 AJAX 工具提示请求且具有可变延迟,这会增加概率观察“粘”问题。

当前尝试

我目前的解决方案大致基于'towr'here 的答案,该答案非常接近工作。我已经在页面上尝试了 每个 解决方案,但它们要么因某种原因而损坏,要么存在“粘滞”工具提示问题。

因此,在 AJAX 请求加载数据以填充表格后,我按类 $( ".tooltip-cell" ).on( "mouseover", set_tooltip ) 遍历单元格,其中 set_tooltip 是执行以下操作的函数

var $e = $(this);
if( $e.attr( "title" ) === undefined )  // request data once per cell
    // show loading GIF
    $e.attr( "title", "<img src='images/wait.gif'/>" );
    $e.tooltip(
        
            html: true,
            trigger: "hover"
        
        ).tooltip( "show" );
    // perform AJAX GET
    $.ajax(
            
                url: "ajax/tooltip_data.php",
                data:
                        
                            lookup_id: $e.attr("lookup_id")
                        ,
                success:
                        function(response) 
                            // prepare final version of tooltip
                            $e.attr( "title", response ).tooltip( "fixTitle" );
                            // if mouse still hovers, display final version
                            if( $e.is( ":hover" ) ) 
                                $e.tooltip( "show" );
                            
                        ,
                dataType: "html"
            
            );

这里的问题是 AJAX 成功回调中的悬停检测。现在显然.is(":hover") 已经被弃用了很长一段时间,所以我尝试了各种替代方法,例如$( ":focus :active" ).filter( $e ).length &gt; 0,但结果总是显示 all 工具提示并粘贴或 no 显示工具提示。通过引入setTimeout( function() , 2000 ); 将代码包装在回调中,很容易重现这一点。然后问题总是出现。事实上,我可以创建 10 个相邻的工具提示,将鼠标移过它们,2 秒后,它们都将显示为 AJAX HTML 并粘住,尽管鼠标没有悬停在其中任何一个上。通过打印语句和调试,我可以验证 if( &lt;hover-check&gt; ) 中的值是否正确,反过来,这 10 个元素中的每一个都是正确的,因此悬停检查本身不正确或返回过时的信息。

关键

在与该元素对应的回调准备好工具提示内容时,如何准确地确定鼠标是否当前位于该元素的顶部?

其他想法

我在处理这个问题时遇到了两个复杂的问题,但我认为它们不相关。

1) 我收到一个错误,指出 .tooltip() 未定义,除非我的 jQuery JS 包含在 &lt;head&gt; 中并且我的 Bootstrap JS 包含在我的 HTML 正文的底部。如果我将 Bootstrap 向上或 jQuery 向下移动(始终将 jQuery 保持在 Bootstrap 之上),我会收到错误消息。

2) 解决方案here 看起来不错,但无论我尝试复制代码的程度如何,我的代码中的$el.data('tooltip').tip().is(':visible') 行都会出现$el.data(...) undefined 错误。尽管链接的演示页面本身对我来说很好。

一般希望

我希望这个问题可以成为想要这样做的人的规范资源,因为我昨天实际上花了 16 小时(是的,真的 16 小时)来解决这个问题,实现了我能想象到的每一个我能找到的解决方案的每一个变化在线。

【问题讨论】:

你能用你的代码创建一个 JSBin 或 JSFiddle 吗? 到目前为止,很遗憾没有。 JSFiddle 在模拟 AJAX 和 Bootstrap 工具提示的特定组合中表现不佳。如果可以的话,我会继续尝试并添加链接。 您在 head 标签中放置 javascript 文件的顺序是什么?首先你放置 Core Jquery JS 文件,然后放置 bootstrap JS 文件。如果你这样做,请承认我。 是的,Bootstrap 依赖于 jQuery,所以必须先加载和解析 jQuery 库。然而,我在项目早期遇到的一个相关问题是,我不小心下载了内置 jQuery 的 DataTables,这实际上意味着我正在加载 jQuery,然后是 Bootstrap,然后又覆盖了 jQuery。那不好,给我带来了无穷无尽的问题。 【参考方案1】:

核心理念

对我来说,关键在于提供的解决方案 here,我在原始问题中已链接。

源代码中出现的这个解决方案的问题是使用了$el.data('tooltip').tip().is(':visible'),这总是导致错误$el.data(...) undefined,但是检查工具提示的显示状态而不是鼠标悬停状态的想法看起来很有希望。

仔细检查 Bootstrap v3.3.6 工具提示操作后发现,它将悬停元素上的“aria- describeby”设置为工具提示的元素 ID。有了这些信息,我们就可以$( "#" + $el.attr( "aria-describedby" ) ).is( ":visible" )

我不知道这将如何适应未来,但它最终是“坚持”的。

代码

$( ".ajax-tooltip-required" ).tooltip(
        
            html: true,
            trigger: "manual"
        
        ).on(
        
            mouseenter:
                function() 
                    var $el = $(this);
                    if( $el.data( "fetched" ) === undefined ) 
                        $el.data( "fetched", true );
                        $el.attr( "data-original-title", "<img src='images/wait.gif'/>" ).tooltip( "show" );
                        $.ajax(
                            
                                url: "ajax/tooltip_data.php",
                                data:                                   
                                        lookup_id: $el.attr("lookup_id")
                                    ,
                                success:
                                    function( response ) 
                                        $el.attr( "data-original-title", response );
                                        if( $( "#" + $el.attr( "aria-describedby" ) ).is( ":visible" ) ) 
                                            $el.tooltip( "show" );
                                        
                                    ,
                                dataType: "html"
                            
                            );
                     else 
                        $(this).tooltip( "show" );
                    
                ,
            mouseleave:
                function() 
                    $(this).tooltip( "hide" );
                
        
        );

【讨论】:

以上是关于使用 AJAX 的引导工具提示(再一次)的主要内容,如果未能解决你的问题,请参考以下文章

将引导工具提示设置为 AJAX 调用结果

包含 ajax 后如何初始化引导工具提示?

为啥引导工具提示在引导模式中不起作用?

ajax 后引导程序中的工具提示不起作用

单击时更改 Twitter 引导工具提示内容

带有手动触发和选择器选项的引导工具提示