这是一个相当骇人听闻的解决方案,但这是我刚刚找到的临时修复。编辑:在完成了下面的第一个跨浏览器解决方案之后,它根本就不那么骇人听闻了。下面列出的#1、#4和#2解决方案应该是可用的。
jQuery Event 对象有一个 hiddenoriginalEvent
属性,在问题的情况下,它是一个对本机mouseover
事件的引用。因此event.originalEvent.target
可用于 Chrome 和 Firefox。
open: function(e, ui) {
var el = e.originalEvent.target;
if (el.offsetWidth === el.scrollWidth) {
ui.tooltip.hide();
}
}
垃圾桶
当涉及到旧的 IE 支持时,您将不得不使用event.srcElement
when event.target
is not present。
var el = e.originalEvent.target || e.originalEvent.srcElement;
垃圾桶
#1 跨浏览器解决方案
最后,当触发工具提示的元素内有嵌套元素时,您必须使用.closest()
传递与工具提示的委托选择器相同的过滤器的方法来对其进行猴子补丁(items
选项,默认[title]:not([disabled])
为 UI 1.10.2):
var el = $(e.originalEvent.target || e.originalEvent.srcElement).closest($(this).tooltip('option', 'items'))[0];
垃圾桶
这基本上是 Tooltip Widget 在内部执行的操作,如此处所示。
#2 替代的跨浏览器解决方案
通过使用简单的 DOM 查询不需要这么多变通方法的替代解决方案:
var el = $('[aria-describedby="'+ui.tooltip[0].id+'"]')[0];
垃圾桶
#3 内部方法滥用
这不应该被使用,但是通过覆盖内部_open
方法,您可以访问一个target
jQuery 对象,该对象包含作为参数传递给它的事件的目标元素。问题是,您甚至无法访问它的tooltip
小部件,.tooltip('widget')
因为它是“未创建”的,尽管它已经存在于 DOM 中。您可以使用内部_find
方法来解决它,该方法将通过 ID 执行DOM 查询,因此您可以hide
在show
动画开始后立即执行它,而它的生命周期不受影响 - 它会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();
垃圾桶
那个 DOM 查询_find
是相当不必要的,所以我们也可以扩展内部_tooltip
方法,它返回一个包含该元素的 jQuery 对象,这样我们就可以在我们的覆盖执行tooltip
之前使用 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();
垃圾桶
当然,由于_tooltip
内部方法接收target
as 参数并返回tooltip
,因此可以仅覆盖此方法来执行整个操作,但是由于此方法返回后tooltip
为show
n ,因此这setTimeout(fn, 0)
可能会导致不希望的闪烁效果。
对于如此简单的事情来说,这过于hackish、繁琐和冗长。
#4 清洁解决方案
“干净”,即不使用未记录的方法、属性、原型覆盖或 DOM 查询。回到第一个片段,我们所需要的只是对触发工具提示的元素的引用。该元素由在处理程序之前调用this
的函数内部引用,因此我们可以使用词法范围来存储该引用的上一级:content
open
var el;
$(document).tooltip({
content: function() {
el = this;
return this.title;
},
open: function(e, ui) {
if (el.offsetWidth === el.scrollWidth) {
ui.tooltip.hide();
}
}
});
垃圾桶
请注意,我content
在上面的代码片段中的自定义函数删除了 jQuery 的默认 HTML 标记剥离(因为我喜欢在工具提示中使用 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();
}
}
});
垃圾桶
我将在 jQuery UI bugtracker 上开一张票,要求同时实现此功能。这是它:
工具提示:公开在打开/关闭处理程序中触发工具提示的元素