Brandon Wang
Brandon Wang

Reputation: 3931

Repeating code block problem

I have the following code in a jQuery JavaScript document running on a page (THIS IS CURRENT):

$(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;
    }
}

This code is from my previous question, branched here simply because I think it is related.

The problem here is that the beginning is fine: it is displayed. However, if the screen is resized to less than 1300, it disappears; still good.

Now I make the window again larger than 1300. Suddenly the gear element is doubled. Another screen squish and largen and BAM, there's three now. Do this several times and it quickly adds up.

How can I stop this?

Upvotes: 0

Views: 243

Answers (2)

Brandon Wang
Brandon Wang

Reputation: 3931

Haha! After a while, I decided to ignore everything said by everyone else for a while (sorry) and try to see if I could figure it out myself, and I did!

Thanks to SolutionYogi for all the help, but the code he gave me was out of my expertise; it was impossible to debug. My solution is not as pretty as his (if you can help optimize, please do), but it works:

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();
});

Upvotes: 0

SolutionYogi
SolutionYogi

Reputation: 32233

If you hook any code in resize event, make sure that your code doesn't resize the window again. Otherwise, resize event will fire again and your code will go in infinite loop.

Also, in your code, you are not using the global gearsExists variable. Remove the 'var' at the bottom of the method to use the global variable.

function detectscreen() {

        // Your original code

        //var gearsExists = shouldExist; //This code will create new local variable. 
        gearsExists = shouldExist; 
    }
}

EDIT: Here's what I would do:

//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(); } );

EDIT:

Final working version:

http://jsbin.com/ufipu

Code:

http://jsbin.com/ufipu/edit

Upvotes: 4

Related Questions