jQuery 验证,滚动到错误无法正常工作

jQuery Validation, scroll to error doesn't work correctly

所以我有一个 3 阶段的表格,它在每一步都验证,并在提交时再次验证。我有一些问题,我认为这可能是由于我的 JS 的结构,但我不能确定。

出于某种原因,它只会滚动到第一个错误一次,一旦有人填写该字段时错误被清除,它就会滚动到页面顶部。尽管我们现在可以翻开新的一页。我已经复制了所有相关代码,并删除了大部分 JS,因为大约有 300 行。如果您希望看到工作副本 'xxxx'

,我确实有一个实时 url

这是JS;

var form = $("#msform");
    form.validate({
        rules: {
            age: { 
                digits: true,
                minlength: 2
            },
            group: {
                required: true
            },
            product: {
                required: true
            },
            tan: {
                required: true
            },
            exfoliate: {
                required: true
            },
            advertising: {
                required: true
            },
            morizLove: {
                required: true
            },
            morizMoreProducts: {
                required: true
            },
            terms: {
                required: true
            },
            media: {
                required: true,
                minlength: 4
            },
            other: {
                required: true              
            },
            buyother: {
                required: true,
                minlength: 4
            },
        },
        messages: {
            fullname: { 
                required: "Please tell us your full name"
            },
            age: { 
                required: "Please tell us your age"
            },
            email: { 
                required: "Please enter a valid email"
            },
            address: { 
                required: "Please tell us your Address"
            },
            postcode: { 
                required: "Please tell us your Post Code"
            },
            product: { 
                required: "Please select a product"
            },
            tan: { 
                required: "Please tell us how often you self tan"
            },
            buymost: { 
                required: "Please tell us which product you use most"
            },
            group: {
                required: "Please select at least 1"
            },
            maintain: {
                required: "Please select at least 1"
            },
            advertising: {
                required: "Please select at least 1"
            },
            morizMoreProducts: {
                required: "Please tell us what products you would like to see from St. Moriz"
            },
            morizLove: {
                required: "Please tell us what you love most about St. Moriz"
            },
            terms: {
                required: "Please accept our Terms & Conditions"
            },
            media: {
                required: "Please tell us what media you have seen advertising this campaign"
            },
            other: {
                required: "Please tell us where you normally buy St. Moriz products from"
            },
            buyother: {
                required: "Please tell us which product you use most"
            },
        },
        errorPlacement: function(error, element) {
            switch(element.attr("name")) {
            case "product": 
                error.insertAfter( $(".product-error") );
                break;
            case "tan": 
                error.insertBefore( $(".tan-error") );
                break;
            case "group": 
                error.insertAfter( $("#other") );
                break;
            case "exfoliate": 
                error.insertAfter( $(".exfoliate-error") );
                break;
            case "maintain": 
                error.insertAfter( $(".maintain-error") );
                break;
            case "terms": 
                error.insertBefore( $(".terms-error") );
                break;
            case "advertising": 
                error.insertBefore( $(".advertising-error") );
                break;
            default:
                // the default error placement for the rest
                error.insertAfter(element);
            }
   }
    });

$(".submit").click(function(){
    $("#msform").validate();

    if (form.valid() == false){

        $('html, body').animate({
       scrollTop: ($('.error').offset().top - 60)
    }, 500);
    }
});


$(".next").click(function(){
    // if(animating) return false;
    animating = true;

    current_fs = $(this).parent();
    next_fs = $(this).parent().next();


        if (form.valid() == true){

            //show the next fieldset
            next_fs.show();
            //hide the current fieldset with style
            current_fs.animate({opacity: 0}, {
                step: function(now, mx) {
                    //as the opacity of current_fs reduces to 0 - stored in "now"
                    //1. scale current_fs down to 80%
                    scale = 1 - (1 - now) * 0.2;
                    //2. bring next_fs from the right(50%)
                    left = (now * 50)+"%";
                    //3. increase opacity of next_fs to 1 as it moves in
                    opacity = 1 - now;
                    current_fs.css({
                'transform': 'scale('+scale+')',
                'position': 'absolute'
              });
                    next_fs.css({'left': left, 'opacity': opacity, 'position': 'relative'});
                },
                duration: 800,
                complete: function(){
                    current_fs.hide();
                    animating = false;
                },
                //this comes from the custom easing plugin
                easing: 'easeInOutBack'
            });     

                //activate next step on progressbar using the index of next_fs
            $("#progressbar li").eq($("fieldset").index(next_fs)).addClass("active").find('img').attr("src","images/boardActive.png");

            // Scroll to top of next step form.

            $('html, body').animate({
         scrollTop: $("#progressbar").offset().top - 200
            }, 500);
            return false;

        }   
        else { // Scrolls to top error
            $('html, body').animate({
         scrollTop: ($('.error').offset().top - 60)
        }, 500);
        }

});

$(".previous").click(function(){
    // if(animating) return false;
    animating = true;

    current_fs = $(this).parent();
    previous_fs = $(this).parent().prev();

    //de-activate current step on progressbar
    $("#progressbar li").eq($("fieldset").index(current_fs)).removeClass("active").find('img').attr("src","images/board.png");;

    //show the previous fieldset
    previous_fs.show();
    //hide the current fieldset with style
    current_fs.animate({opacity: 0}, {
        step: function(now, mx) {
            //as the opacity of current_fs reduces to 0 - stored in "now"
            //1. scale previous_fs from 80% to 100%
            scale = 0.8 + (1 - now) * 0.2;
            //2. take current_fs to the right(50%) - from 0%
            left = ((1-now) * 50)+"%";
            //3. increase opacity of previous_fs to 1 as it moves in
            opacity = 1 - now;
            current_fs.css({'left': left});
            previous_fs.css({'transform': 'scale('+scale+')', 'opacity': opacity, 'position': 'relative'});
        },
        duration: 800,
        complete: function(){
            current_fs.hide();
            animating = false;
        },
        //this comes from the custom easing plugin
        easing: 'easeInOutBack'
    });

});

我知道那里有很多代码,但我认为这可能是一个结构问题。非常感谢您花时间阅读本文。请查看 IP 地址以获取表单如何对验证做出反应的工作副本。

非常感谢您花时间阅读本文。

编辑:删除直播 link 因为问题已得到回答。

$('html, body').animate({
    scrollTop: ($('.error:visible').offset().top - 60)
}, 500);

尽管显示 if 或 none,但您的选择器匹配所有错误 类。在您的情况下,动画函数采用了列表中的第一个匹配项。

当您添加“:visible”时,您只选择了页面上显示的元素。