【问题标题】:Make jQuery UI Tooltip reposition after Ajax loading在 Ajax 加载后重新定位 jQuery UI Tooltip
【发布时间】:2018-03-10 10:37:30
【问题描述】:

我正在尝试实现一个 ajax 加载的工具提示,它应该包含一个 HTML 表格。

在执行ajax调用时,tooltip首先显示“正在加载...”文本,然后在收到HTML数据时,将其用作tooltip内容。

问题是工具提示位置似乎只在开始时计算,当显示“正在加载...”时,而不是在工具提示内容更改时再次计算。

工具提示使用以下代码初始化:

$('.my_tooltip').each(function() {
    var $this = $(this),
        tooltip_url = $this.data('tooltip-url'),
        cache_id = tooltip_url || '',
        opts = $.extend({}, {
            content: function(done) {
                if(tooltip.cache[cache_id]) {
                    return tooltip.cache[cache_id];
                }

                if(tooltip_url) {
                    Ajax.get($this.data('tooltip-url'), {}, {
                        dataType: 'html',
                        success: function(data) {
                            tooltip.cache[cache_id] = data;
                            done(tooltip.cache[cache_id]);
                        },
                        error: function() {
                            done('Error while loading data!');
                        }
                    });

                    return 'Loading...';
                }

                return $this.attr('title');
            },
            items: $this,
            tooltipClass: $this.data('tooltip-class') || ('age-tooltip' + (!tooltip_id && !tooltip_url ? '-auto' : ''))
        }, options);

    $this.tooltip(opts);
});

这是加载时的工具提示,此时工具提示确实适合视口。

这是加载后的样子,因为你看到工具提示没有自动重新定位,所以你只能看到不到一半。

在这种情况下,如果它移动到带有工具提示的元素上,它将完全可见,但是即使我让工具提示消失然后再次移动鼠标悬停,从本地工具提示缓存中加载它,它不会重新定位。

我已经查看了工具提示的position 属性,但是如果可能的话,我希望避免手动指定它,并让插件自动处理它。

有没有办法将工具提示定位在 ajax 加载后大部分可见的位置?

编辑:

我尝试了@Stphane 的解决方案,位置为{my: 'left top+15', at: 'left bottom', of: this, collision: 'flipfit'},但位置不正确,似乎忽略了top/bottom 部分,而是采用了证书,如下所示:

查看控制台,我明白了

错误:工具提示小部件实例没有此类方法“实例”

我猜这可能是因为我们仍在使用 jQuery UI 版本 1.10.4

【问题讨论】:

    标签: javascript jquery jquery-ui tooltip jquery-ui-tooltip


    【解决方案1】:

    您可以利用jQuery UI position method 上记录的using 属性(作为回调/挂钩)

    指定后,实际的属性设置将委托给此回调。

    更清洁的方法

    …就是使用tooltip实例getter尽快申请到正确的位置:

    var tooltip = {cache: []},
        posSetter = function () {
            // 1.10.4 code
            $('.ui-tooltip').position({
            // 1.12.1
            // this.tooltip('instance').bindings.filter('.ui-tooltip').position({
                // Put the values that fit your need
                my: 'left top+15', at: 'left bottom', of: this, collision: "flip fit"
              })
            ;
        };
    
    $('.my_tooltip').each(function() {
      var $this = $(this),
        ownPosSetter = posSetter.bind($this),
        tooltip_url = $this.data('tooltip-url'),
        cache_id = tooltip_url || '',
        opts = $.extend({}, {
          content: function(done) {
            if (tooltip.cache[cache_id]) {
              return tooltip.cache[cache_id];
            }
    
            if (tooltip_url) {
              setTimeout(() => {
                let content = "<div style='height:200px;width:300px'>Content Loaded!</div>";
                tooltip.cache[cache_id] = content;
                done(content);
                setTimeout(ownPosSetter, 100);
              }, 2000);
              return 'Loading...';
            }
    
            return $this.attr('title');
          },
          items: $this,
          tooltipClass: 'age-tooltip-auto'
        }, {position: {using: ownPosSetter}});
    
      $this.tooltip(opts);
    });
    div.contents {
      min-height: 50px;
      margin-top: 10px;
      border: 1px solid black
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.4/css/jquery-ui.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js">
    <!-- 
    < link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet" / >
    < script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" >
    -->
    </script>
    <div class="contents"></div>
    <div class="contents"></div>
    <div class="contents"></div>
    <div class="contents"></div>
    <div class="contents"></div>
    <div class="contents"></div>
    <div class="contents"></div>
    <div class="contents my_tooltip" title="Some content" data-tooltip-url="//somewhere.com">Has tooltip</div>
    <div class="contents my_tooltip" title="Some content" data-tooltip-url="//somewhereelse.com">Has tooltip</div>
    <div class="contents" id="log"></div>
    <div class="contents"></div>
    <div class="contents"></div>
    <div class="contents"></div>
    <div class="contents"></div>

    【讨论】:

    • 这可行,我会尽快尝试,我只需要根据高度而不是宽度更改代码即可,谢谢!
    • 有比使用间隔更好的方法。我已经编辑了我的答案。
    • @MatteoTassinari 似乎我的答案中的“setInterval Alternative”部分不适用于1.10.4。我花了一些时间在这上面,我希望你早点告诉过版本约束。不过我们会找到办法的。
    • 你说得对,很抱歉浪费了你的时间,我没有写,因为我确定我是最新版本,只有控制台中的错误消息让我意识到我错了
    • @MatteoTassinari 作为一种解决方法,您所要做的就是直接查找工具提示 HTMLDOMElement 而不是依赖工具提示插件实例:我将 this.tooltip('instance').bindings.filter('.ui-tooltip').position({ 更改为 $('.ui-tooltip').position({(加上脚本和 css链接到相应的版本)。检查我的更新。
    猜你喜欢
    • 1970-01-01
    • 2013-02-02
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多