2011-07-12 3 views
1

私のウェブサイトでは、特定の要素が検出されたときに条件付きのJavaScriptの読み込みを使用したいと考えていました。最初は、新しいスクリプト要素を作成して頭に追加しました。これを行うと、ブラウザがまだjavascriptファイルをロードしていて、関数がまだ準備されていないため、そのステートメントに続くコマンドは常に失敗します。 $("element").something is not a functionJavascriptには、ロード時にコールバック関数が含まれています

2番目の問題は、スクリプトのもう1つの部分で、すでに要求されていたスクリプトを追加したかったときです。スクリプトが常にロードされているか、その時点ですでにロードされているとは思えませんでした。

私は、スクリプト/スクリプトがロードされたときにコールバックを実行するスクリプトを作成しました。これは私の関数は、今どのように見えるかです:

/* LOADING LIST */ 
var loading = new Array(); 

function include(script, callback) { 
    if (script instanceof Array) { 
     /* load an array of scripts */ 
     if (script.length > 1) { 
      var top = script.shift(); 
      include(top, function() { 
       include(script, callback); 
      }); 
     } else 
      include(script[0], callback); 
    } else { 
     var source = base_url + script; 
     var type = /[^.]+$/.exec(script); 

     if (type == "js") { 
      if ($('script[src="' + source + '"]').length == 0) { 
       /* first time script is requested */ 
       loading[script] = true; 

       var e = document.createElement('script'); 
       e.src = source; 
       e.type = "text/javascript"; 
       e.onload = function() { 
        delete loading[script]; 
        if (callback !== undefined) { 
         callback(); 
        } 
       }; 
       document.getElementsByTagName("head")[0].appendChild(e); 
      } 
      else if(script in loading) { 
       /* script is being loaded */ 
       var e = $('script[src="' + source + '"]')[0]; 
       var old = e.onload; 
       e.onload = function() { 
        old(); 
        callback(); 
       }; 
      } 
      else { 
       /* script is loaded */ 
       callback(); 
      } 
     } 
     else if (type == "css") { 
      /* no need to wait for stylesheets */ 
      if ($('link[href="' + source + '"]').length == 0) { 
       var e = document.createElement('link'); 
       e.rel = 'stylesheet'; 
       e.type = 'text/css'; 
       e.href = source; 
       document.getElementsByTagName("head")[0].appendChild(e); 
      } 
      if (callback !== undefined) { 
       callback(); 
      } 
     } 
    } 
} 

それはこのようなものをサポートしています。

if($('.wysiwyg').length>0) { 
    include(['javascript/ckeditor/ckeditor.js','javascript/ckeditor/adapters/jquery.js'], function() { 
     $(".wysiwyg").ckeditor(); 
    } 
} 

すべての言及スクリプトがロードされている場合にのみ、コールバックを実行します。

私はjavascriptについてよく知らないので、このスクリプトが短くて効率的になるかどうか疑問に思っていました。

+0

http://microjs.com/#loader –

+0

まず、あなたのHTML文書の最後にJavaScriptを置くことができますこれで、すべてのDOM要素が読み込まれ、アクセスできる状態になります。第二に、条件付きでスクリプトを読み込むのはなぜですか?スクリプトが本当に巨大でない限り、パフォーマンス上の理由からこれを行う必要はありません。それらを読み込むだけで、ブラウザーはそれらを必要とする他のページの準備が整うでしょう。 –

答えて

1

jQueryから$ .getScript()を使用する必要があります。それはあなたがしていることをします。また、$ .ajaxSetup({async:false})と同時にロードを同期させることもできます。私はのような機能を使用し

$.ajaxSetup({async: false}); 
$.getScript('myClass.js'); 
imFromMyClass(); 

例えば

function require(module) { 
    $.ajaxSetup({async: false, cache: true}); 

    if (window['matchExtension'] === undefined) { 
     window['matchExtension'] = function(filename, extensions) { 
      return (getFileExtension(filename).match(new RegExp("(" + extensions + ")", "ig"))); 
     } 
    } 

    if (typeof module == 'string') { 
     var tmp = ""; 
     if (matchExtension(module, "htm*") || matchExtension(module, "txt")) { 
      tmp = $.get(module).responseText; 
      return tmp; 
     } else if (matchExtension(module, "css")) { 
      var obj = $.get(module); 
      if (obj.status == 404) return ''; 

      tmp = obj.responseText; 
      var el = document.createElement('style'); 
      el.type = 'text/css'; 
      el.media = 'screen'; 
      document.getElementsByTagName('head')[0].appendChild(el); 
      if(el.styleSheet) el.styleSheet.cssText = tmp;// IE method 
      else el.appendChild(document.createTextNode(tmp));// others 
     } else if (module.EndsWith("/")) { 
      return $.get(module).responseText; // directory listing 
     } else { 
      $.getScript(module); 
     } 
    } else { 
     $.ajaxSetup({async: false, cache:true}); 
     for (var i =0, len = module.length; i < len; i++) $.getScript(module[i]); 
    } 
    return true; 
} 

var content = require('someFile.html'); 
require('someStyle.css'); 
require('someClass.js'); 
require(['class1.js', 'class2.js', 'class3.js']); 

JavaScriptファイルの配列をロードするときに、あなたが行うことができます一つの他の改善は、その連結し、サーバースクリプトにリストを提供することですそれらはすべて同じ応答内にあります

+0

'require(['class1.js'、 'class2.js'、 'class3.js']);はよりエレガントではありませんか? – mplungjan

+0

私はgetScriptを試しましたが、同じjavascriptが複数回リクエストされたときに問題が発生しました。 – Jens

関連する問題