2012-10-29 15 views
5

Mam szybki zestaw jsFiddle, aby zademonstrować problem.Popouty i podpowiedzi w zakładkach na listbox Elementy opcji Listbox wyświetlane w niewłaściwym miejscu

Podczas korzystania z podpowiedzi lub popover z Bootstrap na elemencie opcji z listy select, popover lub tooltip nie pokazuje się obok elementu, ale raczej w skrajnym górnym lewym rogu strony.

HTML używam jest:

<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 wywołanie jest prosta:

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

Co mogę zrobić, aby pokazać się w odpowiednim miejscu?

+0

Co ciekawe, połączenie jsFiddle prawdopodobnie działa. Być może nowsza wersja naprawiła to? – SteveShaffer

Odpowiedz

15

To jest oczekiwane. TB tooltip/popover oblicza ich pozycję na podstawie powiązanych elementów offsetWidth i offsetHeight. Opcja nie ma takich właściwości, nigdy nie ma, więc popover zawsze kończy się na czymś w stosunku do gospodarstwa domowego body w lewo/górę.

Jednak można dodać popover dla dla samego . Bind mouseover dla zaznaczenia, z tego pokazuje popover w prawo wypełniony atrybutami danych dla ukrycia się option.

HTML, czyszczone rel="popover" i "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>​​ 

wiążą mouseover, zbierać opcji danych-attribues, pokaż popover

$("#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'); 
    } 
}); 

niektóre porządki więc popover znika, gdy wyjeżdżamy select

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

Nie sądzę, że można zrobić wiele zakładów ter dla listy opcji :) Ty może walczyć z template, zmuszając popover do mniej więcej podążać za pozycją pionową dla każdej opcji przez jej indeks.

rozwidlony kod http://jsfiddle.net/mM8sx/


Aktualizacja - problemy z IE i Chrome na oknach.
Widziałem kilka odniesień do tej odpowiedzi, wskazując, że nie działało w IE i Chrome w systemie Windows. Wynika to z faktu, że w przypadku okien, elementy <option> nie otrzymują wcale zdarzeń myszy. Oto "hack" powyższej odpowiedzi, co czyni go "crossbrowser".

Testy zakończone pomyślnie z Chrome, FF, IE i Safari w systemie Windows. Chrome, FF i Opera w systemie Ubuntu. Chodzi o to, aby celować w prawidłową kamerę <option> przy użyciu myszy (nie po najechaniu kursorem myszy), obliczając indeks na podstawie wartości myszy mouseevents clientY/height.

$("#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'); 
    } 
}); 

zobaczyć skrzypce na szczegóły ->http://jsfiddle.net/LfrPs/

+0

Twoje skrzypce działają zgodnie z przeznaczeniem, ale miałem następne pytanie. Co się stanie, jeśli nie chcę jawnie ustawić rozmiaru zaznaczenia? Jak więc mógłbym uzyskać popover z rozwijanym elementem select? – Sam

+1

@Sam, chciałbym rozwiązać to - niestety zdarzenie 'mouseover' dla' option' nie jest wyzwalane, gdy 'size' nie jest ustawione. Działa w FireFox, ale nie w Chrome ani Opera (nie testowałem IE), więc nie możesz określić, który popover musi być wyświetlony. – davidkonrad

+0

Świetne pomysły, ale wersja "mousemove" nie działa teraz niezawodnie w Firefoksie, a pozostałe nie działają w ogóle z wersją 3.x Bootstrapa, w moich testach. :( –

2

bardzo się starała, aby zastosować tę samą skrzynkę popover na liście rozwijanej bez powodzenia:

  1. Wygląda na to, że nie ma wydarzenie strzela w ogóle za elementy opcjonalne w rozwijanym menu wyboru.
  2. E.target zdarzenia "hover" na elemencie "select" będzie zawsze wybranym elementem! Nie ma sposobu, aby uzyskać odniesienie do znacznika "opcja", który jest ukryty.
  3. Próbowałem również owijać tekst w element "option" w element "span" i spróbować dodać detektor zdarzeń "hover" lub "mouseover" do tego elementu "span". To też nie działa.

Po zmianie listy rozwijanej (tj. Dodaniu rozmiaru = "xx") elementy opcjonalne mogą działać jak normalne elementy. Podejrzewam, że w rozwijanych polach wszystkie opcje są zawijane przez przeglądarkę do oddzielnej warstwy. Nie dopuszcza się interakcji z wewnętrznymi elementami wybranego elementu. Proszę mi powiedzieć, czy się mylę.