2013-03-12 12 views
8

non riesco a calcolare la posizione di offset di un'opzione all'interno di un prescelto:di Chrome offset() restituisce i valori nulli per l'opzione

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

$("#bar").offset() 

Chrome ritorna (qualsiasi versione di jQuery come 1.7.2, 1.9 testato):

{top: 0, left: 0} 

FF rendimenti:

{top: 26, left: 9} 

ho bisogno le posizioni come rendimenti FF. C'è una soluzione alternativa per Chrome?

http://jsfiddle.net/YrRLx/

+0

[Questo] (http://stackoverflow.com/a/4240492/1427942) potrebbe essere utile. Non lo so, ma forse non c'è alcun offset per gli elementi 'option' in chrome. – Eich

+0

Puoi dirci qualcosa di più su quale è l'idea che alcuni di noi potrebbero escogitare un altro approccio che non implica '.offset()' – kidwon

+0

l'offset della selezione non è abbastanza buono? – Huangism

risposta

2

Ah ... una soluzione che posso pensare sta sostituendo la selezione con ul oggetto, e allegare i gestori di eventi alla sincronizzazione selezionare su ul. Chiamare .offset() su elementi li funziona come previsto su FF e Chrome.

Quindi, se si fa clic sugli elementi li, verrà aggiornato il colore di sfondo e verrà aggiornato il valore selezionato della selezione nascosta. In questo modo, quando viene inviato il modulo, viene inviato il valore corretto.

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())); 
}); 

a cura

Quindi, ho provato un altro metodo seguendo il suggerimento di Huangism usando offset() e scrollTop() dell'elemento select.

L'unica cosa che non è disponibile è l'altezza dell'elemento opzione. Così ho cercato di stimare l'uso della dimensione del font, ma non era perfetto, e ho dovuto aggiungere magic number 3 su Chrome per ottenere gli offset esatti. Se riesci a capire l'altezza dell'elemento opzionale, non devi occuparti di tutti gli affari ul/li sopra.

Eccolo:

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

Bella soluzione secondo me, ma suppongo che dipenda dai requisiti di compatibilità (dispositivi mobili) se questa è effettivamente una soluzione valida – JakeJ

+0

Ah, ottimo punto. Dovrebbe funzionare su dispositivi mobili, ma non attiverà l'interfaccia utente nativa del dispositivo. Puoi eseguire questo codice in base al contenuto della stringa di intestazione USER_AGENT. Forse posso aiutarti ulteriormente se mi dici perché hai bisogno dell'offset delle opzioni in primo luogo. – haejeong87

+0

Ho aggiunto una seconda soluzione possibile dopo aver preso il consiglio di Huangism. Potrebbe essere utile per te. – haejeong87

0

direi che Chrome restituisce 0 causa l'opzione non è visibile in modo che non può calcolare la parte superiore. Questo potrebbe accadere anche in Safari poiché sono tutti i browser Webkit. L'unica cosa che posso pensare è ottenere l'offset superiore della selezione e poi fare alcuni calcoli per ottenere un massimo approssimativo dell'opzione. Ad esempio, se un'opzione è di circa 10px in altezza, devi sapere quante opzioni ci sono prima di quella desiderata e calcolare quanti pixel devi aggiungere alla parte superiore selezionata.

+0

È ancora strano, però. Nella selezione multipla, le opzioni sono effettivamente visibili ... – haejeong87

Problemi correlati