Javascript Bind на Blur, оба «если indexOf» и «еще» выполнено - PullRequest
0 голосов
/ 26 октября 2010

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);
                    }
                });
            });
        });
    });

Я добавил несколько предупреждений, чтобы увидеть порядок выполнения этого скрипта. Когда я вводю 1234 в input[name=calendar_add] и размытие, предупреждения появляются, как и ожидалось. Затем, когда я продолжаю и ввожу 1234 в input[name=calendar_remove] и размытие, этот сценарий выдает предупреждения в следующем порядке: Размытие, Не пусто, Eval False, Размытие, Не пусто, Eval True - Если я повторяю этот процесс, количество моих предупреждений удваивается каждый раз (как добавление, так и удаление), но в том же порядке (как в наборах).

Я думаю, что проблема заключается в повторном объявлении переменной значения attr_val в DOM, но я не совсем уверен, как пересмотреть мой сценарий, чтобы облегчить эту проблему.

Ответы [ 2 ]

4 голосов
/ 26 октября 2010

Это не так. Это невозможно.

Итак, есть несколько возможных причин, по которым это может выглядеть так:

  • Код, который на самом деле выполняется, выглядит не так. Это может быть более старая версия с кэшированием или вы ищете не тот файл.

  • Код выполняется более одного раза, таким образом могут выполняться обе ветви выполнения. (Хотя я не вижу возможности для этого здесь.)

  • Вы неправильно интерпретируете результат, и все, что вы видите, приводит к выводу, что обе ветви должны быть выполнены, на самом деле вызвано каким-то другим кодом.

Вы можете использовать отладчик для установки точек останова в коде. Установите одну точку останова перед условием и одну в каждой ветви. Затем вы увидите, выполняется ли код дважды, один раз или нет.

Edit:

Оповещения, которые вы добавили в код, показывают, что событие фактически вызывается дважды, и в первый раз значения не соответствуют вашим ожиданиям.

Добавьте код, чтобы попытаться выяснить, откуда вызывается событие. Поймать объект события, добавив его в сигнатуру функции: .blur(function(e) {. Затем вы можете использовать e.currentTarget, чтобы получить элемент, вызвавший событие, и отобразить некоторые атрибуты из него (например, его идентификатор), чтобы идентифицировать его.

Редактировать 2:

Меня интересует эта строка:

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

Вы создаете переменную product_calendar где-нибудь или имеете в виду:

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

Редактировать 3:

Видя полный код, причина двойного выполнения понятна. Вы добавляете четные обработчики внутри обработчика событий, что означает, что каждый раз добавляется другой обработчик.

Причина, по которой attr_val не работает должным образом, заключается в том, что он создается как локальная переменная в одной функции, а затем не обрабатывается в другой функции.

Вместо этого добавьте обработчики размытия с самого начала, и они появятся только один раз. Объявите переменную вне функции.

Некоторые заметки:

  • Вы можете использовать функцию val вместо доступа к атрибуту value с помощью функции attr.
  • Когда вы присваиваете $(this) product_calendar, это объект jQuery. Вам не нужно использовать $(product_calendar).
  • Удаление не соответствует полным значениям, поэтому вы можете добавить 12 и 2, затем удалить 2 и вы получите 1 и 2 left.

(это фиктивный текст, потому что вы не можете иметь блок кода после списка ...)

// 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);
    }
  });

});
1 голос
/ 27 октября 2010

ОК, мне кажется, я понимаю проблему сейчас.

Каждый раз, когда вы фокусируете внимание на элементах product_calendar, вы делаете fadeIn на элементе #calendar_addRemove.Каждый раз, когда вы делаете это fadeIn, вы используете его обратный вызов для привязки новых обработчиков размытия к элементам calendar_add и calendar_remove.Это означает, что со временем эти элементы будут иметь несколько обработчиков размытия (все они выполняют одну и ту же логику.) Это не может быть тем, что вы хотите.

В приведенном ниже сценарии явытащил вложенные обработчики, чтобы они были связаны только один раз с каждым элементом.Обратите внимание:

  • product_calendar объявляется (как null) в верхней части анонимной функции, а затем обновляется обработчиком фокуса в элементе 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);
        });
    });
...