【问题标题】:Separate jquery listener for regular forms and forms containing a file input field用于常规表单和包含文件输入字段的表单的单独 jquery 侦听器
【发布时间】:2013-10-16 22:41:18
【问题描述】:

所以我尝试为包含文件输入的表单和不包含文件输入的表单设置单独的提交侦听器。当我在添加侦听器之前尝试过滤我想要的元素时,似乎选择了整个 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);
    });
});

【问题讨论】:

    标签: jquery forms jquery-selectors


    【解决方案1】:

    如果您的表单不是动态注入到页面中,那么您不需要使用事件委托,如果您的表单是动态注入到页面中,那么这不是您使用事件委托的方式。 (您可能想阅读.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 元素。

    【讨论】:

    • "如果您的表单是动态注入到页面中的,那么这不是您使用事件委托的方式。"我如何错误地使用事件委托?您的意思是附加到父元素而不是主体?
    • 我的意思是,如果你阅读.on(),你会发现你的变量regular_formsfile_forms根本没有被用来缩小事件范围,而是被作为可通过event.data 访问的“数据”传递给事件处理程序。要使用事件委托,您需要传递 .on() 一个选择器,该选择器必须满足才能调用处理程序。
    【解决方案2】:

    我能想到的最简单的方法是选择所有表单,然后过滤该选择以创建 hasFormsnoForms(或您喜欢的任何名称),然后附加 submit -handler(带有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.

    【讨论】:

      猜你喜欢
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      • 2017-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-19
      • 1970-01-01
      相关资源
      最近更新 更多