Почему мой скрипт jQuery для проверки обязательных полей ввода работает так медленно?

Я пытаюсь использовать jQuery для проверки обязательных полей ввода для браузеров, которые не распознают HTML-тег required. Мой сценарий jQuery выглядит следующим образом.

$('div').on('submit', '#myform', function(e){     
    e.stopPropagation();
    e.preventDefault();
    $( ':input[required]').each( function (e) { 
        if ( this.value.trim() == '' ) {
            $('.error').html(this.name + " is required");
            return false;
        }       
    }); 
    $(this).unbind().submit();
 }); 

Но очень медленно загружается! после того, как я нажму кнопку отправки формы, пройдет около 5 секунд, прежде чем появится сообщение об ошибке! Кажется, он занимает несколько циклов. Почему это так? Как я могу это решить?


person user2335065    schedule 28.03.2015    source источник


Ответы (2)


Делегированный обработчик submit не привязан напрямую к элементу формы, поэтому вы не можете отвязать обработчик таким образом. Вы создаете бесконечный цикл. Вы должны использовать метод off и отвязать обработчик элемента div.

Также обратите внимание, что возвращаемое значение обратного вызова each не влияет на поток выполнения оболочки, обработчика отправки. Каждая функция имеет свое возвращаемое значение.

$('div').on('submit', '#myform', function(e){     
    var $e = $('.error').empty();
    var $invalids = $(':input[required]').filter( function (e) { 
        var invalid = this.value.trim().length === 0;
        if ( invalid ) {
            $e.append('<p>' + this.name + " is required</p>");
        }
        return invalid;       
    }); 
    if ( $invalids.length ) {
       return false;
    }
    this.submit();
}); 

Метод submit объекта HTMLFormElement не запускает обработчик отправки jQuery, поэтому нет необходимости отвязывать обработчик. Если проверка проходит, форма отправляется нормально.

С точки зрения производительности вы также можете избежать использования селектора :input. Из :input документации jQuery:

Поскольку :input является расширением jQuery, а не частью спецификации CSS, запросы, использующие :input, не могут воспользоваться преимуществом повышения производительности, обеспечиваемым собственным методом DOM querySelectorAll(). Чтобы добиться наилучшей производительности при использовании :input для выбора элементов, сначала выберите элементы с помощью чистого селектора CSS, а затем используйте .filter(":input").

Свойство elements объекта HTMLFormElement возвращает HTMLFormControlsCollection в браузерах HTML5 и объект HTMLCollection в браузерах HTML4, содержащий все элементы управления элемента формы. Вы также можете использовать это свойство вместо запроса DOM и использовать метод jQuery filter для фильтрации required полей:

 $(this.elements).filter('[required]');
person undefined    schedule 28.03.2015
comment
Кроме того, :input[required] очень медленный селектор. - person Jashwant; 28.03.2015
comment
@Jashwant Да, хороший звонок. Если он все еще медленный, следует рассмотреть возможность использования более быстрого селектора. - person undefined; 28.03.2015

Когда вы вызываете submit() в последней строке, вы создаете бесконечный цикл.

person Evgeniy Ryzhkov    schedule 28.03.2015