Jak ukryć <opcję> w menu <select> za pomocą CSS?


104

Zdałem sobie sprawę, że wydaje się, że Chrome nie pozwoli mi ukryć się <option>w pliku <select>. Firefox to zrobi.

Muszę ukryć te, <option>które pasują do kryteriów wyszukiwania. W narzędziach internetowych Chrome widzę, że są one poprawnie ustawiane display: none;przez mój JavaScript, ale po <select>kliknięciu menu są wyświetlane.

Jak mogę sprawić, aby te, <option>które pasują do moich kryteriów wyszukiwania, NIE były wyświetlane po kliknięciu menu? Dzięki!


4
Zamiast się ukrywać i pokazywać podczas wyszukiwania. Spróbuj wypełnić pole wyboru w zależności od wyszukiwania
— Henesnarfel,

1
Zgadzam się z Henesnarfel. Jeśli już wyszukujesz lub wykonujesz jakieś zapytanie, powinieneś być w stanie po prostu wypełnić te, które chcesz.
— Michael Stramel

1
to działa dobrze dla mnie w Chrome 16.0.912.77 m. Czy źle rozumiem problem?
— mgibsonbr

3
@mgibsonbr To nie działa w różnych przeglądarkach.
— Jasper

3
@Henesnarfel Mogą być dobre powody, aby ukryć opcje. Na przykład miałem stronę z polem wyboru wyboru i łączami do ukrywania lub pokazywania elementów oznaczonych jako nieaktywne. Nie ma powodu, aby przechowywać wiele list lub wysyłać zapytania do serwera o nową listę za każdym razem, gdy użytkownik zmieni tę opcję.
— Ryan P

Odpowiedzi:


69

Musisz zaimplementować dwie metody ukrywania. display: nonedziała dla FF, ale nie Chrome czy IE. Więc drugą metodą jest zawijanie <option>w a <span>with display: none. FF tego nie zrobi (technicznie nieprawidłowy HTML, zgodnie ze specyfikacją), ale Chrome i IE to zrobią i ukryją opcję.

EDYCJA: O tak, już to zaimplementowałem w jQuery:

jQuery.fn.toggleOption = function( show ) {
    jQuery( this ).toggle( show );
    if( show ) {
        if( jQuery( this ).parent( 'span.toggleOption' ).length )
            jQuery( this ).unwrap( );
    } else {
        if( jQuery( this ).parent( 'span.toggleOption' ).length == 0 )
            jQuery( this ).wrap( '<span class="toggleOption" style="display: none;" />' );
    }
};

EDYCJA 2: Oto jak możesz użyć tej funkcji:

jQuery(selector).toggleOption(true); // show option
jQuery(selector).toggleOption(false); // hide option

EDYCJA 3: Dodano dodatkowe sprawdzenie sugerowane przez @ user1521986


1
Ta szalona metoda jest jedyną, która faktycznie działała całkowicie w różnych przeglądarkach i nie obejmowała tworzenia fałszywie ukrytego hackowania pola wyboru.
— Jesse Atkinson

15
Ostrożnie z tym. Na początku wydaje się działać świetnie, ale gdzieś po drodze się zatrzymuje. Oto małe demo: jsfiddle.net/Yb6sk/9
— Bill Criswell

17
Chociaż to rozwiązanie ukrywa element, każda próba odczytania wartości <select>(przy użyciu jQuery .val()) zwróci null. Właśnie przetestowałem to w Chrome 29, więc Googlersi uważajcie!
— Mark

10
Interesujący hack, ale radziłbym unikać „technicznie nieprawidłowego HTML”, jeśli to w ogóle możliwe.
— Łukasz

3
To prawda, że ​​wszystkie przeglądarki mają różne implementacje. Ale jednym z powodów, dla których przeglądarki nie mogą ściśle zaimplementować standardowych specyfikacji, jest to, że istnieje zbyt dużo aktywnego kodu, który nie jest zgodny ze specyfikacjami. IMO: Jeśli nie ma innych rozwiązań, zdecydowanie użyj hacka. Ale jeśli możesz postępować zgodnie ze specyfikacją i rozwiązać problem, dlaczego nie? Pomaga Twojemu kodowi grać dobrze z innymi i pomaga wzmocnić specyfikację.
— Łukasz

84

W przypadku HTML5 możesz użyć atrybutu „ukryty”.

<option hidden>Hidden option</option>

To jest nie obsługiwane przez IE <11. Ale jeśli potrzebujesz tylko ukryć kilka elementów, może byłoby lepiej po prostu ustawić atrybut ukryty w połączeniu z przyjaznym niepełnosprawnym w porównaniu do dodawania / usuwania elementów lub nie robi semantycznie poprawne konstrukcje.

<select>  
  <option>Option1</option>
  <option>Option2</option>
  <option hidden>Hidden Option</option>
</select>

Odniesienie .


4
IE 11 to obsługuje.
— Iván Pérez

7
Oto współczesna odpowiedź. W idealnym przypadku ustawiamy to również disabledtak, aby przeglądarki, które nie obsługują globalnego hiddenatrybutu HTML5 , miały pewne wizualne wskazania dla użytkownika.
— Cloudworks

1
Jak używasz tej techniki w CSS?
— GetFree

7
Nie działa w Safari, Edge ani IE. Błąd dla Safari ma 10 lat, prosimy o pomoc, aktualizując istniejące łatki. Nie można znaleźć błędu w narzędziu do śledzenia błędów Edge.
— Indolering

7
Istnieje obejście tego problemu <option hidden disabled>, więc ukrywa się we wszystkich dobrych przeglądarkach i wyłącza je w innych.
— Ramon Balthazar

37

Sugerowałbym, abyś nie korzystał z rozwiązań wykorzystujących rozszerzenie<span> opakowanie, ponieważ nie jest to prawidłowy HTML, co może powodować problemy w . Myślę, że preferowanym rozwiązaniem jest faktycznie usunięcie wszystkich opcji, które chcesz ukryć, i przywrócenie ich w razie potrzeby. Korzystając z jQuery, będziesz potrzebować tylko tych 3 funkcji:

Pierwsza funkcja zapisze oryginalną zawartość pliku zaznaczenia . Dla pewności możesz chcieć wywołać tę funkcję podczas ładowania strony.

function setOriginalSelect ($select) {
    if ($select.data("originalHTML") == undefined) {
        $select.data("originalHTML", $select.html());
    } // If it's already there, don't re-set it
}

Ta następna funkcja wywołuje powyższą funkcję, aby upewnić się, że oryginalna zawartość została zapisana, a następnie po prostu usuwa opcje z DOM.

function removeOptions ($select, $options) {
    setOriginalSelect($select);
    $options.remove();
 }

Ostatnia funkcja może być używana, gdy chcesz „zresetować” z powrotem do wszystkich oryginalnych opcji.

function restoreOptions ($select) {
    var ogHTML = $select.data("originalHTML");
    if (ogHTML != undefined) {
        $select.html(ogHTML);
    }
}

Zauważ, że wszystkie te funkcje oczekują, że przekazujesz elementy jQuery. Na przykład:

// in your search function...
var $s = $('select.someClass');
var $optionsThatDontMatchYourSearch= $s.find('options.someOtherClass');
restoreOptions($s); // Make sure you're working with a full deck
removeOptions($s, $optionsThatDontMatchYourSearch); // remove options not needed

Oto działający przykład: http://jsfiddle.net/9CYjy/23/


3
Niezawodny i niezawodny. Świetna odpowiedź!
— Jeremy Cook

1
@DanBeaulieu W poprzednim pliku jsfiddle była niepoprawnie nazwana funkcja. Naprawiłem i zaktualizowałem powyższy link. Dzięki, że to złapałeś.
— Łukasz

Tak, ten też był moim wyborem. Właściwie udało mi się nieco zmniejszyć kod, najpierw biorąc wartość danych do zmiennej, jeśli jest niezdefiniowana, zapisze opcje, w przeciwnym razie przywróci opcje. Moja potrzeba była specyficzna.
— diynevala

1
Musiałem dodać, var value=$select.val(); $select.html(ogHTML); $select.val(value);aby zachować wybraną wartość nawet po przywróceniu.
— diynevala

Cykl wybierania opcji do usunięcia i ich usuwania działał tylko jeden raz. Po tym, options.remove () nie przyniosło mi żadnego efektu. Po przeniesieniu opcji restoreOptions ($ s) wywołaj kilka wierszy, aby zawsze pracować z pełnym, świeżym obiektem Select, zadziałało.
— Newclique

18

Odpowiedź Ryana P powinna zostać zmieniona na:

    jQuery.fn.toggleOption = function (show) {
        $(this).toggle(show);
        if (show) {
            if ($(this).parent('span.toggleOption').length)
                $(this).unwrap();
        } else {
            **if ($(this).parent('span.toggleOption').length==0)**
                $(this).wrap('<span class="toggleOption" style="display: none;" />');
        }
    };

W przeciwnym razie zostanie opakowany w zbyt wiele tagów


5
Zwróć uwagę, że zgodnie ze specyfikacjami HTML ( w3.org/TR/html5/forms.html#the-select-element ) a <select>powinien zawierać tylko elementy obsługujące skrypty <option>lub <optgroup>lub. Dlatego należy unikać używania nieprawidłowych <span>opakowań.
— Łukasz

9

Funkcja toggleOption nie jest doskonała i wprowadziła nieprzyjemne błędy w mojej aplikacji. jQuery będzie mylony z .val () i .arraySerialize () Spróbuj wybrać opcje 4 i 5, aby zobaczyć, o co mi chodzi:

<select id="t">
<option value="v1">options 1</option>
<option value="v2">options 2</option>
<option value="v3" id="o3">options 3</option>
<option value="v4">options 4</option>
<option value="v5">options 5</option>
</select>
<script>
jQuery.fn.toggleOption = function( show ) {
    jQuery( this ).toggle( show );
    if( show ) {
        if( jQuery( this ).parent( 'span.toggleOption' ).length )
            jQuery( this ).unwrap( );
    } else {
        jQuery( this ).wrap( '<span class="toggleOption" style="display: none;" />' );
    }
};

$("#o3").toggleOption(false); 
$("#t").change(function(e) {
    if($(this).val() != this.value) {
    console.log("Error values not equal", this.value, $(this).val());
    }
});
</script>

8

W ten sposób wybieranie danych wejściowych jest trudne. A co z wyłączeniem go zamiast tego, zadziała to w różnych przeglądarkach:

$('select').children(':nth-child(even)').prop('disabled', true);

Spowoduje to wyłączenie wszystkich <option> elementów, ale możesz wybrać dowolny, który chcesz.

Oto demo: http://jsfiddle.net/jYWrH/

Uwaga: Jeśli chcesz usunąć wyłączoną właściwość elementu, możesz użyć .removeProp('disabled').

Aktualizacja

Możesz zapisać <option>elementy, które chcesz ukryć w ukrytym elemencie wyboru:

$('#visible').on('change', function () {
    $(this).children().eq(this.selectedIndex).appendTo('#hidden');
});

Następnie możesz dodać <option>elementy z powrotem do oryginalnego elementu select:

$('#hidden').children().appendTo('#visible');

W tych dwóch przykładach oczekuje się, że widoczny element select ma identyfikator, visiblea ukryty element select ma identyfikator hidden.

Oto demo: http://jsfiddle.net/jYWrH/1/

Zauważ, że .on()jest to nowość w jQuery 1.7, a użycie tej odpowiedzi jest takie samo, jak .bind(): http://api.jquery.com/on


7

Prosta odpowiedź: nie możesz. Elementy formy mają bardzo ograniczone możliwości stylizacji.

Najlepszą alternatywą byłoby ustawienie disabled=true opcji (i być może szarego koloru, ponieważ tylko IE robi to automatycznie), co spowoduje, że opcja będzie niemożliwa do kliknięcia.

Alternatywnie, jeśli możesz, całkowicie usuń optionelement.


6
// Simplest way

var originalContent = $('select').html();

$('select').change(function() {
    $('select').html(originalContent); //Restore Original Content
    $('select option[myfilter=1]').remove(); // Filter my options
});

4

Ponieważ używasz już JS, możesz utworzyć ukryty element SELECT na stronie i dla każdego elementu, który próbujesz ukryć na tej liście, przenieść go na listę ukrytą. W ten sposób można je łatwo przywrócić.

Nie znam sposobu na zrobienie tego w czystym CSS ... Myślałem, że display: żadna sztuczka by nie zadziałała.


2

!!! OSTRZEŻENIE !!!

Zamień drugie „JEŚLI” na „GDY” lub nie działa!

jQuery.fn.toggleOption = function( show ) {
    jQuery( this ).toggle( show );
    if( show ) {
        while( jQuery( this ).parent( 'span.toggleOption' ).length )
            jQuery( this ).unwrap( );
    } else {
        jQuery( this ).wrap( '<span class="toggleOption" style="display: none;" />' );
    }
};

2

Powinieneś je usunąć z <select>using JavaScript. To jedyny gwarantowany sposób, aby odejść.


1
Korzystając z jQuery, można to zrobić, usuwając:$('options').remove();
— Luke

2

ten wydaje się działać dla mnie w chrome

$("#selectid span option").unwrap();
$("#selectid option:not([filterattr=filtervalue])").wrap('<span/>');

1
Dodaj format kodu do swojego kodu, poprzez wcięcie 4 spacjami lub zawijanie kodu za pomocą `.
— Banan

1
ten kod jest świetny! działa na najnowszym chrome, firefox i IE 11, to mi wystarczy :)
— Sijav,

1
przed moim ostatnim komentarzem, ta rzecz działa również w IE 7! wiec ff 3.5 to na koniec wymyśliłem to jakoś na IE i chrome zachowują wybraną wartość zanim opcje zostaną ukryte i jeśli inna wartość nie zostanie ustawiona po przywróceniu opcji przeglądarka ustawi opcję wybrane jak poprzednio!
— Sijav

0

Spóźniona gra, ale większość z nich wydaje się dość skomplikowana.

Oto jak to zrobiłem:

var originalSelect = $('#select-2').html();

// filter select-2 on select-1 change
$('#select-1').change(function (e) {

    var selected = $(this).val();

    // reset select ready for filtering
    $('#select-2').html(originalCourseSelect);

    if (selected) {
        // filter
        $('#select-2 option').not('.t' + selected).remove();
    }

});

znaczniki select-1:

<select id='select-1'>
<option value=''>Please select</option>
<option value='1'>One</option>
<option value='2'>Two</option>
</select>

znaczniki select-2:

<select id='select-2'>
<option class='t1'>One</option>
<option class='t2'>Two</option>
<option>Always visible</option>
</select>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.