« 1 2
Autor Zpráva
Witiko
Profil
Menší update, místo vytvoření veřejné metody _load, kterou volají stejně jen metody objektu, jsem přesunul funkci _load přímo do konstruktoru objektu jako privátní metodu load, ke které může přistupovat pouze veřejná metoda load, jejíž definice se za účelem možnosti přístupu k privátní metodě load také přesunula do konstruktoru objektu.

/*
  
    DScript - Dynamic script loading library
    Copyright (C) 2010  Vít Novotný

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  
    How to use:
      We create an instance of the dscript class.
      We call the dscript.prototype.load() function with these arguments:
        String url, Number timeout (in milliseconds), function callback(boolean loaded, int time (in milliseconds) ) {}

*/

function dscript() {
  this.object = false;
  this.engaged = false;
  // Creating a two-dimensional Array.
  this.queue = new Array();
  // Here are the URLs stored.
  this.queue[0] = new Array();
  // Here are the passed timeouts stored.
  this.queue[1] = new Array();
  // Here are the callback functions stored.
  this.queue[2] = new Array();

  /*
      Definition of the public load function in the prototype constructor
      method so that it still could access the private load method.
  */

  this.load = function(url, timeout, callback) {
  
    /*
        Firstly we check if the previous script has already been loaded.
        If so, we may continue and define some of the variables.
    */
  
    if(!this.engaged) {
      this.engaged = true;
      this.time = new Date().getTime();
      var that = this;
      var loaded = false;
      
    /*
        If the script element haven't been attached to the document yet, we will
        create it and attach the onload and the onreadystatechange (MSIE) events
        to it. Then we append it as a child to the head element.
    */
  
      if(!this.object) {
        this.object = document.createElement("script");
        this.object.type = "text/javascript";
        this.object.src = url;
        this.object.onload = function(script) {
          if(loaded) return;
          loaded = true;
          window.clearTimeout(timeout);
          if(that.queue[0].length == 0) that.engaged = false;
          else load(that.queue[0][0],that.queue[1][0],that.queue[2][0]);
          if(callback && typeof callback == "function") callback(true, new Date().getTime() - that.time);
        };
        this.object.onreadystatechange = function() {
          if(loaded || (this.readyState != "loaded" && this.readyState != "complete")) return;
          loaded = true;
          window.clearTimeout(timeout);
          if(that.queue[0].length == 0) that.engaged = false;
          else load(that.queue[0][0],that.queue[1][0],that.queue[2][0]);
          if(callback && typeof callback == "function") callback(true, new Date().getTime() - that.time);
        };
        timeout = window.setTimeout(function(){
          loaded = true;
          if(that.queue[0].length == 0) that.engaged = false;
          else load(that.queue[0][0],that.queue[1][0],that.queue[2][0]);
          if(callback && typeof callback == "function") callback(false, timeout);
        },timeout);
        this.object = document.getElementsByTagName("head")[0].appendChild(this.object);
        
    /*
        If the "physical" script element have already been attached to the document,
        we will just create a new element with an altered src attribute and replace
        the old element for the new one (simply changing the src attribute in the
        existing element doesn't work, the new script is not loaded to the document)
    */
  
      } else {
        var object = document.createElement("script");
        object.type = "text/javascript";
        object.src = url;
        object.onload = function(script) {
          if(loaded) return;
          loaded = true;
          window.clearTimeout(timeout);
          if(that.queue[0].length == 0) that.engaged = false;
          else load(that.queue[0][0],that.queue[1][0],that.queue[2][0]);
          if(callback && typeof callback == "function") callback(true, new Date().getTime() - that.time);
        };
        object.onreadystatechange = function() {
          if(loaded || (this.readyState != "loaded" && this.readyState != "complete")) return;
          loaded = true;
          window.clearTimeout(timeout);
          if(that.queue[0].length == 0) that.engaged = false;
          else load(that.queue[0][0],that.queue[1][0],that.queue[2][0]);
          if(callback && typeof callback == "function") callback(true, new Date().getTime() - that.time);
        };
        timeout = window.setTimeout(function(){
          loaded = true;
          if(that.queue[0].length == 0) that.engaged = false;
          else load(that.queue[0][0],that.queue[1][0],that.queue[2][0]);
          if(callback && typeof callback == "function") callback(false, timeout);
        },timeout);
        document.getElementsByTagName("head")[0].replaceChild(object, this.object);
        this.object = object;
      }
      
    /*
        Should the previous script not've been loaded yet, the variables will be stored in the queue.
    */
  
    } else {
      this.queue[0][this.queue[0].length] = url;
      this.queue[1][this.queue[1].length] = timeout;
      this.queue[2][this.queue[2].length] = callback?callback:false;
    }
  }
  
  /*
      Definition of the private load method accessable by the public
      load method only. This method handles the queued scripts.
  */
  
  var load = function(url, timeout, callback) {
    this.time = new Date().getTime();
    var loaded = false;
    var that = this;
    var object = document.createElement("script");
    object.type = "text/javascript";
    object.src = url;
    object.onload = function(script) {
      if(loaded) return;
      loaded = true;
      window.clearTimeout(timeout);
      that.queue[0] = that.queue[0].slice(1);
      that.queue[1] = that.queue[1].slice(1);
      that.queue[2] = that.queue[2].slice(1);
      if(that.queue[0].length == 0) that.engaged = false;
      else load(that.queue[0][0],that.queue[1][0],that.queue[2][0]);
      if(callback && typeof callback == "function") callback(true, new Date().getTime() - that.time);
    };
    object.onreadystatechange = function() {
      if(loaded || (this.readyState != "loaded" && this.readyState != "complete")) return;
      loaded = true;
      window.clearTimeout(timeout);
      that.queue[0] = that.queue[0].slice(1);
      that.queue[1] = that.queue[1].slice(1);
      that.queue[2] = that.queue[2].slice(1);
      if(that.queue[0].length == 0) that.engaged = false;
      else load(that.queue[0][0],that.queue[1][0],that.queue[2][0]);
      if(callback && typeof callback == "function") callback(true, new Date().getTime() - that.time);
    };
    timeout = window.setTimeout(function(){
      loaded = true;
      that.queue[0] = that.queue[0].slice(1);
      that.queue[1] = that.queue[1].slice(1);
      that.queue[2] = that.queue[2].slice(1);
      if(that.queue[0].length == 0) that.engaged = false;
      else load(that.queue[0][0],that.queue[1][0],that.queue[2][0]);
      if(callback && typeof callback == "function") callback(false, timeout);
    },timeout);
    document.getElementsByTagName("head")[0].replaceChild(object, this.object);
    this.object = object;
  }
}
« 1 2

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: