views:

129

answers:

2

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?

+4  A: 

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

SolutionYogi
So how do I make sure that it doesn't fire into infinite? I have changed it to a global variable, and it doesn't fire infinitely now, but each time the page is resized smaller and larger again, it creates it again.After a while of making the window bigger and smaller again it looks messed up.
Brandon Wang
Good catch on the global variable getting redefined. +1
Jose Basilio
+1, but big emphasis on that "var gearsExists", it prevents the loop ever closing.
annakata
@Brandon - just remove the "var" as per Yogi's sample. You're creating and setting a local variable with that "var", lose it and you'll be addressing 9and setting) the actual global you mean to.
annakata
I have taken out the var and it still does not work! In fact, everything that's related to this that is a variable has had its 'var' taken out. It still doesn't work... well, it works but resizing it a few times breaks it.
Brandon Wang
I went ahead and updated the question with my current code.
Brandon Wang
I have updated my post to reflect how I would do it.
SolutionYogi
For some reason, that code doesn't work even though I copy and pasted it exactly (I originally moved the ready() item into my own already existing one).Is it anything I am doing wrong? Now nothing happens.
Brandon Wang
Actually, there were few bugs which I fixed. Could you please copy the code again? I typed the code without using an editor, so there could be syntax error. Could you run the code in firebug and see if there are any errors reported?
SolutionYogi
Dreamweaver doesn't show any problems, and opening the page in Firefox w/ Firebug doesn't do anything (I'm not sure exactly how to "run" code in Firebug; I develop in Chrome)
Brandon Wang
Let me try to create a working version and then post a link.
SolutionYogi
All right; thank you so much!
Brandon Wang
I have posted the working demo on jsbin.com and updated the code on this post.
SolutionYogi
Sorry to keep on annoying you, but your example doesn't show anything on my side. The first time I loaded it there was a "Go to top" text there but now there is nothing.
Brandon Wang
Here's a page with virtually nothing on it except for code: http://jsbin.com/onogu
Brandon Wang
Make that http://jsbin.com/abolo; I am very sorry to annoy you like this, but I really want it to work.
Brandon Wang
Are you sure? On the jsbin code, I have changed the targetWidth to '500', so if your browser width is more than 500, it will show Go To Top link otherwise it will hide it.
SolutionYogi
Try this:http://jsbin.com/uruke
SolutionYogi
OK, after clearing my cache, it does behave as expected but unfortunetely once it is refreshed, it dies and won't come back. Why? In the meantime I'll try to implement the code.
Brandon Wang
Try to create another JSBIN having the minimum code to show the problem. For me, the last two links which I posted are working fine.
SolutionYogi
Is there any way we can arrange a Skype chat / Yuuguu screenshare so you can see what I'm doing? I don't want you to be a consultant or anything, but I can't figure this out and I'm confident I can fix it in a few minutes with your help.
Brandon Wang
Unfortunately, I can't chat online. See if you can use Firefox with FireBug plugin to debug this problem. Good luck.
SolutionYogi
A: 

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();
});
Brandon Wang
Why is the gearsFload length check if block empty? Also, you should use == operator in that if condition. Also, as I wrote earlier, you don't have to remove #clickGoTop link explicitly as it will be automatically removed when you remove gearsFloat div.
SolutionYogi
Ah, oopsies, I accidentally left that there. In the meantime, I'm very aware that it takes up CPU usage to remove it each time it is resized and then add it back.
Brandon Wang
Anything I can do about that or is that just the best way?
Brandon Wang