0

ページの準備ができて実行されているこのコードを検討してください。

$("input.extraOption[checked]").each(function() {   
        console.log($(this));
        $(this).closest('.questionRow').find('.date').attr("disabled", true);
        $(this).closest('.questionRow').find('.dateSpan').hide();
        $(this).closest('.questionRow').find('.date').val("");
        $(this).closest('.questionRow').find('.textareaResize').attr("disabled", true);
        $(this).closest('.questionRow').find('.textareaResize').val("");
        $(this).closest('.questionRow').find('.text').attr("disabled", true);
        $(this).closest('.questionRow').find('.text').val("");
        $(this).closest('.questionRow').find('.checkbox').attr("disabled", true);

    });

これらの呼び出しは他の場所でも使用されるため、リファクタリングしたいので、次の関数を作成しました。

jQuery.fn.extend({
    toggleAnswers: function (disable) {
        var group = $(this);
        group.find('.date').attr("disabled", disable);
        group.find('.date').val("");
        group.find('.textareaResize').attr("disabled", disable);
        group.find('.textareaResize').val("");
        group.find('.text').attr("disabled", disable);
        group.find('.text').val("");
        group.find('.checkbox').attr("disabled", disable);
        if(checkedStatus === true){
            group.find('.dateSpan').hide();
        }else{
            group.find('.dateSpan').show();
        }
    return group;
    }
});

次に、8 つの $(this).closest(...) 呼び出しを次のように変更します。

$(this).closest('.questionRow').toggleAnswers(true);

ここに問題があります: セレクターに一致する 5 つの要素を持つページでは、最初の要素のみが変更されます (つまり、console.log は 1 つしか取得されません)。リファクタリングの前に、5 つの要素すべてで期待どおりの変更が得られます。

このリファクタリングで間違っていることは何ですか?

4

1 に答える 1

1

checkStatusどこにも定義されていないため、例外が発生します。disable代わりに使いたいようです。

thisちなみに、 はこのメソッドが呼び出される jQuery コレクションを既に参照しているため、jQuery オブジェクト ( ) でラップするthisこと$(this)は冗長/不要です。これは$.fn、通常の jQuery メソッドではなく、特にメソッド内にあることに注意してください。たとえば、イベント ハンドラー内では DOM 要素を参照するため、jQuery メソッドを呼び出すにはthisそれをラップする必要があります。$(this)

また、要素の無効化は.prop() vs .attr().prop("disabled", true/false)で行う必要があります

同じ jQuery メソッドを呼び出す任意のセレクターを組み合わせることもできます。たとえば、次のようgroup.find('.date').val("");group.find('.text').val("");組み合わせることができます。group.find(".date, .text").val("");

これらの提案をすべてまとめて、this(一貫性とスケーラビリティのために) 反復処理を行うと、次のようになります。

jQuery.fn.extend({
    toggleAnswers: function (disable) {
        return this.each(function (idx, el) {
            var $group = $(el);
            $group.find(".date, .text, .textareaResize, .checkbox").prop("disabled", disable);
            $group.find(".date, .textareaResize, .text").val("");
            $group.find(".dateSpan").toggle(!disable);
        });
    }
});

使い方に応じて、次のように設定します。

var targets = $("input.extraOption[checked]"),
    toggler = function () {
        $(this).closest(".questionRow").toggleAnswers(this.checked);
    };

targets.each(toggler).on("click", toggler);

デモ: http://jsfiddle.net/XdNDA/

于 2013-08-22T18:30:52.397 に答える