【问题标题】:Repeating code block problem重复代码块问题
【发布时间】:2009-07-06 19:08:34
【问题描述】:

我在页面上运行的 jQuery JavaScript 文档中有以下代码(这是当前的):

$(window).resize(function(){
    detectscreen();
});

function windowWidth() {
    if(!window.innerWidth) {
        // user is being a git, using ie
        return document.documentElement.clientWidth;
    } else {
        return window.innerWidth;
}}

gearsExists = false;

function detectscreen() {
    shouldExist = windowWidth() >= 1300;
    if (shouldExist != gearsExists) {
        if (shouldExist) {
                $('body').append('<div id="gearsfloat"><a href="#" id="clickGoTop"></a></div>');
                $('#clickGoTop').fadeTo(0,0);
                $('#clickGoTop').hover(function() {
                    $(this).stop().fadeTo(500,1);
                }, function() {
                    $(this).stop().fadeTo(500,0);
                });
        } else {
            $('#gearsfloat').remove();
            $('#clickGoTop').remove();
        }
        gearsExists = shouldExist;
    }
}

这段代码来自我的previous question,只是因为我认为它是相关的,所以在这里分支。

这里的问题是开头很好:显示出来了。但是,如果屏幕被调整到小于 1300,它就会消失;还是不错的。

现在我再次将窗口设置为大于 1300。突然,齿轮元件增加了一倍。另一个屏幕挤压和放大和 BAM,现在有三个。这样做几次,它很快就会加起来。

我怎样才能阻止这种情况?

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    如果您在调整大小事件中挂钩任何代码,请确保您的代码不会再次调整窗口大小。否则,resize 事件将再次触发,您的代码将进入无限循环。

    另外,在您的代码中,您没有使用全局 gearsExists 变量。删除方法底部的“var”以使用全局变量。

    function detectscreen() {
    
            // Your original code
    
            //var gearsExists = shouldExist; //This code will create new local variable. 
            gearsExists = shouldExist; 
        }
    }
    

    编辑:这就是我要做的:

    //We will add only one variable to the global scope. 
    var screenManager = function()
    {
        var pub = {};
    
        var inResizeHandler = false;
    
        pub.getWindowWidth = function() 
                            { 
                                return window.innerWidth || document.documentElement.clientWidth;
                            };
    
        pub.manage = function()
                    {
                        //if we are already in the resize handler, don't do anything.
                        if(inResizeHandler)
                            return;
    
                        inResizeHandler = true;
    
                        if(pub.getWindowWidth() < 1300)
                        {
                            $('#gearsfloat').remove();
                            //You don't have to remove clickGoTop because it is part of gearsfloat.
                            inResizeHandler = false;
                            return;
                        }
    
                        if($('#gearsfloat').length > 0)
                        {
                            inResizeHandler = false;
                            return false;
                        }
    
                        $('body').append('<div id="gearsfloat"><a href="#" id="clickGoTop"></a></div>');
                        $('#clickGoTop').fadeTo(0,0);
                        $('#clickGoTop').hover(                     
                                    function() {$(this).stop().fadeTo(500,1);}, 
                                    function() {$(this).stop().fadeTo(500,0);
                            });
    
                        inResizeHandler = false;
                    };
    
        pub.init = function()
                    {
                        $(window).resize(pub.manage);
                    };
    
        return pub;
    }();
    
    
    $(document).ready( function() { screenManager.init(); } );
    

    编辑:

    最终工作版本:

    http://jsbin.com/ufipu

    代码:

    http://jsbin.com/ufipu/edit

    【讨论】:

    • 那么我如何确保它不会无限触发呢?我已将其更改为全局变量,现在它不会无限触发,但是每次页面再次调整大小越来越大时,它都会再次创建它。一段时间后,窗口再次变得越来越小,看起来很乱。
    • 很好地抓住了重新定义的全局变量。 +1
    • +1,但非常强调“var gearsExists”,它可以防止循环关闭。
    • @Brandon - 只需按照 Yogi 的示例删除“var”。您正在使用该“var”创建和设置一个局部变量,将其丢失,然后您将处理 9 并设置)您想要的实际全局变量。
    • 我取出了var,还是不行!事实上,与此相关的所有变量都已删除其“var”。它仍然无法正常工作......好吧,它可以工作,但调整它几次会破坏它。
    【解决方案2】:

    哈哈!过了一会儿,我决定暂时忽略其他人所说的一切(对不起),并尝试看看我自己是否能弄清楚,我做到了!

    感谢 SolutionYogi 提供的所有帮助,但他给我的代码超出了我的专业知识;无法调试。我的解决方案不如他的漂亮(如果您可以帮助优化,请这样做),但它有效:

    function WinWidth() {
        // check width of content
        if(!window.innerWidth) {
            // you git, how dare you use ie
            return document.documentElement.clientWidth;
        } else {
            return window.innerWidth;
        }
    };
    
    function gearsAction() {
        if(WinWidth() >= 1300) {
            $('body').append(
                '<div id="gearsfloat"><a href="#" id="clickGoTop"></a></div>');
    
            $('#clickGoTop').fadeTo(0,0);
    
            $('#clickGoTop').hover(
                function() {$(this).stop().fadeTo(500,1);}, 
                function() {$(this).stop().fadeTo(500,0);});
    
        };
    };
    
    $(document).ready(function() {
        gearsAction();
    });
    
    $(window).resize(function() {
        $('#gearsfloat').remove();          
        gearsAction();
    });
    

    【讨论】:

    • 为什么gearsFload长度检查块是否为空?此外,您应该在 if 条件下使用 == 运算符。此外,正如我之前所写,您不必显式删除 #clickGoTop 链接,因为当您删除 gearsFloat div 时它会自动删除。
    • 啊,哎呀,我不小心把那个放在那里了。同时,我非常清楚每次调整大小时删除它然后重新添加它会占用 CPU 使用率。
    • 我能做些什么或者这只是最好的方法?
    猜你喜欢
    • 1970-01-01
    • 2021-07-14
    • 2016-06-08
    • 1970-01-01
    • 2020-06-05
    • 2017-10-04
    • 1970-01-01
    • 2020-07-28
    • 2016-11-15
    相关资源
    最近更新 更多