1

意図したとおりに機能するシンプルなフォームがあります。これは、一度に1つの質問のみを表示するマルチステップフォームです。ユーザーが入力フィールド(すべてのラジオボタン)をクリックすると、次の質問に移動します。これは、クリックした内容によって異なり、最後の質問の後に送信ボタンが表示されます。
私は現在いくつかの.click機能を持っていますが、これはうまく機能します。ただし、書き込みとパフォーマンスの両方の観点から、これを行うのに最も効率的な方法ではないと確信しています。.click複数の関数を使用するより効率的な方法はありますか?

$('.male').click(function() {
  $('#male').show();
  $('#gender').hide();
});

$('.female').click(function() {
  $('#female').show();
  $('#gender').hide();
});
4

4 に答える 4

3

次のような HTML の論理構造を仮定します。

<form action="#" method="post">
    <fieldset>
        <legend>Question 1: gender</legend>
        <label for="m">Male</label>
        <input type="radio" name="gender" id="m" />
        <label for="f">Female</label>
        <input type="radio" name="gender" id="f" />
    </fieldset>
    <fieldset>
        <legend>Question title</legend>
        <!-- answer options -->
    </fieldset>
    <!-- other questions... -->
</form>

次に、私が考えることができる最も簡単なオプションは次のとおりです。

$('form').on('click','input',
              function(){
                  var fieldset = $(this).closest('fieldset');
                  fieldset.fadeOut(500,
                      function(){
                          fieldset.next('fieldset').fadeIn(500);
                      });
              });​

<a href="http://jsfiddle.net/davidThomas/sQW79/1/" rel="nofollow">JS Fiddle のデモ。

以前の質問を再検討できるようにするために、次の行に沿って適応することをお勧めします。

<form action="#" method="post">
    <fieldset>
        <legend>Question 1: gender</legend>
        <label for="m">Male</label>
        <input type="radio" name="gender" id="m" />
        <label for="f">Female</label>
        <input type="radio" name="gender" id="f" />
        <div class="controls">
            <a href="#" class="prev">Previous</a>
            <a href="#" class="next">Next</a>
        </div>
    </fieldset>
    <!-- other questions... -->
</form>

そしてjQueryと組み合わせる:

$('fieldset').not($('fieldset:eq(0)')).hide();
$('.controls a.prev:first, .controls a.next:last').addClass('disabled');
$('form').on('click', 'input, a', function(e) {
    var target = e.target,
        targetType = target.tagName.toLowerCase(),
        targetClass = target.className,
        fieldset = $(this).closest('fieldset'),
        prev = fieldset.prev().length,
        next = fieldset.next().length;

    if (targetType == 'input' && next > 0) {
        fieldset.fadeOut(500, function() {
            fieldset.next('fieldset').fadeIn(500);
        });
    }
    else if (targetType == 'a') {
        if (targetClass == 'prev' && prev > 0) {
            fieldset.fadeOut(500, function() {
                fieldset.prev('fieldset').fadeIn(500);
            });
        }
        else if (targetClass == 'next' && next > 0) {
            fieldset.fadeOut(500, function() {
                fieldset.next('fieldset').fadeIn(500);
            });
        }
    }
});​

JS フィドルのデモ

参考文献:

  1. jQueryのもの:

  2. ネイティブ JavaScript のもの:

于 2012-04-09T16:13:25.947 に答える
1

イベントバブリングのため、これを行うことができます:

​$('body').on('click',function(e){
    switch ($(e.target).attr('class')){
        case "male":
            $('#male').show();
            $('#gender').hide();
            break;
        case "female":
            $('#female').show();
            $('#gender').hide();
            break;
        default:
            alert("default function!");
            break;            
    }
});​​​​​​

これがデモです:http://jsfiddle.net/748sE/2/

もちろん、デフォルトの関数は、まだキャッチされていないそのページをクリックしたものすべてに戻ります...

ところで、 David Thomasが彼の答えでしたように、それを少し最適化する$(e.target).attr('class')ために置き換えることができます...e.target.className

于 2012-04-09T12:45:49.810 に答える
0

すべての質問に「質問」のクラスを指定すると、各回答に、表示したい次のブランチのクラス(またはその他の)プロパティに対応するIDを含めることができます。

したがって、各応答には次に表示するものの名​​前が含まれ、クリックハンドラーは1つだけになります

すなわち:

$("input").click(function() {
    $(".question").hide();
    var itemToShow = $(this).attr("id");
    //alert(itemToShow);
    if ($("."+itemToShow).length > 0) {
        $("."+itemToShow).show("normal");
    } else {
        $(".finale").show("normal");
    }
});

コントロールが希望どおりに機能するまで、おそらく少し試してみる必要があります。これが解決すべきフィドルです。

更新:これが最新のフィドルデモンストレーションです。

于 2012-04-09T12:45:19.670 に答える
0

#male要素と要素の両方#femaleがクリックされたときにコードを実行する必要があるため、両方とも独自のクリック ハンドラーが必要です。ただし、両方を同じセレクターに含め、単一の関数を呼び出して両方を処理することで、このコードを簡素化できます。これを試して:

$(".male, .female").click(showDivs);

function showDivs() {
    if ($(this).hasClass("male")) {
        $("#male").show();
    }
    else {
        $("#female").show();
    }
    $("#gender").hide();
}
于 2012-04-09T12:37:20.797 に答える