<select>仅显示所选选项的第一个字符

46

我有一个标准的下拉选择框,使用jQuery添加选项。但是在IE9中,只显示所选选项的第一个字符。显然,在FireFox和Chrome中它运作正常,但我必须支持IE9。我尝试了IE9兼容模式,但没有任何改善,对select或option应用样式也没有效果。

有人遇到过这个问题吗?是什么导致的?你是如何解决的?

IE9中的问题示例

简化的代码示例:

<select id="selectCCY" ValueColumn="ccyID" DisplayColumn="ccySymbol" ></select>



$.each(res.result, function (key, value) {  
    $('#selectCCY').append('<option value="' + value[$('#selectCCY').attr('ValueColumn')]+ '">' + value[$('#selectCCY').attr('DisplayColumn')] + '</option>');
});

res.result 是一个简单的 JSON 数组,格式如下:

[{"ccyID":1,"ccySymbol":"GBP"},{"ccyID":2,"ccySymbol":"AUD"},{"ccyID":3,"ccySymbol":"USD"}]

糟糕!在我简化的示例中它可以正常工作,问题一定出在其他地方。抱歉。原始代码太长太复杂了,无法粘贴到这里,但是我找到答案后会让你知道。

之后一段时间...

好了,我将问题缩小到了$(selector).each()循环内部的ajax调用上。该循环遍历所有选择框并异步填充选项。如果我将其更改为同步调用,则选择框的宽度和显示都正确,但如果是异步调用,则选择框仅显示第一个字符,如图所示。我还在努力解决这个问题,稍后再回复你。

我仍然想知道是什么原因导致选择框显示不正确。我可以采用解决方法来获得正确的显示效果,但这并不能回答我的问题。它只是一个带有选项的选择框,它应该总是能正常工作,对吗?

经过一个周末的忽略这个问题之后...

好了,我找到了一个解决方法。在进行ajax调用以填充选择框之前,我首先将其css display属性设置为“none”,然后填充它,最后当ajax调用和填充完成时,我只需删除css display 'none'属性即可。

所以我仍然不知道为什么IE不喜欢我,但至少我们有了一个解决方案。


4
叹气你用来填充‘select’框的标记或代码长什么样?” - T.J. Crowder
仅为完整起见:您的jQuery代码是什么? - slhck
你可以使用http://jsfiddle.net来设置你的代码演示。 - Russ Clarke
6
“您可以使用jsfiddle.net来设置代码演示。”但是如果您这样做,请确保在问题中同时发布实际的代码,而不仅仅是一个指向jsfiddle.net(或jsbin.com)的链接。 - T.J. Crowder
1
你可以尝试在IE9中异步调用后强制重新绘制UI - justkt
显示剩余4条评论
8个回答

24
在我的情况下,在ajax请求触发之前,我没有事件钩子来隐藏选择(select)元素,因此我不得不在此后强制重绘选择(select)元素。重新应用现有的宽度似乎可以解决问题:
$("select").width($("select").width());

这对我解决了问题,但在我的情况下引入了另一个问题:这将把选择项的样式属性设置为太短的宽度。我猜测这行代码是在 CSS 宽度设置运行之前运行的,因为这个 js 行设置了内联样式,所以它会覆盖 CSS。 - jyoungdev
这个 bug 真是太蠢了。这个答案让我找到了解决方案,但我不得不像这样做两次:$("#mydropdown").width($("select").width()); $("#mydropdown").width(300); - Adam Levitt
谢谢您。我不得不使用$('select').css('width', 0).css('width', '').hide().show()来使IE9正确更新一个选择多个选项的情况,其中选项会动态地被AngularJS删除和添加。 - cebru
这对我有用,我的选择选项“发布日期”在页面加载时显示为“发布”,因此我在页面加载时重置了Js中的选择框宽度,然后它起作用了。 - Sanjeev

17

这是一个仅在IE浏览器中出现的问题。首先将下拉框的CSS display属性设置为“none”,然后通过你的Ajax调用填充它,最后当Ajax调用完成且下拉框被填充后,移除下拉框的CSS display属性“none”。


3
你得爱上IE浏览器,因为它有很多小怪癖,让网页开发变得更加“有趣”。 - Spudley

11

根据Jim的回答,我将下拉列表传递给这个方法:

// force redraw to get around bug in IE.
// NOTE that this removes width from the style attribute.
function forceRedraw(jqueryObject) {
    jqueryObject.css('width', 0);
    jqueryObject.css('width', '');  // remove from style tag
}

这样可以解决IE中的错误,并且在元素方法被调用之前保留元素的宽度,只要该宽度是在CSS中指定而不是在style属性中。


3

我正在使用AngularJS,在IE8 / IE9中也遇到了此问题。这种方法/解决方法适用于我: 例如,HTML看起来像这样:

<select ng-show="data.showSelect" ng-cloak ng-model="data.model" ng-options="l.id as l.name for l in data.items></select>

我有这段代码在下拉数据加载后运行,并修复了问题。
$timeout(function(){$scope.data.showSelect = true;},100);

如果网站上有多个区域需要这种解决方法,你也可以将其封装成指令。


1

我的情况中有回调函数,因此在填充过程中将显示设置为无法选项对我来说不是一个选择。然而,我能够详细说明@Daniel Brinks的答案以解决我的问题。事实证明,一旦添加任何项目并将显示从无更改为无,所有未来添加的项目都将正常运行。使用jquery和小部件。因此,如果您正在尝试修复IE中的小部件,则可能对您有用。

在小部件的_create函数中:

this.availableFields = $("<select multiple='multiple' name='AvailableFields'></select>")
                                .addClass("ui-fieldselector-available-select")
                                .css("display", "none")
                                .appendTo( this.element );

在小部件的_init函数中:
buildAvailableItem - 添加到选择器中
然后添加到一个数组中,以跟踪小部件的状态。
var $this = this;
                //IE HACK Part 1--
                $this.buildAvailableItem("Loading...", "Loading..." );
                $this.availableList.push("Loading...");
                //----------------
    //do stuff, here I initialize some functionality, like drag and drop, add click events, etc.
                //IE HACK Part 2--
                $($this.availableFields).css("display", "");
                $this.removeAvailableOption("Loading...");
                //----------------
    // AJAX adding

我通常使用一个名为addAvailableItem的函数来处理构建项目并将其添加到列表中,但这也会触发一个事件,而我不希望“正在加载...”项目触发事件。
如果由于某种原因有人使用非常慢的浏览器,他们将在ajax项目被添加之前看到“正在加载...”。
如果有人想要更多的复制和粘贴友好版本,请让我知道。
供参考,这是构建项目的代码:
buildAvailableItem: function (display, value)
        {
            $("<option>" + display + "</option>").val(value).appendTo(this.availableFields);
        },

1
在angular.js的selectDirective的render函数中,**以下位置(用粗体标记)添加几行代码**对我很有效。除了修补angularJS或下面给出的forEach之外,我正在寻找是否有其他可能的解决方案?
if (existingOption.label !== option.label) {
  lastElement.text(existingOption.label = option.label);
  **lastElement.attr('label', existingOption.label);**
}

并且

  (element = optionTemplate.clone())
      .val(option.id)
      .attr('selected', option.selected)
      .text(option.label);
  **element.attr('label', option.label);**

问题出在HTMLOptionElement的label属性如果在IE中为空,则与text属性不同。可以通过在屏幕加载后添加以下代码,查看FF和IE的Web控制台以查看差异来验证此问题。如果取消注释标签设置为文本的最后一行,则可以正常工作。或者按上述方式修复angular.js。
// This is an IE fix for not updating the section of dropdowns which has ng-options with filters
angular.forEach($("select"), function (currSelect) {
    console.log("1.text ", currSelect.options[currSelect.selectedIndex].text);
    console.log("1.label ", currSelect.options[currSelect.selectedIndex].label);
    //console.log("1.innerHTML ", currSelect.options[currSelect.selectedIndex].innerHTML);
    //console.log("1.textContent ", currSelect.options[currSelect.selectedIndex].textContent);
    //console.log("1.cN.data ", currSelect.options[currSelect.selectedIndex].childNodes[0].data);
    //console.log("1.cN.nodeValue ", currSelect.options[currSelect.selectedIndex].childNodes[0].nodeValue);
    //console.log("1.cN.textContent ", currSelect.options[currSelect.selectedIndex].childNodes[0].textContent);
    //console.log("1.cN.wholeText ", currSelect.options[currSelect.selectedIndex].childNodes[0].wholeText);
    //console.log("1. ", currSelect.options[currSelect.selectedIndex], "\n");

    //currSelect.options[currSelect.selectedIndex].label = "xyz";
    //currSelect.options[currSelect.selectedIndex].label = currSelect.options[currSelect.selectedIndex].text;
});

0
这是另一种只使用 CSS 的解决方案:
您可以使用 ch 来设置选择宽度,它会考虑到字符数。请参见此示例,它会产生下面的图像(在 Chrome v99 中测试)。
select {
    max-width: 2ch;
    padding-right: 24px;
    box-sizing: content-box;
}

也许你需要根据你的字体调整 2ch2.2ch 或者其他数值。

enter image description here


0

我刚刚通过更改选择元素的初始化方式(在 jQuery 小部件中动态创建)来解决了相同的问题。

示例 A

这种方法不起作用:

var select = $('<select size=7>') // IE9 'first character' bug

这个做:

var select = $('<select>').attr('size', 7) // Yay

示例 B

同样,以下内容不起作用:

self.element.append('<select name="mySelect">'); // IE9 'first character' bug

而这将会:

var mySelect = $('<select>').attr('name', 'mySelect');
self.element.append(mySelect);

结论

我很想解释上面的内容,但恐怕我不能。不过,这可能会使人们避免不必要地向他们的代码添加一堆CSS hack。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接