How to getScript only once

2019-07-17 01:55发布

问题:

So this is a simplified question of this ( which im using for reference, to make this question easy...)

Using resize to getScript if above x pixels (jQuery)

If I call for a function that gets a script, to, if that function fires again, it will not load the script again.

Which in ^ that code it is.

getScript - How to only call if not already called

Is an example, but i tried that code awhile ago.

EX:

$(function() 
{
  var gotscript=false;   
  $(window).resize(function() 
  {
      //Dekstop
      if (window.innerWidth >= 768) 
      {
           if (!gotscript) 
           {
               // GET DESKTOP SCRIPT TO KEEP THINGS QUICK
               $.getScript("js/desktop.js", function() 
               { 
                   gotscript=true;
               });
           }
       }
       if (window.innerWidth < 768) 
       {
           if (window.innerWidth >= 768) 
           {
               if (!gotscript) 
               {
                   // GET DESKTOP SCRIPT TO KEEP THINGS QUICK
                   $.getScript("js/desktop.js", function() 
                   { 
                       gotscript=true;
                   });
               }
            }
       }
   }) .resize(); // trigger resize event
})

This loads the script on any window resize event.

I forgot to mention...

var $window = $(window);

function checkWidth() {
    var windowsize = $window.width();

    ////// LETS GET SOME THINGS IF IS DESKTOP 
    var $desktop_load = 0;
    if (windowsize >= 768) {
        if (!$desktop_load) {
            // GET DESKTOP SCRIPT TO KEEP THINGS QUICK
            $.getScript("js/desktop.js", function() { 
                $desktop_load = 1;
            });
        }
    }
    ////// LETS GET SOME THINGS IF IS MOBILE
    if (windowsize < 768) { 

    } 
}

// Execute on load
checkWidth();

This will work when window size is above 768, and since its only loading this function once, it will not load the script again. What can i do to make the script load if is less then 768, then goes above 768, and not load it again.

回答1:

I expect the issue is to do with getScript being asynchronous, and therefore not having access to the $desktop_load variable which is inside a separate function scope.

The fix is to make $desktop_load a global variable.

Try this,

var $desktop_load = 0; // <~~ move the variable into global scope
function checkWidth() {
    var windowsize = $window.width();

    ////// LETS GET SOME THINGS IF IS DESKTOP 
    // var $desktop_load = 0; // <~~ remove the variable from local scope

Also, this will avoid you re-setting the variable to false every time you run the checkWidth function as it will always be false before your test that way - not what you want.

p.s. it is quite unusual to use $ to prefix a variable in javascript, unless it is a cached jQuery object.



回答2:

The cache: true doesn't fully work because it merely lets the browser decide whether the file shall be loaded again or not.

You need a function such as getScriptOnce. There are several possible solutions for this type of function. I wrote such a function for my code. You can test with the Network tab in Firebug or Chrome dev tools. This just loads the same file once. You just need to copy to your files the getScriptOnce function and the global array ScriptArray.

Pay attention not to download the second time immediately after the previous, because the function just assumes the file was loaded, after the callback is called, i.e., after the file was loaded successfully.

var ScriptArray = []; //global array of urls
function getScriptOnce(url, callback) {
    //the global array doesn't have such url
    if (ScriptArray.indexOf(url) === -1){
        if (typeof callback === 'function') {
            return $.getScript(url, function(script, textStatus, jqXHR) {
                ScriptArray.push(url);
                callback(script, textStatus, jqXHR);
            });
        } else {
            return $.getScript(url, function(){
                ScriptArray.push(url);
            });
        }
    }
    //the file is already there, it does nothing
    //to support as of jQuery 1.5 methods .done().fail()
    else{
        return {
            done: function () {
                return {
                    fail: function () {}
                };
            }
        };
    }
}

/*#####################################################################*/
/*#####################################################################*/


//TEST - tries to load the same jQuery file twice
var jQueryURL = "https://code.jquery.com/jquery-3.2.1.js";
console.log("Tries to load #1");
getScriptOnce(jQueryURL, function(){
  console.log("Loaded successfully #1")
});

//waits 2 seconds and tries to load again
window.setTimeout(function(){
  console.log("Tries to load #2");
  getScriptOnce(jQueryURL, function(){
    console.log("Loaded successfully #2");
  });
}, 2000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>



回答3:

So no one came up with a good answer, maybe it was me not explaining it well. Regardless I solved my own issue.

It will load the script @ 768 or above, and only once. But if the browser loads @ less then 768 then the browser is re-sized above 768 it will load the script, once. I use this to load code blocks and images from within desktop.js by ajax. So when it wasnt working, it would re-load the content, an example was a loading gif that would show up and reset the content. The idea behind this was to stay responsive with css, and use jquery to load bigger loops when needed.

$.ajaxSetup({
  cache: true
});

var $window = $(window);
var onlyonce = 0;

function resizing() {
  var windowsize = $window.width();
  if (windowsize >= 768) {
    getdeskTop();
}};

function getdeskTop() {
  if (onlyonce === 0) {
    grabScript ();
  } else {
  };
};

function grabScript() {
  onlyonce = 1;
  $.getScript("js/desktop.js", function() { });
}

$(window).resize(resizing);
resizing();

This may be a bit ugly, but I got it to work :).