这是一个相当老套的解决方案,但这是我刚刚找到的临时修复。 编辑: 在完成了下面的第一个跨浏览器解决方案之后,它一点也不骇人听闻。下面列出的 #1、#4 和 #2 解决方案应该是可用的。
jQuery Event 对象有一个隐藏的originalEvent 属性,在问题的情况下,它是一个引用本机mouseover 事件。因此event.originalEvent.target 可以同时用于 Chrome 和 Firefox。
open: function(e, ui) {
var el = e.originalEvent.target;
if (el.offsetWidth === el.scrollWidth) {
ui.tooltip.hide();
}
}
Bin
当涉及到旧的 IE 支持时,当 event.target 不存在时,您将不得不使用 event.srcElement。
var el = e.originalEvent.target || e.originalEvent.srcElement;
Bin
#1 跨浏览器解决方案
最后,当触发工具提示的元素内有嵌套元素时,您必须使用 .closest() 方法对其进行猴子补丁,该方法传递与工具提示的委托选择器相同的过滤器(items option,默认为 @ 987654346@ 从 UI 1.10.2 开始):
var el = $(e.originalEvent.target || e.originalEvent.srcElement).closest($(this).tooltip('option', 'items'))[0];
Bin
这基本上是 Tooltip Widget 在内部执行的操作,如 here 所示。
#2 替代跨浏览器解决方案
通过使用简单的 DOM 查询不需要这么多变通方法的替代解决方案:
var el = $('[aria-describedby="'+ui.tooltip[0].id+'"]')[0];
Bin
#3 内部方法滥用
这不应该被使用,但是通过覆盖内部_open 方法,您可以访问一个target jQuery 对象,该对象包含作为参数传递给它的事件的目标元素。问题是,那么您甚至无法通过.tooltip('widget') 访问它的tooltip 小部件,因为它虽然已经存在于DOM 中,但尚未“创建”。您可以使用内部的_find 方法解决它,该方法将执行DOM query by ID,因此您可以在show 动画启动后立即hide 它,而它的生命周期不受影响 - 它会在那里并像往常一样在mouseleave 上删除,但在整个周期中都会有display:none。
var bk_open = $.ui.tooltip.prototype._open;
$.ui.tooltip.prototype._open = function(event, target, content) {
bk_open.apply(this, arguments);
if (target[0].offsetWidth === target[0].scrollWidth) {
this._find(target).hide();
}
};
$(document).tooltip();
Bin
_find 的 DOM 查询是相当不必要的,所以我们还可以扩展内部的 _tooltip 方法,它返回一个包含 tooltip 元素的 jQuery 对象,这样我们就可以使用 JS 的词法范围来保存对工具提示的引用在我们被覆盖的_open 执行之前的元素:
var tooltipproto = $.ui.tooltip.prototype,
bk_open = tooltipproto._open,
bk_tooltip = tooltipproto._tooltip,
$tooltip;
tooltipproto._open = function(event, target, content) {
bk_open.apply(this, arguments);
if (target[0].offsetWidth === target[0].scrollWidth) {
$tooltip.hide();
}
};
tooltipproto._tooltip = function(element) {
return ($tooltip = bk_tooltip.apply(this, arguments));
};
$(document).tooltip();
Bin
当然,由于_tooltip 内部方法接收target 作为参数并返回tooltip,所以只需覆盖此方法即可完成整个操作,但tooltip 是shown 之后此方法返回,这将需要 setTimeout(fn, 0) 可能会导致不良闪烁效果。
但是对于这么简单的事情来说,这过于hackish、繁琐和冗长。
#4 清洁解决方案
“干净”,即不使用未记录的方法、属性、原型覆盖或 DOM 查询。回到第一个 sn-p,我们所需要的只是对触发工具提示的元素的引用。该元素由content 函数内部的this 引用,该函数在open 处理程序之前调用,因此我们可以使用词法范围来存储该引用的上一级:
var el;
$(document).tooltip({
content: function() {
el = this;
return this.title;
},
open: function(e, ui) {
if (el.offsetWidth === el.scrollWidth) {
ui.tooltip.hide();
}
}
});
Bin
请注意,我在上面 sn-p 中的自定义 content 函数删除了 jQuery 的 default HTML tags stripping(因为我喜欢在工具提示中使用 HTML),但是如果您使用用户动态填充标题属性,这可能是一个问题-输入的数据,所以如果你想保留原来的content处理程序的功能:
var el,
bk_content = $.ui.tooltip.prototype.options.content;
$(document).tooltip({
content: function() {
el = this;
return bk_content.apply(this, arguments);
},
open: function(e, ui) {
if (el.offsetWidth === el.scrollWidth) {
ui.tooltip.hide();
}
}
});
Bin
我将在 jQuery UI bugtracker 上开一张票,要求同时实现此功能。就是这样:
Tooltip: Expose element which triggered the tooltip inside open/close handlers