Làm cách nào để ẩn <option> trong menu <select> bằng CSS?


103

Tôi nhận ra rằng có vẻ như Chrome sẽ không cho phép tôi ẩn nấp <option>trong <select>. Firefox sẽ.

Tôi cần ẩn các <option>s phù hợp với tiêu chí tìm kiếm. Trong các công cụ web của Chrome, tôi có thể thấy rằng chúng đang được đặt chính xác display: none;bởi JavaScript của tôi, nhưng khi <select>menu được nhấp vào, chúng sẽ được hiển thị.

Làm cách nào để làm cho những thứ này <option>phù hợp với tiêu chí tìm kiếm của tôi KHÔNG hiển thị khi nhấp vào menu? Cảm ơn!


4
Thay vì ẩn và hiện khi tìm kiếm. Hãy thử và cư trú trong chọn tùy thuộc vào việc tìm kiếm
Henesnarfel

1
Tôi đồng ý với Henesnarfel. Nếu bạn đang thực hiện một tìm kiếm hoặc một số loại truy vấn, bạn có thể chỉ điền những thứ bạn muốn.
Michael Stramel

1
điều này hoạt động tốt đối với tôi trong Chrome 16.0.912.77 m. Tôi đang hiểu sai vấn đề?
mgibsonbr

3
@mgibsonbr Nó không hoạt động trên nhiều trình duyệt.
Jasper

3
@Henesnarfel Có thể có lý do chính đáng để ẩn các tùy chọn. Ví dụ: tôi có một trang có hộp danh sách chọn lọc và các liên kết để ẩn hoặc hiển thị các mục được đánh dấu là không hoạt động. Không có lý do gì để giữ nhiều danh sách hoặc truy vấn máy chủ cho một danh sách mới bất cứ khi nào người dùng thay đổi tùy chọn đó.
Ryan P

Câu trả lời:


69

Bạn phải thực hiện hai phương pháp để ẩn. display: nonehoạt động cho FF, nhưng không hoạt động cho Chrome hoặc IE. Vì vậy, phương pháp thứ hai là gói <option>trong a <span>với display: none. FF sẽ không làm điều đó (HTML không hợp lệ về mặt kỹ thuật, theo thông số kỹ thuật) nhưng Chrome và IE thì có và nó sẽ ẩn tùy chọn.

CHỈNH SỬA: Ồ đúng rồi, tôi đã triển khai điều này trong 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;" />' );
    }
};

CHỈNH SỬA 2: Đây là cách bạn sẽ sử dụng chức năng này:

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

CHỈNH SỬA 3: Đã thêm kiểm tra bổ sung do @ user1521986 đề xuất


1
Phương pháp điên rồ này là phương pháp duy nhất thực sự hoạt động hoàn toàn trên nhiều trình duyệt và không liên quan đến việc tạo ra một vụ hack hộp chọn ẩn.
Jesse Atkinson

15
Hãy cẩn thận với điều này. Nó có vẻ hoạt động tốt lúc đầu nhưng ở đâu đó dọc theo dòng nó dừng lại. Dưới đây là một chút giới thiệu: jsfiddle.net/Yb6sk/9
Bill Criswell

17
Mặc dù giải pháp này ẩn phần tử, bất kỳ nỗ lực nào để đọc giá trị của <select>(sử dụng jQuery's .val()) sẽ trả về null. Tôi vừa thử nghiệm điều này trong Chrome 29, vì vậy nhân viên của Google hãy cẩn thận!
Đánh dấu

10
Việc hack thú vị, nhưng tôi khuyên bạn nên tránh "HTML không hợp lệ về mặt kỹ thuật" nếu có thể.
Luke

3
Đúng, tất cả các trình duyệt đều có các cách triển khai khác nhau. Nhưng một lý do khiến các trình duyệt không thể thực hiện nghiêm ngặt các thông số kỹ thuật tiêu chuẩn là vì có quá nhiều mã trực tiếp không tuân theo thông số kỹ thuật. IMO: Nếu không có giải pháp nào khác, thì bằng mọi cách hãy sử dụng hack. Nhưng nếu bạn có thể làm theo thông số kỹ thuật giải quyết vấn đề của mình, tại sao bạn lại không? Nó giúp mã của bạn chơi tốt với người khác và giúp củng cố thông số kỹ thuật.
Luke

82

Đối với HTML5, bạn có thể sử dụng thuộc tính 'hidden'.

<option hidden>Hidden option</option>

không được IE hỗ trợ.

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

Tham khảo .


4
IE 11 hỗ trợ điều này.
Iván Pérez

7
Đây là câu trả lời hiện đại. Lý tưởng nhất là chúng tôi cũng đang thiết lập cài đặt này để disablednhững trình duyệt không hỗ trợ thuộc tính toàn cục HTML5hidden sẽ có một số chỉ dẫn trực quan cho người dùng.
cloudworks

1
Làm thế nào để bạn sử dụng kỹ thuật này với CSS?
GetFree

7
Không hoạt động trong Safari, Edge hoặc IE. Lỗi dành cho Safari đã 10 tuổi, vui lòng trợ giúp bằng cách cập nhật các bản vá hiện có. Không thể tìm thấy lỗi trong trình theo dõi sự cố Edge.
Indolering

7
Một giải pháp cho điều này là sử dụng <option hidden disabled>, vì vậy nó ẩn trong tất cả các trình duyệt tốt và vô hiệu hóa nó trên các trình duyệt khác.
Ramon Balthazar

37

Tôi khuyên bạn không nên sử dụng các giải pháp sử dụng <span>trình bao bọc vì nó không phải là HTML hợp lệ, điều này có thể gây ra sự cố. Tôi nghĩ rằng giải pháp ưa thích là thực sự loại bỏ bất kỳ tùy chọn nào bạn muốn ẩn và khôi phục chúng nếu cần. Sử dụng jQuery, bạn sẽ chỉ cần 3 chức năng sau:

Chức năng đầu tiên sẽ lưu nội dung ban đầu của vùng chọn . Để an toàn, bạn có thể muốn gọi hàm này khi tải trang.

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

Hàm tiếp theo này gọi hàm trên để đảm bảo rằng nội dung gốc đã được lưu và sau đó chỉ cần xóa các tùy chọn khỏi DOM.

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

Chức năng cuối cùng có thể được sử dụng bất cứ khi nào bạn muốn "thiết lập lại" trở lại tất cả các tùy chọn ban đầu.

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

Lưu ý rằng tất cả các hàm này mong đợi rằng bạn đang truyền các phần tử jQuery. Ví dụ:

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

Đây là một ví dụ hoạt động: http://jsfiddle.net/9CYjy/23/


3
Đáng tin cậy và không phải là một hack. Câu trả lời chính xác!
Jeremy Cook,

1
@DanBeaulieu Có một hàm được đặt tên không chính xác trong jsfiddle trước đó. Tôi đã sửa và cập nhật liên kết trên. Cảm ơn vì đã nắm bắt được điều đó.
Luke

Vâng, cái này cũng là sự lựa chọn của tôi. Tôi thực sự quản lý để đánh gôn mã nhỏ hơn một chút, bằng cách đầu tiên lấy giá trị dữ liệu vào một biến, nếu không xác định, nó sẽ lưu các tùy chọn, nếu không, nó sẽ khôi phục các tùy chọn. Nhu cầu của tôi là cụ thể cho như vậy.
diynevala

1
Tôi đã phải thêm var value=$select.val(); $select.html(ogHTML); $select.val(value);để giữ giá trị đã chọn được chọn ngay cả sau khi khôi phục.
diynevala

Chu trình chọn các tùy chọn để loại bỏ và loại bỏ chúng chỉ hoạt động một lần. Sau đó, options.remove () không có tác dụng đối với tôi. Khi tôi di chuyển lệnh gọi restoreOptions ($ s) lên một vài dòng để tôi luôn làm việc với đối tượng Select mới, đầy đủ, nó đã hoạt động.
Newclique

18

Câu trả lời của Ryan P nên được đổi thành:

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

Nếu không, nó được bọc trong quá nhiều thẻ


5
Lưu ý rằng theo thông số kỹ thuật HTML ( w3.org/TR/html5/forms.html#the-select-element ), a <select>chỉ nên chứa <option>hoặc <optgroup>hoặc các phần tử hỗ trợ tập lệnh. Vì vậy, bạn nên tránh sử dụng các <span>trình bao bọc không hợp lệ .
Luke

9

Chức năng toggleOption không hoàn hảo và có nhiều lỗi khó chịu trong ứng dụng của tôi. jQuery sẽ bị nhầm lẫn với .val () và .arraySerialize () Hãy thử chọn tùy chọn 4 và 5 để xem tôi muốn nói gì:

<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

Theo cách này, lựa chọn đầu vào rất phức tạp. Còn về việc vô hiệu hóa nó thay vào đó, điều này sẽ hoạt động trên nhiều trình duyệt:

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

Điều này sẽ vô hiệu hóa mọi <option>phần tử khác , nhưng bạn có thể chọn bất kỳ phần tử nào bạn muốn.

Đây là bản demo: http://jsfiddle.net/jYWrH/

Lưu ý: Nếu bạn muốn xóa thuộc tính bị vô hiệu hóa của một phần tử, bạn có thể sử dụng .removeProp('disabled').

Cập nhật

Bạn có thể lưu các <option>phần tử bạn muốn ẩn trong phần tử chọn ẩn:

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

Sau đó, bạn có thể thêm các <option>phần tử trở lại phần tử chọn ban đầu:

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

Trong hai ví dụ này, phần tử chọn hiển thị có id là visiblevà phần tử chọn ẩn có id là hidden.

Đây là bản demo: http://jsfiddle.net/jYWrH/1/

Lưu ý rằng tính năng .on()mới trong jQuery 1.7 và cách sử dụng cho câu trả lời này cũng giống như .bind(): http://api.jquery.com/on


7

Câu trả lời đơn giản: Bạn không thể. Các phần tử biểu mẫu có khả năng tạo kiểu rất hạn chế.

Cách thay thế tốt nhất là đặt disabled=truetrên tùy chọn (và có thể là màu xám, vì chỉ IE làm điều đó tự động) và điều này sẽ làm cho tùy chọn không thể nhấp được.

Ngoài ra, nếu bạn có thể, hãy xóa hoàn toàn optionphần tử.


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

Vì bạn đã sử dụng JS nên bạn có thể tạo phần tử CHỌN ẩn trên trang và đối với mỗi mục bạn đang cố ẩn trong danh sách đó, hãy di chuyển nó vào danh sách ẩn. Bằng cách này, chúng có thể được khôi phục dễ dàng.

Tôi không biết cách thực hiện nó trong CSS thuần túy ... Tôi đã nghĩ rằng màn hình hiển thị: không có thủ thuật nào có hiệu quả.


2

!!! CẢNH BÁO !!!

Thay thế "IF" thứ hai bằng "WHILE" hoặc không hoạt động!

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

Bạn nên xóa chúng khỏi <select>JavaScript bằng cách sử dụng. Đó là cách đảm bảo duy nhất để khiến chúng biến mất.


1
Sử dụng jQuery, điều này có thể được thực hiện với loại bỏ:$('options').remove();
Luke

2

cái này có vẻ phù hợp với tôi trong chrome

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

1
Vui lòng thêm định dạng mã vào mã của bạn, bằng cách thụt lề với 4 dấu cách hoặc bọc mã của bạn bằng dấu `.
Banana

1
mã này là tuyệt vời! nó hoạt động trên chrome mới nhất, firefox và IE 11, đó là đủ tốt cho tôi :)
Sijav

1
trước nhận xét cuối cùng của tôi, điều này cũng hoạt động trên IE 7! vì vậy ff 3.5, đây là những gì tôi nghĩ ra cuối cùng, bằng cách nào đó trên IE và chrome giữ nguyên giá trị đã được chọn trước khi các tùy chọn bị ẩn và nếu một giá trị khác không được đặt sau khi đưa trở lại tùy chọn, trình duyệt sẽ đặt tùy chọn đã chọn như trước đây!
Sijav

0

Cuối game, nhưng hầu hết trong số này có vẻ khá phức tạp.

Đây là cách tôi đã làm điều đó:

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

});

đánh dấu lựa chọn-1:

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

đánh dấu của lựa chọn-2:

<select id='select-2'>
<option class='t1'>One</option>
<option class='t2'>Two</option>
<option>Always visible</option>
</select>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.