0

HTML

<!-- Contents of div #1 -->
<form id="6hgj3y537y2biacb">
    <label for="product_calendar" class="entry_label">Calendar</label>
    <input type="text" name="product_calendar" class="entry" value="" />
</form>
<form id="pyc2w1fs47mbojez">
    <label for="product_calendar" class="entry_label">Calendar</label>
    <input type="text" name="product_calendar" class="entry" value="" />
</form>
<form id="kcmyeng53wvv29pa">
    <label for="product_calendar" class="entry_label">Calendar</label>
    <input type="text" name="product_calendar" class="entry" value="" />
</form>

<!-- Contents of div #2 -->
<div id="calendar_addRemove"> <!-- CSS >> display: none; -->
    <div id="calendar_add">
        <label for="calendar_add" class="calendar_addLabel">Add Occurrence</label>
        <input type="text" name="calendar_add" class="calendar_addInput" value=""/>
    </div>
    <div id="calendar_remove">
        <label for="calendar_remove" class="calendar_removeLabel">Remove Occurrence</label>
        <input type="text" name="calendar_remove" class="calendar_removeInput" value=""/>
    </div>
</div>

Javascript

// Complete behavioral script
$(function() {
    $('input[name=product_calendar]').css({ 'color': '#5fd27d', 'cursor': 'pointer' }).attr({ 'readonly': 'readonly' }); // Additional formatting for specified fields
    $('input[name=product_calendar]').focus(function() { // Focus on any 'input[name=product_calendar]' executes function
        var product_calendar = $(this); // Explicit declaration
        var attr_val = $(product_calendar).attr('value');
        $('#calendar_addRemove input').attr({ 'value': '' }); // Clear input fields
        $('#calendar_addRemove').fadeIn(500, function() { // Display input fields
            $('input[name=calendar_add]').blur(function() { // After value entered, action occurs on blur
                alert('Blur'); // Added for testing
                var add_val = $('input[name=calendar_add]').attr('value');
                if (add_val != '') {
                    alert('Not Blank'); // Added for testing
                    var newAdd_val = attr_val + ' ' + add_val;
                    $(product_calendar).attr({ 'value': newAdd_val });
                    $('#calendar_addRemove').fadeOut(500);
                    }
                else {
                    alert('Blank'); // Added for testing
                    $('#calendar_addRemove').fadeOut(500);
                    }
                });
            $('input[name=calendar_remove]').blur(function() { // After value entered, action occurs on blur
                alert('Blur'); // Added for testing
                var remove_val = $(this).attr('value');
                if (remove_val != '') {
                    alert('Not Blank'); // Added for testing
                    if (attr_val.indexOf(remove_val) != -1) {
                        alert('Eval True'); // Added for testing
                        var newRemove_val = attr_val.replace(remove_val, '');
                        $(product_calendar).attr({ 'value': newRemove_val });
                        $('#calendar_addRemove').fadeOut(500);
                        }
                    else {
                        alert('Eval False'); // Added for testing
                        $('#calendar_remove').append('<p class="error">Occurrence Not Found</p>');
                        $('.error').fadeOut(1500, function() { $(this).remove(); });
                        }
                    }
                else {
                    alert('Blank'); // Added for testing
                    $('#calendar_addRemove').fadeOut(500);
                    }
                });
            });
        });
    });

このスクリプトが実行されている順序を確認するために、いくつかのアラートを追加しました。入力1234input[name=calendar_add]てぼかしを入れると、アラートが期待どおりに表示されます。次に、続行して入力1234input[name=calendar_remove]てぼかしを行うと、このスクリプトは次の順序でアラートをスローします:ぼかし、空白ではない、偽の評価、ぼかし、空白ではない、真の評価-このプロセスを繰り返すと、アラートの発生は毎回2倍になります時間(追加と削除の両方)。ただし、同じ順序を維持します(セットの場合と同様)。

問題はDOMでの変数の複数値の再宣言だと思いますが、attr_valこの問題を軽減するためにスクリプトを修正する方法がよくわかりません。

4

2 に答える 2

4

そうではありません。それは不可能です。

それで、それがそう見えるかもしれないいくつかの考えられる理由があります:

  • 実際に実行されるコードはそのようには見えません。キャッシュされているのは古いバージョンであるか、間違ったファイルを探している可能性があります。

  • コードは複数回実行されるため、両方の実行ブランチが実行される可能性があります。(ここではその可能性は実際にはわかりませんが。)

  • あなたは結果を誤って解釈しており、両方のブランチを実行する必要があるという結論につながるものは、実際には他のコードが原因です。

デバッガーを使用して、コードにブレークポイントを設定できます。条件の前に1つのブレークポイントを設定し、各ブランチに1つ設定します。次に、コードが2回実行されるか、1回実行されるか、まったく実行されないかを確認します。

編集:

コードに追加したアラートは、イベントが実際に2回呼び出され、最初は値が思ったとおりではないことを示しています。

イベントがどこから呼び出されたかを調べるためのコードを追加します。イベントオブジェクトを関数シグネチャに追加してキャッチします.blur(function(e) {。次に、e.currentTargetを使用して、イベントをトリガーした要素を取得し、そこからいくつかの属性(idなど)を表示してイベントを識別できます。

編集2:

私はこの行について好奇心が強いです:

$(product_calendar).attr({ value: newRemove_val });

product_calendarどこかに変数を作成しますか、それとも次のことを意味しますか?

$('input[name=product_calendar}').attr({ value: newRemove_val });

編集3:

完全なコードを見ると、二重実行の原因は明らかです。イベントハンドラー内にハンドラーを追加しています。つまり、毎回別のハンドラーが追加されます。

正しく機能しない理由attr_valは、ある関数でローカル変数として作成され、別の関数でアンセッドされるためです。

代わりに、最初からぼかしハンドラーを追加してください。これらは1回だけ発生します。関数の外で変数を宣言します。

いくつかのメモ:

  • 関数を使用して属性valにアクセスする代わりに、関数を使用できます。valueattr
  • に割り当てる$(this)product_calendar、それはjQueryオブジェクトになります。を使用する必要はありません$(product_calendar)
  • 削除は完全な値と一致しないため、を追加12して2から削除する2と、取得1して終了できます2

(リストの後にコードブロックを含めることはできないため、これはダミーテキストです...)

// Complete behavioral script
$(function() {

  // declare variables in outer scope
  var attr_val;
  var product_calendar;

  $('input[name=product_calendar]')
    .css({ 'color': '#5fd27d', 'cursor': 'pointer' })
    .attr('readonly', 'readonly') // Additional formatting for specified fields
    .focus(function() { // Focus on any 'input[name=product_calendar]' executes function
      product_calendar = $(this); // Explicit declaration
      attr_val = product_calendar.val();
      $('#calendar_addRemove input').val(''); // Clear input fields
      $('#calendar_addRemove').fadeIn(500); // Display input fields
    });

  $('input[name=calendar_add]').blur(function() { // After value entered, action occurs on blur
    var add_val = $(this).val();
    if (add_val != '') {
      product_calendar.val(attr_val + ' ' + add_val);
    }
    $('#calendar_addRemove').fadeOut(500);
  });

  $('input[name=calendar_remove]').blur(function() { // After value entered, action occurs on blur
    var remove_val = $(this).val();
    if (remove_val != '') {
      if (attr_val.indexOf(remove_val) != -1) {
        product_calendar.val(attr_val.replace(remove_val, ''));
        $('#calendar_addRemove').fadeOut(500);
      } else {
        $('#calendar_remove').append('<p class="error">Occurrence Not Found</p>');
        $('.error').fadeOut(1500, function() { $(this).remove(); });
      }
    } else {
      $('#calendar_addRemove').fadeOut(500);
    }
  });

});
于 2010-10-26T19:20:39.623 に答える
1

OK、私は今問題を理解していると思います。

要素に焦点を合わせるたびに、要素に焦点を合わせproduct_calendarます。これを行うたびに、そのコールバックを使用して、新しいブラーハンドラーをand要素にバインドします。つまり、時間の経過とともに、これらの要素には複数のブラーハンドラー(すべて同じロジックを実行する)が含まれるようになります。これは、希望するものではありません。fadeIn#calendar_addRemovefadeIncalendar_addcalendar_remove

以下のスクリプトでは、ネストされたハンドラーを引き出して、各要素に1回だけバインドされるようにしています。ご了承ください:

  • product_calendarnull匿名関数の先頭で(として)宣言され、product_calendar要素のフォーカスハンドラーによって更新されます。これにより、正しい動作が得られると思います

  • attr_val両方のブラーハンドラーでローカルに宣言および割り当てられます。繰り返しになりますが、これにより正しい動作が得られると思います。 (宣言されているように)ブラーハンドラーの外部product_calendarで宣言すると、アクセス時に誤って古い値を使用する可能性があります。

このコードがどのように機能するのかはまだ正確にはわかりませんが、このスクリプトは「合理的」と思われる方法で実行されます。

(ちなみに、本番コードでは、入力文字列の最初と最後に空白を含める必要があります。)

    $(function() {
    var product_calendar = null;

    $('input[name=product_calendar]').css({ 'color': '#5fd27d', 'cursor': 'pointer' }).attr({ 'readonly': 'readonly' }); // Additional formatting for specified fields

    $('input[name=calendar_add]').blur(function() { // After value entered, action occurs on blur
        alert('Blur'); // Added for testing
        var add_val = $('input[name=calendar_add]').attr('value');
        if (add_val != '') {
            alert('Not Blank'); // Added for testing
            var attr_val = $(product_calendar).attr('value');
            var newAdd_val = attr_val + ' ' + add_val;
            $(product_calendar).attr({ 'value': newAdd_val });
            $('#calendar_addRemove').fadeOut(500);
        }
        else {
            alert('Blank'); // Added for testing
            $('#calendar_addRemove').fadeOut(500);
        }
    });

    $('input[name=calendar_remove]').blur(function() { // After value entered, action occurs on blur
        alert('Blur'); // Added for testing
        var remove_val = $(this).attr('value');
        if (remove_val != '') {
            alert('Not Blank'); // Added for testing
            var attr_val = $(product_calendar).attr('value');
            if (attr_val.indexOf(remove_val) != -1) {
                alert('Eval True'); // Added for testing
                var newRemove_val = attr_val.replace(remove_val, '');
                $(product_calendar).attr({ 'value': newRemove_val });
                $('#calendar_addRemove').fadeOut(500);
            }
            else {
                alert('Eval False'); // Added for testing
                $('#calendar_remove').after('<p class="error">Occurrence Not Found</p>');
                $('.error').fadeOut(1500, function() { $(this).remove(); });
            }
        }
        else {
            alert('Blank'); // Added for testing
            $('#calendar_addRemove').fadeOut(500);
        }
    });

    $('input[name=product_calendar]').focus(function() { // Focus on any 'input[name=product_calendar]' executes function
        product_calendar = $(this);
        $('#calendar_addRemove input').attr({ 'value': '' }); // Clear input fields
        $('#calendar_addRemove').fadeIn(500);
        });
    });
于 2010-10-27T03:55:41.963 に答える