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

时间:2011-05-06 08:02:36

标签: jquery html internet-explorer internet-explorer-9

我有一个标准的选择框,我通过附加选项使用jquery填充,但由于某种原因,IE9只显示所选选项的第一个字符。不用说它在FireFox和Chrome中完美运行,但我必须支持IE9。我尝试了IE9兼容模式,但没有区别,也没有选择或选项的样式。

之前有没有人见过这个问题。是什么造成的?你是怎么解决的?

Example of problem in 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"}]

OH BUGGER !!!它在我的简化示例中工作正常,因此问题出在其他地方。抱歉。原始代码在这里要粘贴很长很复杂,但是当我找到答案时会通知您。

一段时间后......

好的,我把问题归结为$(选择器).each()循环中的ajax调用。循环遍历所有选择框并异步填充选项。如果我进行同步调用,则选择框具有正确的宽度并正确显示,但如果是异步调用,则选择框仅显示图像中的第一个字符。仍在努力,将再次回到你身边。

我仍然想知道什么会导致选择框显示不正确。我可以做变通办法并让它正确显示,但这不能回答这个问题。它只是一个带有选项的选项,它应该始终正常工作,对吗?

在周末无视这个问题之后......

对,我找到了解决方法。在执行ajax调用以填充选择框之前,我首先将css显示属性设置为'none',然后填充它,最后当ajax调用和填充完成时,我只删除css display'none'属性。

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

7 个答案:

答案 0 :(得分:24)

在我的情况下,我没有在ajax请求触发之前隐藏select的事件挂钩,所以我不得不在事后强制重绘select元素。重新应用现有宽度似乎有效:

$("select").width($("select").width());

答案 1 :(得分:17)

这是IE唯一的问题。首先将选择框上的css显示属性设置为'none',然后通过ajax调用填充它,最后当ajax调用完成并填充选择框时,删除选择框上的css display'none'属性

答案 2 :(得分: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中指定了宽度,而不是在样式属性中指定了,就会将元素的宽度留在方法被调用之前。< / p>

答案 3 :(得分: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);

如果您在网站上有多个需要此解决方法的区域,我想您也可以将其包装成指令。

答案 4 :(得分:1)

在我的情况下我有回调,所以在填充时将显示设置为none对我来说不是一个选项,但是,我能够详细说明@Daniel Brinks的答案来解决我的问题..一旦任何项目是添加,显示从无变为零,所有未来添加的项目将是正常的...使用jquery和在一个小部件..所以如果你试图修复你的小部件在IE中工作,这可能对你有用.. < / p>

在小部件的_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);
        },

答案 5 :(得分:1)

在angular.js中selectDirective的渲染函数中添加以下几行(用粗体标记为**)对我来说很好。我正在寻找除了修补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);**

问题是如果IE中的标签为空,则HTMLOptionElement的label属性与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;
});

答案 6 :(得分:0)

我刚刚通过更改select元素的初始化方式(在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黑客。