jQuery不需要的排序数组输出在Chrome和IE (FF工作良好)
jQuery unwanted sorting of array output in Chrome and IE (FF working fine)
我有一个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似乎按降序自动按选项值排序数组的选项值。不像下拉菜单里的大小顺序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
(注:使用[]
,而不是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>');
}
当你这样迭代数组时:
for (var index in options)
你没有得到一个保证的顺序,因为你只是迭代一个对象的属性(不是数组索引),根据规范没有保证的顺序。你应该这样写:
for (var i = 0; i < options.length; i++)
按数组顺序迭代数组。第一种形式迭代对象的属性,没有特定的顺序。后一种形式按数组索引顺序迭代数组元素(它给出了实际数组元素的数组顺序)。
另外,用this声明一个数组:
var options = [];
或
var options = new Array();
你不应该使用:
var options = Array;
您的问题是您使用for...in
来枚举属性。
在任何情况下,如果您想按顺序枚举值,只需使用array.push()
将它们存储在数组中,然后枚举数组的索引。因此,将options[value] = ...
替换为options.push(...)
,将for (var index in options)
替换为for (var index = 0; index < options.length; ++index)
,并从options[index].value
获取值,就像您已经获得文本一样。
- 在FF和IE中使用vimeo播放器的问题-加载flash播放器而不是使用HTML5播放器
- 如何修复FF和IE中的Javascript无效日期错误
- Javascript/AAJAX在Opera中不起作用,在FF/IE/Chrome中完美工作
- 获取所选选项的Javascript在Webkit/FF中有效,但在IE中无效
- Image Map 在 FF 和 IE 中不起作用(使用 onclick javascript)
- 没有在带有IE-FF的IFrame中运行的脚本是可以的
- Highcharts数据FF和IE中的标签定位问题
- ISO 8601日期JS解释差异-IE/FF与Chrome
- 日期&时间脚本-ie vs ff
- JavaScript可以在IE+Chrome中使用,但不能在FF中使用
- 在<a>IE和FF不工作
- jQuery scrollTop没有'不能在FF或IE中制作动画,但在chrome中效果良好
- Onchange,向上,向下箭头键适用于FF和Chrome,但在IE中不起作用
- PHP/JavaScript 检查/取消检查在 FF 中工作,但在 IE 中不起作用
- Jquery对话框在IE中完美运行,但在FF和Chrome中则不然
- 是否有一个JavaScript IDE允许在所有三种浏览器(IE,FF,Chrome)中进行调试
- Cookie不是在Safari,ios中设置的,而是在ie,ff,chrome中工作
- FF/IE中iframe的滚动宽度不一致
- CSS六边形渲染问题在ff/ie
- 从一个标签链接到另一个标签.工作在Chrome,而不是FF/IE