Ah ... одно решение, о котором я могу думать, заключается в замене выбора на объект ul и привязка обработчиков событий для синхронизации к ul. Вызов .offset() на элементах li работает как ожидалось как на FF, так и на Chrome.
Итак, если вы нажмете элементы li, он обновит свой цвет фона и обновит выбранное значение скрытого выбора. Таким образом, когда форма отправляется, отправляется правильное значение.
http://jsfiddle.net/hqYqh/
HTML:
<select id="mySelect" multiple="true">
<option>2011</option>
<option>2012</option>
<option>2013</option>
<option>2014</option>
<option>2015</option>
<option>2016</option>
<option>2017</option>
<option>2018</option>
<option>2019</option>
</select>
CSS:
ul.select {
display: inline-block;
border: 1px solid black;
list-style: none;
margin: 0;
padding: 2px;
height: 80px;
overflow: auto;
width: 50px;
}
ul.select li {
background-color: none;
cursor: pointer;
}
ul.select li.selected {
background-color: skyblue;
}
JS:
var $select = $('#mySelect');
var $ul = $('<ul class="select">').on('click', 'li', function() {
$(this).parent().find('li').removeClass('selected');
$(this).addClass('selected');
$select.val($(this).text()).change();
});
$select.find('option').each(function() {
var $li = $('<li>').text($(this).text());
$ul.append($li);
});
$select.hide().after($ul);
$select.change(function() {
alert('Offset of ' + $(this).val() + ' is ' + JSON.stringify($('li.selected').offset()));
});
EDITED
Итак, я попробовал другой метод после предложения Huangism, используя offset() и scrollTop() элемента select.
Единственное, что недоступно, это высота элемента опции. Поэтому я попытался оценить размер шрифта, но он был не идеальным, и мне пришлось добавить волшебный номер 3 в Chrome, чтобы получить точные смещения. Если вы можете определить высоту элемента option, вам не нужно иметь дело со всем бизнесом ul/li выше.
Здесь:
http://jsfiddle.net/hqYqh/2/
optionOffset = function($option) {
var i = $option.index();
var h = Number($option.css('font-size').replace(/px/, '')) + 3; // Cannot get the height of the option element :(
var $select = $option.parent();
var offset = $select.offset();
offset.top += i*h - $select.scrollTop();
return offset;
}
[Это] (http://stackoverflow.com/a/4240492/1427942) может быть полезным. Я не знаю, но, возможно, нет смещения для элементов 'option' в хроме. – Eich
Не могли бы вы рассказать немного больше о том, какая идея может возникнуть из-за другого подхода, не связанного с '.offset()' – kidwon
- это смещение выбора недостаточно хорошо? – Huangism