如何隐藏<选项>在 <选择> 中带有 CSS 的菜单?

发布于 2025-01-04 16:02:05 字数 323 浏览 0 评论 0 原文

我意识到 Chrome 似乎不允许我在

我需要隐藏与搜索条件匹配的 。在 Chrome 网络工具中,我可以看到它们被我的 JavaScript 正确设置为 display: none;,但是一旦单击

如何使这些与我的搜索条件匹配的 在单击菜单时不显示?

I've realized that Chrome, it seems, will not allow me to hide <option> in a <select>. Firefox will.

I need to hide the <option>s that match a search criteria. In the Chrome web tools I can see that they are correctly being set to display: none; by my JavaScript, but once then <select> menu is clicked they are shown.

How can I make these <option>s that match my search criteria NOT show when the menu is clicked?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

何以畏孤独 2025-01-11 16:02:05

对于 HTML5,您可以使用“隐藏”属性。

<option hidden>Hidden option</option>

IE支持它 11. 但如果您只需要隐藏几个元素,与添加/删除元素或不进行语义上正确的构造相比,将隐藏属性与禁用结合起来设置可能会更好。

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

参考

For HTML5, you can use the 'hidden' attribute.

<option hidden>Hidden option</option>

It is not supported by IE < 11. But if you need only to hide a few elements, maybe it would be better to just set the hidden attribute in combination with disabled in comparison to adding/removing elements or doing not semantically correct constructions.

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

Reference.

遗忘曾经 2025-01-11 16:02:05

您必须实现两种隐藏方法。 display: none 适用于 FF,但不适用于 Chrome 或 IE。因此,第二种方法是将 包装在 中,并使用 display: none。 FF 不会这样做(根据规范,技术上无效的 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 建议的额外检查

You have to implement two methods for hiding. display: none works for FF, but not Chrome or IE. So the second method is wrapping the <option> in a <span> with display: none. FF won't do it (technically invalid HTML, per the spec) but Chrome and IE will and it will hide the option.

EDIT: Oh yeah, I already implemented this in 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: Here's how you would use this function:

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

EDIT 3: Added extra check suggested by @user1521986

星光不落少年眉 2025-01-11 16:02:05

我建议您不要使用使用 包装器的解决方案,因为它不是有效的 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/

I would suggest that you do not use the solutions that use a <span> wrapper because it isn't valid HTML, which could cause problems down the road. I think the preferred solution is to actually remove any options that you wish to hide, and restore them as needed. Using jQuery, you'll only need these 3 functions:

The first function will save the original contents of the select. Just to be safe, you may want to call this function when you load the page.

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

This next function calls the above function to ensure that the original contents have been saved, and then simply removes the options from the DOM.

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

The last function can be used whenever you want to "reset" back to all the original options.

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

Note that all these functions expect that you're passing in jQuery elements. For example:

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

Here is a working example: http://jsfiddle.net/9CYjy/23/

笑看君怀她人 2025-01-11 16:02:05

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

否则它会被太多标签包裹

Ryan P's answer should be changed to:

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

Otherwise it gets wrapped in too many tags

北城半夏 2025-01-11 16:02:05

通过这种方式选择输入是很棘手的。禁用它怎么样,这将跨浏览器工作:

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

这将禁用所有其他 元素,但您可以选择您想要的任何一个。

这是一个演示: http://jsfiddle.net/jYWrH/

注意:如果你想删除禁用的您可以使用 .removeProp('disabled') 元素的属性。

更新

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

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

然后您可以将 元素添加回原始 select 元素:

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

在这两个示例中,预计可见选择元素的 id 为 visible,隐藏选择元素的 id 为 hidden

这是一个演示: http://jsfiddle.net/jYWrH/1/

请注意 .on() 是 jQuery 1.7 中的新功能,此答案的用法与 .bind() 相同:http://api.jquery.com/on

Select inputs are tricky in this way. What about disabling it instead, this will work cross-browser:

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

This will disable every-other <option> element, but you can select which ever one you want.

Here is a demo: http://jsfiddle.net/jYWrH/

Note: If you want to remove the disabled property of an element you can use .removeProp('disabled').

Update

You could save the <option> elements you want to hide in hidden select element:

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

You can then add the <option> elements back to the original select element:

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

In these two examples it's expected that the visible select element has the id of visible and the hidden select element has the id of hidden.

Here is a demo: http://jsfiddle.net/jYWrH/1/

Note that .on() is new in jQuery 1.7 and in the usage for this answer is the same as .bind(): http://api.jquery.com/on

荆棘i 2025-01-11 16:02:05

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>

The toggleOption function is not perfect and introduced nasty bugs in my application. jQuery will get confused with .val() and .arraySerialize()
Try to select options 4 and 5 to see what I mean:

<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>
划一舟意中人 2025-01-11 16:02:05

简单的回答:你不能。表单元素的样式功能非常有限。

最好的替代方法是在选项上设置 disabled=true (可能是灰色,因为只有 IE 会自动执行此操作),这将使该选项不可点击。

或者,如果可以的话,完全删除 option 元素。

Simple answer: You can't. Form elements have very limited styling capabilities.

The best alternative would be to set disabled=true on the option (and maybe a gray colour, since only IE does that automatically), and this will make the option unclickable.

Alternatively, if you can, completely remove the option element.

粉红×色少女 2025-01-11 16:02:05
// Simplest way

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

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

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

$('select').change(function() {
    $('select').html(originalContent); //Restore Original Content
    $('select option[myfilter=1]').remove(); // Filter my options
});
听风念你 2025-01-11 16:02:05

只需使用 option[value=your-value]{display:none;}

这在 Chrome 中运行良好,至少在 2022 年如此,在 safari 和 FF 中也是如此。

Simply use option[value=your-value]{display:none;}

This works fine in Chrome, at least in 2022, as well as in safari and FF.

流殇 2025-01-11 16:02:05

由于您已经在使用 JS,因此您可以在页面上创建一个隐藏的 SELECT 元素,并且对于您尝试隐藏在该列表中的每个项目,将其移至隐藏列表。这样,它们就可以轻松恢复。

我不知道用纯 CSS 做这件事的方法...我本以为 display:none 技巧会起作用。

Since you're already using JS, you could create a hidden SELECT element on the page, and for each item you are trying to hide in that list, move it to the hidden list. This way, they can be easily restored.

I don't know a way offhand of doing it in pure CSS... I would have thought that the display:none trick would have worked.

年华零落成诗 2025-01-11 16:02:05

您应该使用 JavaScript 从

You should remove them from the <select> using JavaScript. That is the only guaranteed way to make them go away.

落在眉间の轻吻 2025-01-11 16:02:05

!!!警告 !!!

将第二个“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;" />' );
    }
};

!!! WARNING !!!

Replace the second "IF" by "WHILE" or doesn't work !

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;" />' );
    }
};
我要还你自由 2025-01-11 16:02:05

这个似乎对我在 Chrome 中有用

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

this one seems to work for me in chrome

$("#selectid span option").unwrap();
$("#selectid option:not([filterattr=filtervalue])").wrap('<span/>');
花间憩 2025-01-11 16:02:05

现代解决方案是简单地应用隐藏的CSS,例如:

<option value="" style="display:none;">Select Item</option>

使用类注释,添加CSS,例如

<option value="" class="hidden">Please select</option>

或者在类案例中

.hidden {
  display: none;
}

Modern solution is simply apply CSS hidden like:

<option value="" style="display:none;">Select Item</option>

Or with a class

<option value="" class="hidden">Please select</option>

Note in class case, add css like

.hidden {
  display: none;
}
℡寂寞咖啡 2025-01-11 16:02:05

游戏虽然迟到了,但其中大多数看起来都相当复杂。

我是这样做的:

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>

Late to the game, but most of these seem quite complicated.

Here's how I did it:

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

});

markup of select-1:

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

markup of select-2:

<select id='select-2'>
<option class='t1'>One</option>
<option class='t2'>Two</option>
<option>Always visible</option>
</select>
多孤肩上扛 2025-01-11 16:02:05

简单来说,这也可以通过HTML来实现。

<select>
    <option value="" disabled selected hidden>Please Choose</option>
    <option value="0">hii</option>
    <option value="1">hello</option>
</select>

Simply, this can achieved by HTML too.

<select>
    <option value="" disabled selected hidden>Please Choose</option>
    <option value="0">hii</option>
    <option value="1">hello</option>
</select>

维持三分热 2025-01-11 16:02:05

2022 答案摘要和跨浏览器解决方案

目前,这些方法不适用于 Safari:

  • 可见性:隐藏
  • 显示:阻止
  • 隐藏属性

因此,这里使用这些方法提出的解决方案都不起作用在 Safari 上,所以它们不能被接受。

解决方案

解决方案是将特殊选项保留在数组中,并按需隐藏/恢复它们。例如,要根据年/月选择显示/隐藏日期选择:

当您初始化组件时:

const tailDayOptions = [];

  const saveTailDayOptions = () => {
    const daySelector = document.querySelector('#daySelector');
    for (let day = 29; day <= 31; day++) {
      tailDayOptions[day - 1] = daySelector.querySelector(`option[value='${day - 1}']`);
    }
  }

当用户更改年份或月份时:

for (let day = 29; day <= 31; day++) {
      if (day <= daysInMonth) {
        daySelector.appendChild(tailDayOptions[day - 1])
      } else {
        const dayOption = daySelector.querySelector(`option[value='${day - 1}']`);
        if (dayOption) {
          daySelector.removeChild(dayOption);
        }
      }
    }

它是如何工作的

  1. 它保存第 29,30 和 31 天的选项到 tailDayOptions 数组
  2. 当用户更改年份或月份时,计算 daysInMonth
  3. 如果给定的年月中不存在给定的日期(例如 29 日)并且它在选择选项中可用,则将从那里删除
  4. 如果给定的日期可用在给定的年份月份中,它会重新添加到 tailDayOptions 数组中的选择

兼容性

与 Firefox、Chrome 和 Safari 兼容。应与所有其他浏览器兼容。

2022 Answer Summary And Cross-Browser Solution

Currently, these methods do not work on Safari:

  • visibility: hidden
  • display: block
  • hidden attribute

So none of proposed solutions here using these methods works on Safari, so they can not be accepted.

Solution

The solution is to keep special options in an array, and hide/restore them on-demand. For example to show/hide day selection based on year/month selection:

When you initialize your component:

const tailDayOptions = [];

  const saveTailDayOptions = () => {
    const daySelector = document.querySelector('#daySelector');
    for (let day = 29; day <= 31; day++) {
      tailDayOptions[day - 1] = daySelector.querySelector(`option[value='${day - 1}']`);
    }
  }

When a user changes year or month:

for (let day = 29; day <= 31; day++) {
      if (day <= daysInMonth) {
        daySelector.appendChild(tailDayOptions[day - 1])
      } else {
        const dayOption = daySelector.querySelector(`option[value='${day - 1}']`);
        if (dayOption) {
          daySelector.removeChild(dayOption);
        }
      }
    }

How does it work

  1. It saves options for day 29,30 and 31 to a tailDayOptions array
  2. When user changes the year or month, daysInMonth are calculated
  3. If a given day (e.g. 29th) is not present in a given year-month and it is available in the select options, it gets removed from there
  4. If a given day is available in a given year-month it gets re-added to the select from the tailDayOptions array

Compatibility

Compatible with Firefox, Chrome and Safari. Should be compatible with all other browsers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文