如何使用CSS隐藏<select>菜单中的<option>?


103

我已经意识到Chrome似乎不允许我隐藏<option>在中<select>。Firefox将会。

我需要隐藏<option>与搜索条件匹配的。在Chrome网络工具中,我可以看到display: none;我的JavaScript 正确设置了它们,但是一旦<select>单击菜单,它们就会显示出来。

<option>单击菜单时,如何显示不符合搜索条件的这些?谢谢!


4
而不是隐藏并在搜索中显示。尝试根据搜索结果填充选择内容
Henesnarfel

1
我同意Henesnarfel。如果您已经在进行搜索或某种查询,则应该可以只填充所需的内容。
Michael Stramel 2012年

1
这个工作正常,我在Chrome 16.0.912.77米 我误会这个问题了吗?
mgibsonbr

3
@mgibsonbr跨浏览器不起作用。
贾斯珀(Jasper)2012年

3
@Henesnarfel有充分的理由隐藏选项。例如,我有一个带有选择列表框和隐藏或显示标记为非活动的项目的链接的页面。用户更改该选项时,没有理由保留多个列表或向服务器查询新列表。
瑞安P

Answers:


69

您必须实现两种隐藏方法。display: none适用于FF,但不适用于Chrome或IE。因此,第二种方法是将with 包装在<option>中。FF不会这样做(按照规范,技术上无效的HTML),但是Chrome和IE会并且会隐藏该选项。<span>display: none

编辑:哦,是的,我已经在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
这种疯狂的方法是唯一真正可以完全跨浏览器工作且不涉及创建伪隐藏的选择框黑客的方法。
杰西·阿特金森

15
请注意这一点。乍一看似乎效果不错,但沿途却停了下来。这是一个小演示:jsfiddle.net/Yb6sk/9
Bill Criswell,

17
尽管此解决方案确实隐藏了元素,但任何尝试读取<select>(使用jQuery的.val())值的尝试都会返回null。我刚刚在Chrome 29中进行了测试,因此Google员工要当心!
标记

10
有趣的hack,但我建议尽可能避免使用“技术上无效的HTML”。
路加福音

3
的确,所有浏览器都有不同的实现。但是,浏览器不能严格执行标准规范的原因之一是,因为那里有太多不符合规范的实时代码。IMO:如果没有其他解决方案,那么一定要使用黑客手段。但是,如果您可以遵循规范解决问题,为什么不呢?它可以帮助您的代码与他人一起玩,并有助于加强规范。
路加福音

82

对于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支持此功能。
伊万·佩雷斯

7
这是现代答案。理想情况下,我们也将其设置为,disabled以便那些不支持HTML5全局hidden属性的浏览器为用户提供一些视觉指示。
cloudworks

1
如何在CSS中使用这种技术?
GetFree

7
在Safari,Edge或IE中均无法使用。 Safari的错误已有 10年之久,请通过更新现有补丁来提供帮助。在Edge问题跟踪器中找不到错误。
Indolering

7
一种解决方法是使用<option hidden disabled>,因此它会隐藏在所有好的浏览器中,并在其他浏览器上禁用它。
拉蒙·

37

我会建议你做使用使用该解决方案的<span>包装,因为它不是有效的HTML,这可能导致在路上的问题。我认为首选的解决方案是实际上删除您希望隐藏的所有选项,并根据需要还原它们。使用jQuery,您只需要以下3个功能:

第一个功能将保存select的原始内容。为了安全起见,您可能需要在加载页面时调用此函数。

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中有一个错误命名的函数。我修复并更新了上面的链接。感谢您抓住这一点。
2015年

是的,这也是我的选择。我实际上设法通过将数据值放入一个变量中来简化了代码,如果未定义,它将保存选项,否则将恢复选项。我的需求是特定的。
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),一个<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/

注意:如果要删除元素的Disabled属性,可以使用.removeProp('disabled')

更新资料

您可以将<option>要隐藏的元素保存在隐藏的select元素中:

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

然后,您可以将<option>元素添加回原始的select元素:

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

在这两个示例中,期望可见的select元素的ID为visible,而隐藏的select元素的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做到这一点的简易方法...我会以为display:none技巧就行了。


2

!!! 警告 !!!

用“ WHILE”替换第二个“ IF”,否则不起作用!

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,可以使用remove来完成:$('options').remove();
Luke

2

这个似乎对我有用

$("#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 2015年

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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.