2013-03-12 4 views
8

Я не могу вычислить смещение позиции опциона в отборном:Хром смещение() возвращает нулевые значения для опции

<select multiple="true"> 
    <option>asdf</option> 
    <option id="bar">qwer</option> 
</select> 

$("#bar").offset() 

Chrome возвращает (любые версии JQuery, как 1.7.2, 1.9 тестировались):

{top: 0, left: 0} 

FF возвращается:

{top: 26, left: 9} 

мне нужны позиции, как FF возвращается. Есть ли способ обхода Chrome?

http://jsfiddle.net/YrRLx/

+0

[Это] (http://stackoverflow.com/a/4240492/1427942) может быть полезным. Я не знаю, но, возможно, нет смещения для элементов 'option' в хроме. – Eich

+0

Не могли бы вы рассказать немного больше о том, какая идея может возникнуть из-за другого подхода, не связанного с '.offset()' – kidwon

+0

- это смещение выбора недостаточно хорошо? – Huangism

ответ

2

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; 
} 
+0

Хорошее решение на мой взгляд, но я полагаю, что это зависит от требований совместимости (мобильные устройства), если это действительно действительное решение. – JakeJ

+0

А, очень хорошая точка. Он должен работать на мобильных устройствах, но он не будет запускать собственный пользовательский интерфейс устройства. Вы можете выполнить этот код в зависимости от содержимого строки заголовка USER_AGENT. Возможно, я могу помочь вам, если вы скажете мне, почему вам нужно смещение опций в первую очередь. – haejeong87

+0

Я добавил второе возможное решение после принятия рекомендаций Хуангизма. Это может быть полезно для вас. – haejeong87

0

Я бы сказал, что хром возвращает 0 из-за опцию не видно, поэтому он не может рассчитывать на вершину. Это может произойти и в сафари, так как это все браузеры webkit. Единственное, о чем я могу думать, это получить верхнюю часть смещения, а затем выполнить некоторые вычисления, чтобы получить приблизительный верхний параметр. Например, если параметр имеет размер около 10 пикселей в высоту, вам нужно знать, сколько опций перед тем, что вы хотите, и определить, сколько пикселей вам нужно добавить в верхнюю часть выбора.

+0

Это все еще странно. В режиме multi-select параметры на самом деле видны ... – haejeong87