【问题标题】:Uncaught RangeError: Maximum call stack size exceeded - can't find recursion未捕获的 RangeError:超出最大调用堆栈大小 - 找不到递归
【发布时间】:2017-05-19 13:36:25
【问题描述】:

Chrome 在我加载页面的大约 20 次中每 1 次抛出此错误。我已经浏览了代码——请记住,这或多或少是我第一次将 jQuery 用于任何事情——找不到明显的问题根源。我知道这可能是一个递归。错误不会在每次页面加载时引发的事实使得调试变得更加困难。多看几双眼睛会很有帮助。

放轻松,我知道其中一些代码很乱:

$(document).ready(function() {

    // viewport fix for iOS
    if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
        $('meta[name="viewport"]').remove();
        $('<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1">').appendTo('head');
    }

    //imgx retina image swap
    $(function() {
        $('.image').imgx(); 
    });

    // animate loader
    function animateLoader() {
        $('#loader').animate({ 'opacity' : '0' },400, function() {
            $('#loader').animate({ 'opacity' : '1' },0, function() {
                animateLoader();
            });
        });
    }
    animateLoader();

    // hamburger toggle class
    $('.hamburger').click(function() {
        $('.hamburger').toggleClass('is-active');
        $('#nav').slideToggle(200);
    });

    // set on state if active
    $('.linkhome.active span.pre').css({ 'width' : '10px' });

    // nav hover
    $('#nav ul li').hover(function() {
        $(this).children('span.post').animate({ width : '10px' }, 100);
    },function() {
        $(this).children('span.post').animate({ width : '0' }, 100);
    });

    $('#nav ul li, section div a').click(function() {
        if (!$(this).is('.active')) {

            // hide mobile nav on click and scroll to top
            if (window.matchMedia('(max-width: 992px)').matches) {
                $('html,body').animate({ scrollTop: 0 }, 400, 'swing' );
                setTimeout(function () {
                    $('.hamburger').toggleClass('is-active');
                    $('#nav').slideToggle(200); // delay allows band and scrollTop animations to complete
                }, 400);
            }

            if ($(this).is('.linkhome')) { var sectionColor = '#60cfc7'; } 
            else if ($(this).is('.linkplans')) { var sectionColor = '#49bbcc'; }
            else if ($(this).is('.linknetwork')) { var sectionColor = '#6ca3ab'; }
            else if ($(this).is('.linkguarantees')) { var sectionColor = '#a8f4ff'; }
            else if ($(this).is('.linkcontact')) { var sectionColor = '#fff'; }

            var linkId = '.' + $(this).attr('class');
            var sectionId = '#' + $(this).attr('class').replace('link', '');

            $('#band').animate({
                'height' : $(sectionId).height(),
                'background-color' : sectionColor
            }, 400);

            var positionWords = 0;
            $(sectionId).prevAll().each(function() {
                positionWords += parseInt($(this).outerHeight() - 1, 10); // -1 to compensate for jQuery margin collapse bug
            });
            $('#words').animate({
                'margin-top': -( positionWords )
            },400);

            $('#nav ul li' + linkId).addClass('active').siblings().removeClass('active');
            $(linkId).children('span.pre').animate({ width : '10px' }, 100);
            $(linkId).siblings().children('span.pre').animate({ width : '0' }, 100);
            if (window.matchMedia('(max-width: 1000px)').matches) {
                $(linkId).children('span.post').animate({ width : '0' }, 0);
            } else {
                $(linkId).children('span.post').animate({ width : '0' }, 100);
            }
            return false;
        }
    });

    // animate buy plan arrow
    $('ul.plan li.planBuy').hover(function() {
        $(this).children('span').stop().animate({ left : '5px' }, 100);
    },function() {
        $(this).children('span').stop().animate({ left : '0' }, 100);
    });

    // buy plan urls
    $('#buyBronze').click(function(){
        goog_report_conversion('/clients/cart.php?a=add&pid=1');
        window.location = '/clients/cart.php?a=add&pid=1';
    });
    $('#buySilver').click(function(){ 
        goog_report_conversion('/clients/cart.php?a=add&pid=2');
        window.location = '/clients/cart.php?a=add&pid=2';
    });
    $('#buyGold').click(function(){ 
        goog_report_conversion('/clients/cart.php?a=add&pid=3');
        window.location = '/clients/cart.php?a=add&pid=3';
    });
});

// position content on load
$(window).on('load', function(){
    $('#band').animate({ 'height' : $('#home').height(), 'background-color' : '#60cfc7' });
    $('#words').animate({ 'margin-top' : -$('#preload').height() - 1 }); // -1 to compensate for jQuery margin collapse bug
});

// re-position content on resize
$(window).resize(function() {   
    var sectionId = '#' + $('#nav ul li').closest('.active').attr('class').replace(/link|active/g, '');

    var positionWords = 0;
    $(sectionId).prevAll().each(function() {
        positionWords += parseInt($(this).outerHeight() - 1, 10); // -1 to compensate for jQuery margin collapse bug
    });
    $('#words').css({ 'margin-top': -( positionWords ) });
    $('#band').css({ 'height' : $( sectionId ).height() });         
});

【问题讨论】:

  • animateLoader ?
  • 干杯丹尼尔,不知道我是怎么忽略的。现在正在研究一种无需递归即可循环动画的方法...

标签: javascript jquery google-chrome recursion


【解决方案1】:
// animate loader
    function animateLoader() {
        $('#loader').animate({ 'opacity' : '0' },400, function() {
            $('#loader').animate({ 'opacity' : '1' },0, function() {
                animateLoader();
            });
        });
    }
    animateLoader();

在您的代码中,此函数将作为递归调用,因此您可以获得最大调用堆栈错误。尝试评论这个功能,而不是检查是否有错误

【讨论】:

  • 是的,稍后刷新 100 次,没有错误。那么如何在不递归的情况下循环动画呢? setInterval 也许,我会去谷歌搜索...
  • 是的,您可以尝试 setInterval,它可能会在您接受时起作用
【解决方案2】:

正如 Jay 之前所说,问题在于您的 animateLoader() 函数中的递归。 如果您只想在页面加载后隐藏一次加载器 - 您可以使用 css 动画来实现:

CSS:

#loader {
    /* Your loader style */
    animation: hide 0.4s 1;
}
@keyframes hide {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}

如果你想在任何时候显示和隐藏加载器,你可以使用 css 过渡和一点点 js:

CSS:

#loader {
    /* Your loader style */
    opacity: 1;
    transition: opacity 0.4s;
}
#loader.hidden {
    opacity: 0;
}

JS:

$(document).ready(function() {
    hideLoader();
});

function hideLoader() {
    $('#loader').addClass('hidden');
}

function showLoader() {
    $('#loader').removeClass('hidden');
}

【讨论】:

    猜你喜欢
    • 2018-01-24
    • 2014-08-01
    • 2015-10-28
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多