隐藏许多选项时选择元素下拉菜单上的 Chrome 错误

Posted

技术标签:

【中文标题】隐藏许多选项时选择元素下拉菜单上的 Chrome 错误【英文标题】:Chrome bug on select element dropdown when many options are hidden 【发布时间】:2013-06-16 17:32:00 【问题描述】:

我正在为 Chrome 中的呈现错误寻找解决方法。当一个选择元素有大约 90%+ 的隐藏选项元素时,它就会显示出来。在 Chrome 中,下拉菜单的高度太短而无法使用。这似乎不会在其他浏览器上发生。 View example on jsFiddle.

html Example
Note: Some options were removed to keep the code brief.
The bug does not show up unless all options are present.

100 Options, 90% Hidden:<br>
<select>
<option value="">Select an Option</option>
<option value="0" style="display: none">Option 0</option>
<option value="1" style="display: none">Option 1</option>
<option value="2" style="display: none">Option 2</option>
<option value="3" style="display: none">Option 3</option>
<!-- Options removed for brevity. -->
<option value="86" style="display: none">Option 86</option>
<option value="87" style="display: none">Option 87</option>
<option value="88" style="display: none">Option 88</option>
<option value="89" style="display: none">Option 89</option>
<option value="90">Option 90</option>
<option value="91">Option 91</option>
<option value="92">Option 92</option>
<option value="93">Option 93</option>
<option value="94">Option 94</option>
<option value="95">Option 95</option>
<option value="96">Option 96</option>
<option value="97">Option 97</option>
<option value="98">Option 98</option>
<option value="99">Option 99</option>
</select>

经过测试的浏览器:

Chrome 27 和 28(失败) Firefox 21(通过) IE 9(通过) Opera 12(通过) Safari 5.1(通过)

View Example on jsFiddleAlternate Example Link

更新:我对该主题进行了一些阅读,显然选项不应该隐藏在选择中。您可以禁用选项,但它们不会消失。如果您根本不希望选项出现在选择中,则应该完全删除该节点。隐藏选项的功能似乎不能完全跨浏览器工作,在大多数情况下,您可以继续使用箭头键选择“隐藏”选项。我需要打开和关闭选项,这对我的特殊情况造成了不便,但这似乎是迄今为止唯一可行的方法。

【问题讨论】:

你发现了一个很好的错误! @frenchie 谢谢。我已经向 Google 报告了此问题,但同时我仍需要找到解决方法。 Chrome 28 在 Mac 上显示相同,它显示了所有隐藏的项目。 看起来这个 Chrome 错误已修复! 我认为这个错误又回到了 Chrome 78 中,我已经向 Google 提交了报告,这是一个新错误的 JS Fiddle(需要超过 100 个)jsfiddle.net/e7Lburzg 【参考方案1】:

添加它可能被视为一种解决方法:

 $(document).ready(function () 

    $('#ph2').mouseenter(function () 

      var html = '';

        $(this).find('option').each(function () 

            if ($(this).css('display') !== 'none') 

                html = html + '<option>' + $(this).text() + '</option>';   
            
        );

        $(this).html(html);
    )
);

这是jsFiddle;我使用 jquery 只是为了简单。在这种情况下,我只是在 mouseenter 上重做 HTML。这并不理想,但它可以让你走得更远。另外,请注意您已在 HTML 中将 ph2 设置为 div;我认为您应该从一开始就将其设置为选择元素,在小提琴上您可以看到我对 html 所做的更改。但总的来说,在修复错误之前,我认为这样的事情将尽可能接近你将获得的工作选项。

【讨论】:

+1 以获得有效修复。我需要能够切换选项,这样的修复并不能使事情变得容易。实际上,这似乎不是一个错误,而是更多未定义的功能。我更新了答案以包含此信息。 那么也许您可以将选项存储在键值对象中。在此对象中,您将跟踪切换可见的内容,然后在单击或 mouseenter 时使用该对象重做 HTML。在这里看看我的另一个答案:***.com/questions/17076429/… 用于对象模式。 这对我来说是第一次,但因为我也在更改页面上单独隐藏的值,所以“html”不存储任何可能选择的未来项目,任何想法我将如何解决这个问题? 然后将每个选项的状态存储在一个单独的对象中,并使用该对象来确定在重新生成元素时要在 HTML 中包含哪些选项。您可以使用 key:value ,其中 key 是选项,而 value 存储选项是否可见。请参阅我上面评论中的答案。【参考方案2】:

作为此错误的解决方法,我可以提出以下解决方案:

隐藏选项“转换”为其他标签并使用.hide() 隐藏它。 要显示一个选项,将其“转换”回option 并使用.show() 显示。

对于“转换”,我们需要这样的东西:https://***.com/a/9468280。

例子:

// some `replaceTagName` implementation here

// hiding options
$('.option-selector').replaceTagName('span').hide();

// showing options
$('.option-selector').replaceTagName('option').show();

有点重但工作:)

【讨论】:

【参考方案3】:

我遇到了这个问题,这就是我所做的:

var originalSelect = $("#the_select").clone();

function hideSomeOptions()
  $('#the_select .hide_me').remove();


function restoreAllOptions()
  $("#the_select").replaceWith(originalSelect[0]);

目标选择输入的 ID 为“the_select”,需要切换的选项或 optgroup 具有“hide_me”类。

【讨论】:

【参考方案4】:

除 Firefox 外,所有主流浏览器(Edge、Chrome、Opera 等)都存在此问题。 一旦隐藏项目的数量大于 1000,问题就会出现。 小心,因为只有 100 个项目,所有浏览器似乎都可以工作

如果活动项目(未隐藏,未禁用)位于列表顶部,问题也会消失。 更准确地说,当您单击“选择”输入字段时,浏览器会打开一个列表,其中的行数等于前 1000 个项目中包含的活动项目数。 例如,如果您构建一个项目列表,其中前 x 个项目处于活动状态,然后 y 个项目“不活动”(如果 y 大于 1000),然后再次 z 个项目处于活动状态,您将看到一个列表宽 x 行,其中包含 x+z 个项目.

顺便说一句,解决问题的方法可能是对项目列表进行排序

此行为已在 Chrome、Opera、Edge 上得到验证

【讨论】:

【参考方案5】:

我发现隐藏/可见选项的顺序有所不同。就像 chrome 在第一个隐藏选项处停止计算下拉菜单的高度一样。一种解决方法是将显示的选项移动到选择的顶部。如果您正在使用类似这样的 jquery。

var select = "select#MySelect";
$(select).children("option").hide();  //hide all options
$(select).children("Selector for items to show").each(function(idx, elm) 
           $(elm).parent().prepend(elm);  //move item to the top of parent
);
$(select).children("Selector for items to show").show(); //show selected options

【讨论】:

此解决方案没有解决您仍然可以使用键盘选择隐藏选项的问题。无论如何,这很容易修复:将 .prop("disabled":true) 添加到第二行。【参考方案6】:

我遇到了同样的问题(Chrome 40),发现以下解决方法对我很有效。

var originalOptions = [];

$(document).ready(function()
    originalOptions = $("yourSelect").children("option");

    $("someElement").someEvent(function()
        $("yourSelect").children("option").remove();
        $(originalOptions).each(function()
            if(/*criteria here*/)$("yourSelect").append($(this));
        );
    );
);

【讨论】:

一个选择也可能包含 optgroup 元素,而不仅仅是选项元素。【参考方案7】:

最好的解决办法是在最后一个末尾添加

&lt;option&gt;&lt;/option&gt; 在您的选择元素中。添加此代码:

&lt;optgroup&gt;&lt;/optgroup&gt;

这将添加一个空白组元素,目前是对这个罕见 BUG 的最佳简单快速修复。

谢谢!

【讨论】:

以上是关于隐藏许多选项时选择元素下拉菜单上的 Chrome 错误的主要内容,如果未能解决你的问题,请参考以下文章

在下拉菜单中隐藏选项

选择其他人时如何隐藏其他下拉菜单

制作下拉菜单(PopupList)

当第一个选择的项目框 1 更改时重置选项下拉菜单 2 mysql

从 ios 上的选择选项中隐藏/显示 div - 不工作

每个选项下拉项显示不同的内容