javascript - jQuery 在 Chrome 和 IE 中对数组输出进行不需要的排序(FF 工作正常)

标签 javascript jquery internet-explorer google-chrome firefox

我有一个 jquery 脚本,它使用数组将下拉选择框的选项转换为 ul 列表项。下拉列表中的每个选项都有一个数字选项值,例如

<option value="12">Size S</option>
<option value="34">Size M</option>
<option value="7">Size L</option>

它被转换为一个列表,例如

<ul>
<li class="opt_12">Size S</li>
<li class="opt_34">Size M</li>
<li class="opt_7">Size L</li>
</ul>

在 Firefox 中,一切都按预期运行,列表项的显示顺序与下拉选项相同。然而,IE 和 Chrome 似乎会自动按选项值降序对数组的选项值进行排序。 因此,在 Chrome 和 IE 中,我得到的不是下拉列表中的尺寸顺序 S、M、L、XL,而是类似 XL、M、S、L 的列表。

我注意到一件事:当我使用 var options = Array; 构造数组时,Firefox 以正确的顺序显示列表元素,而 Chrome 和 IE 以错误的顺序显示。当我使用 var options = []; 时,所有三个测试浏览器都以错误的顺序显示列表。

下面是我用来将下拉列表转换为列表项的脚本的相关代码:

(function($) {
    $.fn.visualAttribute = function(options) {
        var defaults = {
            useTitle: false,
            attrClicked : function(data) {
                return true;
            },
            attrUpdated : function(data) {
            }
        };
        var settings = $.extend(defaults, options);

        //loop all attributes
        var selectbox_counter = 0;
        return this.each(function() {
            //use counter for a unique class for each wrapper
            selectbox_counter++;

            //store reference to attribute selectbox
            var selectbox = $(this);

            //hide the default dropdown (but keep it in dom for posting the required values)
            $(this).css('position', 'absolute').css('left', '-100000px').show();

            //insert wrapper for options
            var wrapper = $('<ul />')
                    .attr("class", "la_wrapper")
                    .attr("id", "la_wrapper_" + selectbox_counter)
                    .appendTo($(this).parent());

            $(this).parent().append('<div style="clear:both"></div>');

            if (selectbox.attr("id") != "") {
                wrapper.attr("rel", selectbox.attr("id"));
            }

            //store all values of the dropdown in an array
            var options = [];
            var option_counter = 0;
            var description = '';

            selectbox.children('option').each(function() {
                option_counter++;

                if (option_counter == 1) {
                    //first option contains the description, e.g. 'please select size'
                    description = $(this).text();
                }

                //only use option if has a value
                var value = $(this).val();
                if (value != '') {
                    options[value] = ({value : value, text : $(this).text()});
                }
            });

            //loop all stored options and create custom html
            if (options.length) {
                for (var index in options) {
                    if (!isNaN(index)) {
                        var value = index;
                        var text = options[index].text;
                        if (!settings.useTitle) {
                            description = '';
                        }
                        wrapper.append('<li title="' + description + '" class="opt_' + value + '"><a href="#' + value + '">' + text + '</a></li>');
                    }
                }
            }

            //set custom options to same value as current selectbox value (only needed in rare cases)
            var current_value = selectbox.val();
            if (current_value > 0) {
                $("#la_wrapper_" + selectbox_counter + ' li.opt_' + current_value + ' a').addClass('selected');
            }

            //event handler for catching a clicked attribute
            $("#la_wrapper_" + selectbox_counter + ' li a').click(function() {

                var value = $(this).attr("href").split('#')[1];

                //use callback
                if (!settings.attrClicked(options[value])) {
                    return false;
                }

                //set value and class
                selectbox.val(value);
                $("#la_wrapper_" + selectbox_counter + ' .selected').removeClass('selected');
                $(this).addClass('selected');

                //use callback
                settings.attrUpdated(options[value]);

                return false;
            });
        });
    };
    })(jQuery);

如何防止 IE 和 Chrome 对数组进行“自动排序”并保留/转移结果列表中下拉选项的原始顺序?

最佳答案

如果顺序很重要,请不要使用选项的value作为数组键,只需执行append(P.S.使用[],而不是 Array——它没有做你认为它正在做的事情)

var options = [];
var option_counter = 0;
var description = '';

selectbox.children('option').each(function() {
    option_counter++;

    //only use option if has a value
    var value = $(this).val();
    if ( value ) {
        options.push({value : value, text : $(this).text()});
    }
});

然后,在循环时,完全去掉 if (options.length),并使用常规的 for 循环:

for (var i=0; i<options.length; i++) {
    var value = options[i].value;
    var text = options[i].text;
    if (!settings.useTitle) {
        description = '';
    }
    wrapper.append('<li title="' + description +
                   '" class="opt_' + value +
                   '"><a href="#' + value + '">' + text +
                   '</a></li>');
}

关于javascript - jQuery 在 Chrome 和 IE 中对数组输出进行不需要的排序(FF 工作正常),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15515734/

相关文章:

javascript - JCarousel JQuery 插件,需要一些帮助

javascript - 覆盖或删除注入(inject)到 Buildfire 应用程序中的 appTheme CSS

javascript - 使用 jquery.event.drag 拖动多个元素

javascript - .removeClass 在多个项目上?

Ajax 无法在 IE 上使用 SSL 错误代码 12019

javascript - 显示所选名称的数据库值并将该名称插入另一个表

javascript - 如何将html内容添加到幻灯片中?

javascript - 下一个和上一个按钮中的 Json 数据

image - .png图像无法在IE7,IE8中正确呈现

html - Twitter bootstrap 3 禁用光标出现在 IE 11 中的下拉选项顶部