1

ここで問題が発生し、ここ数日髪を引っ張っています...

私はウェブサイトのために一種の言語フィルター機能を作っています、そしてそれはあなたが言語をクリックするメニューであり、そしてそれはそれらの残りをフィルターで取り除きます。たくさんの異なる言語を手に入れたので、同じコードを15個作成するのではなく、すべてをループするのが最善だと思いました。

これが私のコードです:

// >>> Language click effects
    for(langClickNum = 1; langClickNum < langList.length; langClickNum++) {

        $('#lang'+langList[langClickNum]).click(function() {
            if (!langSelect[langClickNum]) {

                clrSearch();
                clrLang();
                langHide();

                $('#lang'+langList[langClickNum]).addClass('langCheck');
                $('.itemLang'+langList[langClickNum]).show();
                langSelect[langClickNum] = true;
            }
            else {
                clrLang();
                langShow();
            }
        });

    }

クリック関数の内部を見るとわかるように、ループカウンター番号を使用してさまざまな配列からインデックスを選択したいと思います。ただし、クリック関数内のスクリプトはクリックしないと実行されないため、正しい配列番号を取得できません。代わりに、クリックした各言語の最後の配列番号を選択します。私は問題が何であるかをよく知っていますが、それを解決する方法がわかりません。助けてください!

ループしない番号を指定すると、次のように問題なく機能します。

$('#lang'+langList[1]).click(function() {
        if (!langSelect[1]) {

            clrSearch();
            clrLang();
            langHide();

            $('#lang'+langList[1]).addClass('langCheck');
            $('.itemLang'+langList[1]).show();
            langSelect[1] = true;
        }
        else {
            clrLang();
            langShow();
        }
});

私の問題をご覧いただければ幸いです。

4

3 に答える 3

1

私は数ヶ月前に同様の問題に直面していました。次のようにします。

$('#lang'+langList[langClickNum]).click(function(langClickNum) {
    return function() {
        if (!langSelect[langClickNum]) {

            clrSearch();
            clrLang();
            langHide();

            $('#lang'+langList[langClickNum]).addClass('langCheck');
            $('.itemLang'+langList[langClickNum]).show();
            langSelect[langClickNum] = true;
        }
        else {
            clrLang();
            langShow();
        }
    }
});

その理由は、すべてのクリック ハンドラー関数が同じクロージャー環境を共有しているため、変数 langClickNum がすべての関数で同じになるためです。それらのそれぞれで langClickNum を異なるものにする必要がある場合は、それを関数に渡す必要があります。これにより、基本的にその関数のクロージャー用に langClickNum のコピーが作成されます。完璧に説明できたか自信がありません...

于 2012-09-30T18:47:30.797 に答える
0

この問題は、JS 変数のスコープ/クロージャの概念に関連しています。

langClickNum の値は、'click' ハンドラーをバインドしているときは正常に繰り返されますが、クリック ハンドラーが実行されると、'langClickNum' はすでに langList.length に等しくなっています。

次のようなことができます:

for(x = 1; x < langList.length; x++) {      
    (function(){
        var langClickNum = x;   
        $('#lang'+langList[langClickNum]).click(function() {//... rest of your code}
    })();
}

ここで、langClickNum の値は、JS の関数スコープにより、期待どおりになります。

詳細については、 https ://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope を参照してください。

于 2012-09-30T19:05:35.837 に答える
0

for ループを使用するのではなく、カウンターを使用して DOM 内の lang オブジェクトを単純に反復処理します。

<script type="text/javascript">
    jQuery(document).ready(function () {
        var _LangList = ['lang1', 'lang2', 'lang3', 'lang4', 'lang5'];
        var _iCurrLangIndex = 0;
        var _iIndex = 0;
        jQuery.each(jQuery('#lang_list').children(), function () {
            var _oCurrLangObj = jQuery(this).click(function () {
                var __iThisItemsIndex = parseInt(jQuery(this).attr('data-lang-index'));
                // Code Here
            }).attr('data-lang-index', _iIndex++);
        });
    });
</script>

<div id="lang_list">
    <div id="lang0"></div>
    <div id="lang1"></div>
    <div id="lang2"></div>
    <div id="lang3"></div>
    <div id="lang4"></div>
</div>

また、値を選択するために、使用されているものを管理するために 1 つのグローバル インデックス変数 (_iCurrLangIndex) を使用し、可能であれば 0 ベースにします。

于 2012-09-30T19:18:38.363 に答える