Як приховати <option> в меню <select> за допомогою CSS?


103

Я зрозумів, що Chrome, здається, не дозволить мені сховатися <option>в <select>. Firefox буде.

Мені потрібно приховати <option>s, які відповідають критеріям пошуку. У веб-інструментах Chrome я бачу, що вони правильно встановлені display: none;моїм JavaScript, але після <select>натискання меню вони відображаються.

Як я можу зробити так, щоб ці <option>елементи, які відповідають моїм критеріям пошуку, НЕ відображалися при натисканні меню? Дякую!


4
Замість того, щоб ховатися і показувати на обшук. Спробуйте та
заповніть

1
Я погоджуюся з Хенеснарфелем. Якщо ви вже здійснюєте пошук або якийсь запит, ви зможете просто заповнити потрібні.
Майкл Страмель

1
це добре працює для мене в Chrome 16.0.912.77 м. Я нерозумію проблему?
mgibsonbr

3
@mgibsonbr Це не працює між браузером.
Джаспер

3
@Henesnarfel Можуть бути вагомі причини приховувати варіанти. Наприклад, у мене була сторінка із списком вибору та посиланнями, щоб приховати чи показати елементи, позначені як неактивні. Немає причин зберігати кілька списків або запитувати сервер на новий список, коли користувач змінює цю опцію.
Ryan P

Відповіді:


69

Ви повинні реалізувати два способи приховування. display: noneпрацює для FF, але не для Chrome або IE. Отже другий метод - загортання <option>в <span>с display: none. FF цього не зробить (технічно недійсний HTML за специфікацією), але Chrome і IE будуть і приховати варіант.

EDIT: О так, я вже реалізував це в 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;" />' );
    }
};

EDIT 2: Ось як ви використовуєте цю функцію:

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

EDIT 3: Додано додатковий чек, запропонований @ user1521986


1
Цей божевільний метод єдиний, який фактично працював повністю крос-браузером і не передбачав створення фальшиво-прихованого вибору вікна вибору.
Джессі Аткінсон

15
Будьте обережні з цим. Спочатку, здається, працює чудово, але десь уздовж лінії він зупиняється. Ось трохи демонстрації: jsfiddle.net/Yb6sk/9
Білл

17
Хоча це рішення приховує елемент, будь-яка спроба зчитувати значення <select>(за допомогою jQuery's .val()) повернеться null. Я щойно тестував це в Chrome 29, тому Google пильнуйте!
Марк

10
Цікавий хак, але я б рекомендував уникати "технічно недійсного HTML", якщо це можливо.
Лука

3
Правда, у всіх браузерах є різні реалізації. Але одна з причин браузерів не може чітко реалізовувати стандартні характеристики, тому що там занадто багато живого коду, який не слідує за специфікаціями. IMO: Якщо інших рішень немає, то, будь-ласка, використовуйте хак. Але якщо ви можете дотримуватися специфікації і вирішити свою проблему, чому б вам це не зробити? Це допомагає вашому коду грати добре з іншими та зміцнює характеристики.
Лука

82

Для HTML5 ви можете використовувати атрибут "прихований".

<option hidden>Hidden option</option>

Він не підтримується IE <11. Але якщо вам потрібно лише приховати декілька елементів, можливо, було б краще просто встановити прихований атрибут у поєднанні з відключеним порівняно з додаванням / видаленням елементів або виконанням несемантично правильних конструкцій.

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

Довідково .


4
IE 11 підтримує це.
Іван Перес

7
Це сучасна відповідь. В ідеалі ми також встановлюємо це disabledтак, щоб ті веб-переглядачі, які не підтримують глобальний hiddenатрибут HTML5 , матимуть певну візуальну індикацію для користувача.
хмарні роботи

1
Як ви використовуєте цю техніку з CSS?
GetFree

7
Не працює в Safari, Edge та IE. Помилка для Safari 10 років, будь ласка, допоможіть, оновивши існуючі патчі. Не вдається знайти помилку в програмі випуску Edge.
Індолінг

7
Для вирішення цього питання використовується <option hidden disabled>, тому він ховається у всіх хороших браузерах і вимикає його для інших.
Рамон Бальтазар

37

Я б запропонував не використовувати рішення, які використовують <span>обгортку, оскільки це недійсний HTML, що може спричинити проблеми в дорозі. Я думаю, що кращим рішенням є фактично видалити всі параметри, які ви хочете приховати, та відновити їх у міру необхідності. Використовуючи jQuery, вам знадобляться лише ці 3 функції:

Перша функція збереже початковий вміст вибору . Щоб забезпечити безпеку, ви, можливо, захочете зателефонувати до цієї функції під час завантаження сторінки.

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

Наступна функція викликає вищевказану функцію, щоб гарантувати збереження вихідного вмісту, а потім просто видаляє параметри з DOM.

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

Останню функцію можна використовувати, коли ви хочете повернутись до всіх початкових параметрів.

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

Зауважте, що всі ці функції очікують, що ви переходите в елементи jQuery. Наприклад:

// 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

Ось робочий приклад: http://jsfiddle.net/9CYjy/23/


3
Надійний і не злом. Чудова відповідь!
Джеремі Кук

1
@DanBeaulieu У попередній jsfiddle була неправильно названа функція. Я виправив та оновив посилання вище. Дякуємо, що це зробили.
Лука

Так, це був і мій вибір. Мені реально вдалося розіграти код трохи менше, спочатку взявши значення даних у змінну, якщо не визначено, це збереже параметри, інакше відновить параметри. Моя потреба була специфічною для таких.
діневала

1
Довелося додати var value=$select.val(); $select.html(ogHTML); $select.val(value);вибране значення навіть після відновлення.
діневала

Цикл вибору варіантів їх видалення та видалення спрацював лише один раз. Після цього Options.remove () не вплинув на мене. Як тільки я перемістив виклик RestoOptions ($ s) на кілька рядків, щоб я завжди працював з повним свіжим об'єктом Select, він працював.
Newclique

18

Відповідь Райана П слід змінити на:

    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;" />');
        }
    };

В іншому випадку він загортається в занадто багато тегів


5
Зверніть увагу , що в відповідно до HTML специфікації ( w3.org/TR/html5/forms.html#the-select-element ), A <select>повинен містити тільки <option>або <optgroup>або сценарії підтримуючих елементів. Тож вам слід уникати використання недійсних <span>обгортки.
Лука

9

Функція toggleOption не є ідеальною і ввела в мою програму неприємні помилки. jQuery плутається з .val () та .arraySerialize () Спробуйте вибрати варіанти 4 та 5, щоб побачити, що я маю на увазі:

<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

Вибір входів складний таким чином. А як відключити її замість цього, це буде працювати крос-браузер:

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

Це дозволить відключити всі інші <option>елементи, але ви можете вибрати, який саме ви хочете.

Ось демонстрація: http://jsfiddle.net/jYWrH/

Примітка. Якщо ви хочете видалити відключене властивість елемента, який ви можете використовувати .removeProp('disabled').

Оновлення

Ви можете зберегти <option>елементи, які ви хочете приховати в прихованому виділеному елементі:

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

Потім ви можете додати <option>елементи до початкового елемента вибору:

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

У цих двох прикладах очікується, що видимий елемент вибору має ідентифікатор, visibleа прихований елемент вибору має ідентифікатор hidden.

Ось демонстрація: http://jsfiddle.net/jYWrH/1/

Зауважте, що .on()у jQuery 1.7 є новим, а використання для цієї відповіді те саме, що .bind(): http://api.jquery.com/on


7

Проста відповідь: Ви не можете. Елементи форми мають дуже обмежені можливості стилізації.

Найкращою альтернативою було б встановити disabled=trueпараметр (а може бути і сірий колір, оскільки тільки IE робить це автоматично), і це зробить варіант нерозбірливим.

Або, якщо можете, повністю видаліть optionелемент.


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

Оскільки ви вже використовуєте JS, ви можете створити прихований елемент SELECT на сторінці, а для кожного елемента, який ви намагаєтесь сховати у цьому списку, перемістіть його до прихованого списку. Таким чином їх можна легко відновити.

Я не знаю, як це зробити в чистому CSS ... Я б подумав, що дисплей: жоден трюк не спрацював би.


2

!!! УВАГА !!!

Замініть друге "АБО" на "КОЛИ" або не працює!

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

Вам слід видалити їх із <select>використання JavaScript. Це єдиний гарантований спосіб змусити їх піти.


1
Використовуючи jQuery, це можна зробити з видаленням:$('options').remove();
Люк

2

цей, здається, працює для мене в хромі

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

1
Будь ласка, додайте формат коду до свого коду, відступаючи 4 пробілами або обертаючи код ".
Банан

1
цей код чудовий! він працює на останніх хромах, firefox та IE 11, це досить добре для мене :)
Sijav,

1
до мого останнього коментаря ця річ працює і на IE 7! так ff 3.5, це те, що я придумав нарешті, він якось на IE і chrome зберігає значення, вибране перед тим, як параметри приховані, і якщо інше значення не встановлено після повернення браузера параметрів, встановить параметр вибрано як раніше!
Сіяв

0

Пізно до гри, але більшість із них здаються досить складними.

Ось як я це зробив:

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

});

розмітка вибору-1:

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

розмітка вибору-2:

<select id='select-2'>
<option class='t1'>One</option>
<option class='t2'>Two</option>
<option>Always visible</option>
</select>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.