จะซ่อน <option> ในเมนู <select> ด้วย CSS ได้อย่างไร?


104

ฉันรู้ว่า Chrome ดูเหมือนจะไม่ยอมให้ฉันซ่อนตัว<option>ในไฟล์<select>. Firefox จะ

ฉันต้องการซ่อน<option>s ที่ตรงกับเกณฑ์การค้นหา ในเครื่องมือเว็บ Chrome ฉันจะเห็นว่าพวกเขาจะได้อย่างถูกต้องถูกตั้งค่าให้display: none;โดย JavaScript ของฉัน แต่ครั้งเดียวแล้ว<select>เมนูที่มีการคลิกที่พวกเขาจะแสดงให้เห็นว่า

ฉันจะทำให้สิ่งเหล่านี้<option>ตรงกับเกณฑ์การค้นหาของฉันไม่แสดงเมื่อคลิกเมนูได้อย่างไร ขอบคุณ!


4
แทนที่จะซ่อนและแสดงในการค้นหา ลองเติมข้อมูลที่เลือกขึ้นอยู่กับการค้นหา
Henesnarfel

1
ฉันเห็นด้วยกับ Henesnarfel หากคุณกำลังทำการค้นหาหรือแบบสอบถามบางประเภทอยู่แล้วคุณควรจะเติมข้อมูลที่คุณต้องการได้
Michael Stramel

1
ใช้งานได้ดีสำหรับฉันใน Chrome 16.0.912.77 ม. ฉันเข้าใจปัญหาผิดหรือเปล่า?
mgibsonbr

3
@mgibsonbr มันไม่ทำงานข้ามเบราว์เซอร์
Jasper

3
@Henesnarfel อาจมีเหตุผลที่ดีในการซ่อนตัวเลือก ตัวอย่างเช่นฉันมีหน้าที่มีช่องรายการและลิงก์สำหรับซ่อนหรือแสดงรายการที่ทำเครื่องหมายว่าไม่ใช้งาน ไม่มีเหตุผลที่จะเก็บหลายรายการหรือสอบถามเซิร์ฟเวอร์สำหรับรายการใหม่เมื่อใดก็ตามที่ผู้ใช้เปลี่ยนตัวเลือกนั้น
Ryan P

คำตอบ:


69

คุณต้องใช้สองวิธีในการซ่อน display: noneใช้งานได้กับ FF แต่ไม่ใช่ Chrome หรือ IE ดังนั้นวิธีที่สองคือการตัด<option>ในด้วย<span> display: noneFF จะไม่ทำ (HTML ไม่ถูกต้องทางเทคนิคตามข้อมูลจำเพาะ) แต่ Chrome และ IE จะซ่อนตัวเลือกไว้

แก้ไข: ใช่ฉันติดตั้งสิ่งนี้ใน 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;" />' );
    }
};

แก้ไข 2: นี่คือวิธีที่คุณจะใช้ฟังก์ชันนี้:

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

แก้ไข 3: เพิ่มการตรวจสอบพิเศษที่แนะนำโดย @ user1521986


1
วิธีการที่บ้าคลั่งนี้เป็นวิธีเดียวที่ทำงานข้ามเบราว์เซอร์ได้อย่างสมบูรณ์และไม่เกี่ยวข้องกับการสร้างแฮ็กกล่องเลือกที่ซ่อนไว้
Jesse Atkinson

15
ระวังเรื่องนี้ด้วย ดูเหมือนว่าจะใช้งานได้ดีในตอนแรก แต่บางแห่งก็หยุดตามแนวเส้น นี่คือตัวอย่างเล็ก ๆ น้อย ๆ : jsfiddle.net/Yb6sk/9
Bill Criswell

17
แม้ว่าวิธีนี้จะซ่อนองค์ประกอบพยายามใด ๆ ที่จะอ่านค่าของ<select>(ใช้ของ jQuery .val()) nullจะกลับมา ฉันเพิ่งทดสอบสิ่งนี้ใน Chrome 29 ดังนั้น Googler โปรดระวัง!
ทำเครื่องหมาย

10
การแฮ็กที่น่าสนใจ แต่ฉันขอแนะนำให้หลีกเลี่ยง "HTML ที่ไม่ถูกต้องในทางเทคนิค" หากเป็นไปได้
Luke

3
จริงอยู่เบราว์เซอร์ทั้งหมดมีการใช้งานที่แตกต่างกัน แต่เหตุผลหนึ่งที่เบราว์เซอร์ไม่สามารถใช้ข้อกำหนดมาตรฐานได้อย่างเคร่งครัดเนื่องจากมีโค้ดสดมากเกินไปที่ไม่เป็นไปตามข้อกำหนด IMO: หากไม่มีวิธีแก้ปัญหาอื่นให้ใช้แฮ็ค แต่ถ้าคุณสามารถทำตามข้อกำหนดและแก้ปัญหาของคุณทำไมคุณจะไม่? ช่วยให้โค้ดของคุณเล่นได้ดีกับผู้อื่นและช่วยเสริมสร้างสเป็ค
Luke

84

สำหรับ HTML5 คุณสามารถใช้แอตทริบิวต์ "hidden" ได้

<option hidden>Hidden option</option>

มันเป็นเรื่องที่ไม่ได้รับการสนับสนุนจาก IE < 11. แต่ถ้าคุณต้องการเพียงที่จะซ่อนองค์ประกอบไม่กี่บางทีมันอาจจะดีกว่าที่จะเพียงแค่ตั้งค่าแอตทริบิวต์ที่ซ่อนอยู่ในการรวมกันกับคนพิการในการเปรียบเทียบกับการเพิ่ม / ลบองค์ประกอบหรือทำการก่อสร้างไม่ถูกต้องความหมาย

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

ข้อมูลอ้างอิง .


4
IE 11 รองรับสิ่งนี้
IvánPérez

7
นี่คือคำตอบที่ทันสมัย ตามหลักการแล้วเรายังตั้งค่านี้เพื่อdisabledให้เบราว์เซอร์ที่ไม่รองรับแอตทริบิวต์ส่วนกลาง HTML5hiddenจะมีตัวบ่งชี้ภาพสำหรับผู้ใช้
cloudworks

1
คุณใช้เทคนิคนี้กับ CSS อย่างไร?
ฟรี

7
ไม่ทำงานใน Safari, Edge หรือ IE Bug for Safariมีอายุ 10 ปีโปรดช่วยอัปเดตแพตช์ที่มีอยู่ ไม่พบข้อผิดพลาดในตัวติดตามปัญหา Edge
Indolering

7
วิธีแก้ปัญหาสำหรับสิ่งนี้คือการใช้<option hidden disabled>ดังนั้นจึงซ่อนอยู่ในเบราว์เซอร์ที่ดีทั้งหมดและปิดใช้งานในเบราว์เซอร์อื่น ๆ
Ramon Balthazar

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
เชื่อถือได้และไม่แฮ็ค ตอบโจทย์มาก!
Jeremy Cook

1
@DanBeaulieu มีฟังก์ชันที่ตั้งชื่อไม่ถูกต้องใน jsfiddle ก่อนหน้านี้ ฉันแก้ไขและอัปเดตลิงก์ด้านบนแล้ว ขอบคุณที่จับได้
ลุค

ใช่อันนี้ก็เป็นทางเลือกของฉันเช่นกัน จริงๆแล้วฉันจัดการโค้ดให้เล็กลงเล็กน้อยโดยนำค่าข้อมูลไปเป็นตัวแปรก่อนหากไม่ได้กำหนดมันจะบันทึกตัวเลือกมิฉะนั้นจะเรียกคืนตัวเลือก ความต้องการของฉันมีความเฉพาะเจาะจงสำหรับสิ่งนั้น
diynevala

1
ฉันต้องเพิ่มvar value=$select.val(); $select.html(ogHTML); $select.val(value);เพื่อให้เลือกค่าที่เลือกไว้แม้ว่าจะกู้คืนแล้วก็ตาม
diynevala

วงจรของการเลือกตัวเลือกเพื่อลบและลบออกใช้งานได้เพียงครั้งเดียว หลังจากนั้น options.remove () ก็ไม่มีผลกับฉัน เมื่อฉันย้ายการเรียกคืน restoreOptions ($ s) ขึ้นมาสองสามบรรทัดเพื่อให้ฉันทำงานกับวัตถุ Select ใหม่ทั้งหมดได้เสมอมันก็ใช้งานได้
Newclique

18

คำตอบของ Ryan P ควรเปลี่ยนเป็น:

    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>Wrapper ที่ไม่ถูกต้อง
Luke

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');

ในสองตัวอย่างนี้คาดว่าองค์ประกอบ Select ที่มองเห็นได้มีรหัสvisibleและองค์ประกอบการเลือกที่ซ่อนอยู่มี id ของ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

!!! คำเตือน !!!

แทนที่ "IF" ที่สองด้วย "WHILE" หรือไม่ทำงาน!

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

อันนี้ดูเหมือนจะใช้ได้กับฉันใน Chrome

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

1
โปรดเพิ่มรูปแบบรหัสให้กับรหัสของคุณไม่ว่าจะโดยการเยื้องด้วยช่องว่าง 4 ช่องหรือห่อรหัสของคุณด้วย ".
กล้วย

1
รหัสนี้ดีมาก! มันใช้งานได้กับ chrome, firefox และ IE 11 ล่าสุดซึ่งดีพอสำหรับฉัน :)
Sijav

1
ก่อนที่จะแสดงความคิดเห็นล่าสุดสิ่งนี้ใช้ได้กับ IE 7 ด้วย! ดังนั้น ff 3.5 นี่คือสิ่งที่ฉันคิดขึ้นมาในที่สุดมันยังไงก็ตามบน IE และ chrome จะรักษาค่าที่เลือกไว้ก่อนที่ตัวเลือกจะถูกซ่อนและหากไม่ได้ตั้งค่าอื่นหลังจากนำตัวเลือกกลับมาเบราว์เซอร์จะตั้งค่าตัวเลือก เลือกไว้ก่อน!
Sijav

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

});

มาร์กอัปของ select-1:

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

มาร์กอัปของ select-2:

<select id='select-2'>
<option class='t1'>One</option>
<option class='t2'>Two</option>
<option>Always visible</option>
</select>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.