2

配列を使用して、ドロップダウン選択ボックスのオプションを ul リスト項目に変換する jquery スクリプトがあります。ドロップダウンの各オプションには数値のオプション値があります。

<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 の代わりに、Chrome & IE では XL、M、S、L のようなリストを取得します。

1 つのことに気付きvar options = Array;ました。配列の作成に使用すると、Firefox はリスト要素を正しい順序で表示し、Chrome と IE は間違った順序で表示します。を使用するvar options = [];と、テスト済みの 3 つのブラウザすべてでリストが間違った順序で表示されます。

以下は、ドロップダウンをリスト項目に変換するために使用するスクリプトの関連コードです。

(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 が配列を「自動ソート」するのを防ぎ、結果リストのドロップダウン オプションの元の順序を保持/転送するにはどうすればよいですか?

4

3 に答える 3

1

これで配列を反復すると:

for (var index in options) 

仕様により順序が保証されていないオブジェクト(配列インデックスではない)のプロパティを反復しているだけなので、順序が保証されていません。これを使用する必要があります:

for (var i = 0; i < options.length; i++)

配列を配列順に反復します。最初の形式は、特定の順序でオブジェクトのプロパティを反復します。後者の形式は、配列要素を配列インデックス順に繰り返します (これにより、実際の配列要素が配列順に表示されます)。

さらに、次のように配列を宣言します。

var options = [];

また

var options = new Array();

あなたは使用すべきではありません:

var options = Array;
于 2013-03-20T05:16:11.077 に答える
0

あなたの問題はfor...in、プロパティを列挙するために使用していることです。

オブジェクト (配列を含む) のプロパティの列挙順序は、これまでのところ ECMAScript では定義されていません。ECMAScript 6 では、順序を多かれ少なかれ次のように定義するという提案があります。これは、Chrome と IE が実装する動作です。Firefox の動作はいくぶん複雑で、オブジェクトが配列であるかどうか、配列であるかどうか、正確なプロパティ名が使用されているかどうか、配列の順序と長さ、およびその他のいくつかの要因によって異なります。

いずれにせよ、値を順番に列挙したい場合は、配列に格納してarray.push()から配列のインデックスを列挙します。したがって、既にテキストを取得しているように、置き換えoptions[value] = ...てから値を取得します。options.push(...)for (var index in options)for (var index = 0; index < options.length; ++index)options[index].value

于 2013-03-20T05:21:43.460 に答える