在 Ajax 加载后使 jQuery UI 工具提示重新定位
Make jQuery UI Tooltip reposition after Ajax loading
我正在尝试实现一个 ajax 加载的工具提示,它应该包含一个 HTML table.
在执行ajax调用时,工具提示首先显示一个"loading..."文本,然后当接收到HTML数据时,它被用作工具提示内容。
问题是工具提示位置似乎只在开始时计算,当显示 "loading..." 时,而不是在工具提示内容更改时再次计算。
工具提示使用以下代码初始化:
$('.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
部分而是采用了 certer,如此处所示:
查看控制台,我明白了
Error: no such method 'instance' for tooltip widget instance
我猜这可能是因为我们仍在使用 jQuery UI 版本 1.10.4
您可以利用 using
属性(作为 callback/hook)记录在 jQuery UI position method
When specified, the actual property setting is delegated to this callback.
更清洁的方法
…就是利用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>
我正在尝试实现一个 ajax 加载的工具提示,它应该包含一个 HTML table.
在执行ajax调用时,工具提示首先显示一个"loading..."文本,然后当接收到HTML数据时,它被用作工具提示内容。
问题是工具提示位置似乎只在开始时计算,当显示 "loading..." 时,而不是在工具提示内容更改时再次计算。
工具提示使用以下代码初始化:
$('.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
部分而是采用了 certer,如此处所示:
查看控制台,我明白了
Error: no such method 'instance' for tooltip widget instance
我猜这可能是因为我们仍在使用 jQuery UI 版本 1.10.4
您可以利用 using
属性(作为 callback/hook)记录在 jQuery UI position method
When specified, the actual property setting is delegated to this callback.
更清洁的方法
…就是利用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>