経験総括:必要に応じてJSとcssをロードする
8589 ワード
プロジェクトでは、すべてのページがSSIコマンドincludeというpublic-jsを介しています.shtmlは、関連するjs(共通のスクリプト検証プラグインカスタムコンポーネントなど)を導入するために使用されますが、インタラクティブな効果のないページではこれらのスクリプトを使用する必要がないため、スクリプトの冗長性が大きくなります(キャッシュから読み取ることができますが、使用されていないスクリプトをできるだけ減らすほうがいいです).
public-js.shtml
コンポーネントと検証プラグインのオンデマンド・ロードを実現するために、loadJsCssという関数を定義します.
//フォーム検証プラグイン動的ロードfunction loadValidator(callback){//nicevalidatorプラグインloadJsCss("/css/nicevalidator.css");loadJsCss("/js/nicevalidator.js",callback);
public-js.shtml
コンポーネントと検証プラグインのオンデマンド・ロードを実現するために、loadJsCssという関数を定義します.
/*** js css ***/
function loadJsCss(url, callback ){// js
var isJs = /\/.+\.js($|\?)/i.test(url) ? true : false;
function onloaded(script, callback){//
if(script.readyState){ //ie
script.attachEvent('onreadystatechange', function(){
if(script.readyState == 'loaded' || script.readyState == 'complete'){
script.className = 'loaded';
callback && callback.constructor === Function && callback();
}
});
}else{
script.addEventListener('load',function(){
script.className = "loaded";
callback && callback.constructor === Function && callback();
}, false);
}
}
if(!isJs){ // css
var links = document.getElementsByTagName('link');
for(var i = 0; i < links.length; i++){//
if(links[i].href.indexOf(url)>-1){
return;
}
}
var link = document.createElement('link');
link.type = "text/css";
link.rel = "stylesheet";
link.href = url;
var head = document.getElementsByTagName('head')[0];
head.insertBefore(link,head.getElementsByTagName('link')[0] || null );
}else{ // js
var scripts = document.getElementsByTagName('script');
for(var i = 0; i < scripts.length; i++){//
if(scripts[i].src.indexOf(url)>-1 && callback && (callback.constructor === Function) ){
// script
if(scripts[i].className === 'loaded'){//
callback();
}else{//
onloaded(scripts[i], callback);
}
return;
}
}
var script = document.createElement('script');
script.type = "text/javascript";
script.src = url;
document.body.appendChild(script);
onloaded(script, callback);
}
}
//フォーム検証プラグイン動的ロードfunction loadValidator(callback){//nicevalidatorプラグインloadJsCss("/css/nicevalidator.css");loadJsCss("/js/nicevalidator.js",callback);
// 组件动态加载
function loadComponent(callback){// 加载自定义组件
loadJsCss("/css/component.css");
loadJsCss("/js/component.js", callback);
}
しかし,各検証メソッドやコンポーネントの呼び出しがコールバック関数の内部に置かれることに気づき,不器用で変更も面倒である.次のようになります.
loadValidator(function(){ $('#frm').validator({...}););
loadComponent(function(){ $.Tab({...}); );
試行により、publicでのみページの元の呼び出し方式を維持できることが分かった.js共通jsファイルで同じインタフェースを定義すればいいです.(function(){ $.fn.validator = function(){ var args = arguments, self = this; loadValidator(function(){//~~~ fn.validator js css, fn.validator $.fn.validator.apply(self, args); }) } var fnames = ['Tab',"SiceSlider","SiceLvSelect","SiceSelect"]; $.each(fnames, function(i,fname){//~~~ $[fname] = function(){ var args = arguments; loadComponent(function(){ var Foo = function(){}; Foo.prototype = $[fname].prototype; var foo = new Foo(); // new , $[fname].apply(foo,args); }); } }); })(jQuery)
~~~個人的にはseaJs requireJsなどのモジュール化管理プラグインを使わない場合でも、このような方式でよいと思います.