Twitter Bootstrap弹出窗口和Listbox选项元素的工具提示显示在错误的位置



我已经设置了一个快速的jsFiddle来演示这个问题。

在选择列表的选项元素上使用工具提示或Bootstrap的弹出窗口时,弹出窗口或工具提示不会显示在项目旁边,而是显示在页面的最左上角。

我使用的HTML是:

<select size="5" id="testList">
<option value="1" rel="popover" data-original-title="This is item 1." data-content="Lots of stuff to say" style="color: red; ">Item 1</option>
<option value="2" rel="popover" data-original-title="This is item 2." data-content="Lots of stuff to say" style="color: green; ">Item 2</option>
<option value="3" rel="popover" data-original-title="This is item 3." data-content="Lots of stuff to say" style="">Item 3</option>
<option value="4" rel="popover" data-original-title="Blah" data-content="Lots of stuff to say" style="color: orange; ">Item 4</option>
</select>​

javascript调用很简单:

$(function () {
$('#testList option[rel=popover]').popover({
placement: 'right',
trigger: 'hover'
});
});  ​

我该怎么做才能让它出现在正确的位置?

这是意料之中的事。TBtooltip/popover基于相关联的元素offsetWidthoffsetHeight来计算它们的位置。选项没有这样的属性,从来没有,所以popover总是会出现在相对于农场最左边/最上面的body的某个位置。

但是,您可以为select本身放置一个popover。为select绑定mouseover,从中显示右侧的popover,其中填充了悬停的option的数据属性。

HTML,为rel="popover""data-original-title"清理

<select size="4" id="testList">
<option value="1" data-title="This is item 1." data-content="Lots of stuff to say 1" style="color:red;">Item 1</option>
<option value="2" data-title="This is item 2." data-content="Lots of stuff to say 2" style="color:green;">Item 2</option>
<option value="3" data-title="This is item 3." data-content="Lots of stuff to say 3" style="">Item 3</option>
<option value="4" data-title="Blah" data-content="Lots of stuff to say 4" style="color:orange;">Item 4</option>
</select>​​

绑定鼠标悬停,收集选项数据属性,显示弹出

$("#testList").on('mouseover', function(e) {
var $e = $(e.target); 
if ($e.is('option')) {
$('#testList').popover('destroy');
$("#testList").popover({
trigger: 'manual',
placement: 'right',
title: $e.attr("data-title"),
content: $e.attr("data-content")
}).popover('show');
}
});

一些清理,这样当我们离开选择时弹出窗口就会消失

$("#testList").on('mouseleave', function(e) {
$('#testList').popover('destroy');
});

我不认为这对选项列表来说会更好:)你可能会template作斗争,迫使popover或多或少地按照每个选项的索引跟随垂直位置。

分叉代码http://jsfiddle.net/mM8sx/


更新-windows上的IE和Chrome问题
我看到一些关于这个答案的参考资料,指出它在IE和Chrome的windows中不起作用。这是因为在windows上,<option>元素根本不会接收鼠标事件。以下是对上述答案的"破解",使其成为"跨浏览器"。

在Windows上成功测试了Chrome、FF、IE和Safari。Ubuntu上的Chrome、FF和Opera。其想法是通过基于选项的mouseeventsclientY/height计算索引,在mousemove(而不是mouseover)上以正确的<option>为目标。

$("#testList").on('mousemove', function(e) {
if (!isWindows) {
var $e = $(e.target);
} else {
var newIndex = Math.floor(e.clientY/optionHeight);
if (newIndex === index) return;
index = newIndex;
$e = $(this).find('option:eq('+index+')');
}    
if ($e.is('option')) {
$('#testList').popover('destroy');
$("#testList").popover({
trigger: 'manual',
placement: 'right',
title: $e.attr("data-title"),
content: $e.attr("data-content")
}).popover('show');
}
});

有关详细信息,请参阅fiddle->http://jsfiddle.net/LfrPs/

很难将相同的弹出框应用到下拉框,但没有成功:

  1. 下拉选择中的选项元素似乎根本没有事件触发
  2. "select"元素上悬停事件的e.target将始终是select元素本身!您无法获得对悬停的"option"标记的引用
  3. 我还尝试将"option"元素中的文本包装到"span"元素中,并尝试将"hover"或"mouseover"事件侦听器添加到该"span'"元素中。这也不起作用

当将下拉列表更改为列表时(即添加size="xx"属性),选项元素可以作为普通元素工作。我怀疑在下拉框中,所有选项都被浏览器包装到一个单独的层中。不允许与select元素的内部元素进行交互。如果我错了,请告诉我。

最新更新