Fab*_*tté 3 javascript firefox jquery jquery-ui jquery-ui-tooltip
基本上,我将一个open处理程序附加到我的jQuery UI工具提示,该工具提示对触发工具提示的元素执行一些检查.到目前为止我得到了什么:
$(document).tooltip({
open: function(e, ui) {
var el = e.toElement/* || e.relatedTarget*/;
console.log(el.offsetWidth, el.scrollWidth);
if (el.offsetWidth === el.scrollWidth) {
ui.tooltip.hide();
}
}
});
Run Code Online (Sandbox Code Playgroud)
上面的检查可防止工具提示出现,除非元素水平溢出,这是流体布局的一部分.它可以很好地在Chrome中运行,你可以在这个jsBin中看到.
但是,在Firefox中,event.toElement是undefined.从阅读SO周围的线索,我认为这event.relatedTarget将是一个合适的替代品,但事实并非如此.在event.toElement引用当前悬停的项目时,event.relatedTarget在mouseover引用中指向设备退出的元素,这是根据W3C规范的正确行为(类似于Chrome的event.fromTarget).
我也试过event.target,event.currentTarget和this参考,但这些点document,因为它是具有结合到工具提示的事件处理程序的节点.通过Tooltip API页面也没有帮助.
我不确定我是否忽略了一些非常基本的东西,或者我是否应该尝试更少的正统方法.
有没有办法获得对open在Firefox中工作的工具提示处理程序内部触发的元素的引用?或者是否有一些神奇的jQuery UI Tooltip选项/方法可以以更简单/类似的方式实现这种期望的行为?
这是一个相当hackish的解决方案,但这是我刚刚发现的临时修复.编辑:在完成下面的第一个跨浏览器解决方案后,它根本不是那么hackish.下面列出的#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();
}
}
Run Code Online (Sandbox Code Playgroud)
当涉及旧的IE支持时,您将不得不event.srcElement在event.target不存在时使用.
var el = e.originalEvent.target || e.originalEvent.srcElement;
Run Code Online (Sandbox Code Playgroud)
最后,当触发工具提示的元素中有嵌套元素时,您必须使用.closest()传递与工具提示的委托选择器相同的过滤器的方法对其进行monkeypatch (items选项,默认[title]:not([disabled])为UI 1.10.2):
var el = $(e.originalEvent.target || e.originalEvent.srcElement).closest($(this).tooltip('option', 'items'))[0];
Run Code Online (Sandbox Code Playgroud)
这基本上是什么工具提示部件内部确实如图所示这里.
通过使用简单的DOM查询不需要这么多变通办法的替代解决方案:
var el = $('[aria-describedby="'+ui.tooltip[0].id+'"]')[0];
Run Code Online (Sandbox Code Playgroud)
#3滥用内部方法
这不应该使用,但是通过覆盖内部_open方法,您可以访问targetjQuery对象,该对象包含作为参数传递给它的事件的目标元素.问题是,然后你甚至没有访问它的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();
Run Code Online (Sandbox Code Playgroud)
那个DOM查询_find是不必要的,所以我们也可以扩展内部_tooltip方法,它返回一个包含该tooltip元素的jQuery对象,这样我们就可以使用JS的词法范围在我们重写_open执行之前保存对tooltip元素的引用:
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();
Run Code Online (Sandbox Code Playgroud)
当然,当_tooltip内部方法接收targetas参数并返回时tooltip,可以完全覆盖此方法进行整个操作,但是当此方法返回后tooltip为shown时,这将需要setTimeout(fn, 0)可能导致不希望的闪烁效应.
对于这么简单的事情来说,这是过于苛刻,笨拙和冗长.
"清理",如不使用未记录的方法,也不使用属性,也不使用原型覆盖或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();
}
}
});
Run Code Online (Sandbox Code Playgroud)
请注意,content上面代码片段中的自定义函数删除了jQuery的默认HTML标记剥离(因为我喜欢在工具提示中使用HTML),但如果您使用用户输入的数据动态填充title属性,则可能会出现问题,以防万一你想保持原始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();
}
}
});
Run Code Online (Sandbox Code Playgroud)
我将在jQuery UI bugtracker上打开一张票,要求同时实现此功能.这是它:
| 归档时间: |
|
| 查看次数: |
7619 次 |
| 最近记录: |