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

Posted

技术标签:

【中文标题】<select> 仅显示所选选项的第一个字符【英文标题】:<select> only shows first char of selected option 【发布时间】:2011-08-19 23:48:47 【问题描述】:

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

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

简化代码示例:

<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 显示属性设置为“无”,然后填充它,最后当 ajax 调用和填充完成时,我只需删除 css 显示“无”属性。

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

【问题讨论】:

sigh 您用来填充select 框的标记或代码是什么样的? 为了完整性:你的 jQuery 代码是什么? 您可以使用jsfiddle.net 来设置您的代码演示。 “您可以使用 jsfiddle.net 来设置您的代码演示。” 但如果您这样做,请务必发布代码实际上在你的问题中。不仅仅是指向jsfiddle.net(或jsbin.com)的链接。 你可以在 IE9 的异步调用之后尝试forcing a redraw of the UI。 【参考方案1】:

在我的例子中,我没有在 ajax 请求触发之前隐藏选择的事件挂钩,所以我不得不在事后强制重绘选择元素。重新应用现有宽度似乎可行:

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

【讨论】:

这解决了我的问题,但在我的情况下引入了另一个问题:这会将选择项的样式属性设置为太短的宽度。我的猜测是,这行是在运行 CSS 宽度设置之前运行的,并且因为这 js 行设置了内联样式,所以它覆盖了 CSS。 这是一个愚蠢的错误。这个答案让我找到了解决方案,但我不得不这样做两次: $("#mydropdown").width($("select").width()); $("#mydropdown").width(300); 谢谢你。我不得不使用 $('select').css('width', 0).css('width', '').hide().show() 来让 IE9 正确更新选项所在的选择倍数使用 AngularJS 动态删除和添加。 这对我有用,我选择的选项“发布日期”在页面加载时显示为“发布”,所以我在页面加载时重置 Js 中的选择框宽度并且它有效。【参考方案2】:

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

【讨论】:

嘿。你一定会喜欢 IE,因为 IE 的这些小怪癖让 Web 开发变得如此有趣【参考方案3】:

根据 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 中指定的,而不是在样式属性中。

【讨论】:

【参考方案4】:

我正在使用 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);

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

【讨论】:

【参考方案5】:

在我的情况下,我有回调,因此在填充时将显示设置为无不是我的选择,但是,我能够详细说明@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);
        ,

【讨论】:

【参考方案6】:

在 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 的标签属性与文本属性不同。

这可以通过在屏幕加载后添加以下代码并查看 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;
);

【讨论】:

【参考方案7】:

我刚刚通过更改 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 hack。

【讨论】:

以上是关于<select> 仅显示所选选项的第一个字符的主要内容,如果未能解决你的问题,请参考以下文章

选择连接:如果所选选项的值为 1,则显示另一个选择

在我的情况下,如何在 <select> 中获取所选选项的 ID?

如何使用 ajax 更改所选选项 [关闭]

如何提取 DataTables 中所选行的第一列?

IE 11不会更新选择元素中选定的选项项标签

在 Django 模板中仅显示正文的第一段