Отдельный слушатель jquery для обычных форм и форм, содержащих поле ввода файла

Поэтому я пытаюсь создать отдельные слушатели отправки для форм, содержащих входные данные файла, и форм, которые этого не делают. Когда я пытаюсь отфильтровать нужные элементы перед добавлением слушателя, кажется, что он выбирает все тело HTML. Это может быть достигнуто? Или я установил обоим слушателям все формы и фильтр после отправки?

http://jsfiddle.net/bi11j0hnst0n/MMzg7/3/

$(function(){
    //file form listener
    var file_forms = $('input[type=file]').closest('form');
    $('body').on('submit', file_forms, function(event){
        event.preventDefault();
        var form = $(this);
        form.css('background-color', 'blue');
        setTimeout(function(){
            form.css('background-color', 'white');
        }, 3000);
    });
    //regular form listener
    var regular_forms = $('form').not($('input[type=file]').closest('form'));
    $('body').on('submit', regular_forms, function(event){
        event.preventDefault();
        var form = $(this);
        form.css('background-color', 'red');
        setTimeout(function(){
            form.css('background-color', 'white');
        }, 3000);
    });
});

2 ответа

Решение

Если ваши формы не внедряются динамически в страницу, вам не нужно использовать делегирование событий, а если ваши формы динамически внедряются в страницу, то вы не используете делегирование событий. (Возможно, вы захотите прочитать о .on ())

Предполагая, что ваши формы статичны на вашей странице, вы можете назначить разные формы в зависимости от того, содержат ли они input[type=file] с помощью:

var allForms = $('form'),
    uploadForms = allForms.has('input[type=file]');

uploadForms.on('submit', function(e) { ... });  // for forms with file uploads

allForms.not(uploadForms).on('submit', function(e) { ... });  // all other forms

http://jsfiddle.net/MMzg7/6/

Если вам нужно использовать делегирование событий, вы можете использовать:

// with uploads
$('body').on('submit', 'form:has(input[type=file])', function(e){ ... });

// all other forms
$('body').on('submit', 'form:not(:has(input[type=file]))', function(e){ ... });

http://jsfiddle.net/MMzg7/7/

Хотя я бы порекомендовал вам прикрепить их к ближайшему статическому родителю, который будет содержать ваши динамически внедренные формы, а не только к body элемент.

Самый простой способ, который я могу придумать, - это выбрать все формы, а затем отфильтровать этот выбор, чтобы создать hasForms а также noForms (или как вы предпочитаете их называть), а затем приложите submitпогрузчик (с on()) к этим коллекциям jQuery, а не к body элемент:

$(function () {

    var forms = $('form'),
        hasFiles = forms.filter(function () {
            return $(this).find('input[type="file"]').length;
        }),
        noFiles = forms.filter(function () {
            return $(this).find('input[type="file"]').length === 0;
        });

    //file form listener
    var file_forms = $('input[type=file]').closest('form');
    hasFiles.on('submit', function (event) {
        event.preventDefault();
        var form = $(this);
        form.css('background-color', 'blue');
        setTimeout(function () {
            form.css('background-color', 'white');
        }, 3000);
    });
    //regular form listener
    var regular_forms = $('form').not($('input[type=file]').closest('form'));
    noFiles.on('submit', function (event) {
        event.preventDefault();
        var form = $(this);
        form.css('background-color', 'red');
        setTimeout(function () {
            form.css('background-color', 'white');
        }, 3000);
    });
});

JS Fiddle demo.

Другие вопросы по тегам