質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.53%

javascriptで外部ファイル(js、css)を一括登録する方法

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 2,542

cti1650

score 9

JavaScript初心者ですが、ローカルで使用するサイトを作成する際、ソースを極力短く済ませるために、外部ファイルを読み込む処理をjsファイルにまとめたいのですが、jQueryとjQuery mobileを読み込むと正常にサイトが表示されません。

一括登録にすることで、サイトの表示速度が遅くなるとは思いますが、今回は、簡潔にコードを記述することに重点を置いておりますので、下記のコードでの改善点等をご教示願います。

汚いコードで申し訳御座いませんが、宜しくお願い致します。

function viewportSet(){
    var metalist = document.getElementsByTagName('meta');
    var hasMeta = false;
    for(var i = 0; i < metalist.length; i++) {
        var name = metalist[i].getAttribute('name');
        if(name && name.toLowerCase() === 'viewport') {
            metalist[i].setAttribute('content', 'width=device-width,initial-scale=1.0');
            hasMeta = true;
            break;
        }
    }
    if(!hasMeta) {
        var meta = document.createElement('meta');
        meta.setAttribute('name', 'viewport');
        meta.setAttribute('content', 'width=device-width,initial-scale=1.0');
        document.getElementsByTagName('head')[0].appendChild(meta);
    }
}

function SetJSText(str){
    var script = document.createElement('script');
    script.appendChild(document.createTextNode(str));
    document.body.appendChild(script);
}

function SetJSURL(url){
    // var script = document.createElement('script');
    // // Data URI
    // script.type = "text/javascript";
    // script.src = url;
    // document.head.appendChild(script);
    $.getScript(url);
}
function SetCSSURL(url){
    // var link = document.createElement('link');
    // link.type = 'text/css';
    // link.rel = "stylesheet";
    // link.href = url;
    // document.head.appendChild(link);
    $("head").append("<link>");
    var css = $("head").children(":last");
    css.attr({
        rel: "stylesheet",
        type: "text/css",
        href: url
    });
}

function jQueryChk(){
    //SetJSURL("//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js");
}


jQueryChk();
(function($) {
SetCSSURL("//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css");
SetJSURL("//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js");
})(jQuery);
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Lhankor_Mhy

    2016/02/29 14:06

    『正常にサイトが表示されません』とは具体的に言うと何が起こりますか? エラーメッセージなどご提示可能でしょうか。

    キャンセル

  • cti1650

    2016/02/29 14:29 編集

    jQuery mobileのスタイルが正しく反映されず、エラーメッセージも表示されません。

    キャンセル

回答 4

checkベストアンサー

+2

jQueryを使ってロードしている部分がありますが、jQueryを読み込む前に実行することは当然できません。

そして、jQueryChk();で正しくロードできたとしても、そのjQueryがJavaScriptから使えるようになるのは、続く無名関数ブロックを実行したです。

結論:jQuery本体も含めてJavaScriptからロードしたいなら、すべてjQueryを使わずに書くことをおすすめします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/29 14:45

    早速のご回答ありがとうございます。
    質問のコードで言いますと、SetJSURL関数と、SetCSSURL関数のコメントアウトしている箇所の通りでは、間違いでしょうか?

    また、jQueryプラグインは、(function($){...})(jQuery)内で記述をすれば実行可能と言う事でしょうか?

    重ねて申し訳御座いませんが、ご教示お願い致します。

    キャンセル

  • 2016/02/29 15:24

    (その1)JS/CSSのロードは、コメントアウト内のコードで特に問題なさそうです。

    (その2)jQueryを使ったコードを書く場合、jQueryの後にそのコードを含むファイルをロードさせるのが楽です(どうしてもしたくないなら、タイマーを回してjQueryがロードされたか監視する、というようなコードが必要で、このままただ無名関数を書くだけでは動きません)。

    キャンセル

  • 2016/02/29 16:43 編集

    下記のサイトを参考にしてjQueryを読み込むscriptタグにイベント処理を追加して待機させてプラグインを実行すれば、出来そうな気がしてきました。

    JS備忘録:script要素でonload
    http://blog.mach3.jp/2010/03/21/js-script-onload.html


    function onloaded(e){
    alert(e.target.src + " is successfully loaded");
    }
    var ele = document.createElement("script");
    ele.src = "hogehoge.js";
    ele.onload = onloaded;
    ele.onreadystatechange = function(){
    if(this.readyState=="loaded"||this.readyState=="complete"){
    onloaded({type:"load", target:this});
    }
    }
    document.body.appendChild(ele);

    キャンセル

  • 2016/02/29 17:39

    一度、ご教示頂いた事を反映してみます。

    ご回答ありがとうございました。

    キャンセル

0

引数に渡している文字列のURLに
httpもしくはhttpsをつけてもダメでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/29 14:36

    ご回答ありがとうございます。
    まだ試していなかったので、今晩試してみます。

    キャンセル

0

試しに以下の2通りで試してみました。

  • maisumakunさんの回答内容を反映したバージョン
    以下の場合は、jQueryロード後、順次プラグインが実行されるため、
    スタイルが適用される前の状態で一度表示され、スタイル適用までに1秒近く表示に時間がかかりました。
(function(){
    var DoSet = 
        {
            JSText : function(str){
                var script = document.createElement('script');
                // テキストノード
                script.appendChild(document.createTextNode(str));
                document.body.appendChild(script);
            },
            JS : function(url){
                var script = document.createElement('script');
                // Data URI
                script.type = "text/javascript";
                script.src = url;
                document.head.appendChild(script);
            },
            CSS : function(url){
                var link = document.createElement('link');
                link.type = 'text/css';
                link.rel = "stylesheet";
                link.href = url;
                document.head.appendChild(link);
            },
            $JS : function(url){
                $.getScript(url);
            },
            $CSS : function(url){
                $("head").append("<link>");
                var css = $("head").children(":last");
                css.attr({
                    rel: "stylesheet",
                    type: "text/css",
                    href: url
                });
            },
            WR : function(code){
                document.write(code);
            }
        };

    function doSetting(){
        DoSet.CSS("//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css");
        DoSet.JS("//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js");
    }

    var metalist = document.getElementsByTagName('meta');
    var hasMeta = false;
    for(var i = 0; i < metalist.length; i++) {
        var name = metalist[i].getAttribute('name');
        if(name && name.toLowerCase() === 'viewport') {
            metalist[i].setAttribute('content', 'width=device-width,initial-scale=1.0');
            hasMeta = true;
            break;
        }
    }
    if(!hasMeta) {
        var meta = document.createElement('meta');
        meta.setAttribute('name', 'viewport');
        meta.setAttribute('content', 'width=device-width,initial-scale=1.0');
        document.getElementsByTagName('head')[0].appendChild(meta);
    }

    var url = "//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js";
    var script = document.createElement('script');
    // Data URI
    script.type = "text/javascript";
    script.src = url;
    script.onload = doSetting;
    script.onreadystatechange = function(){
        if(this.readyState=="loaded"||this.readyState=="complete"){
            doSetting();
        }
    }
    document.head.appendChild(script);
})();
  • 速度重視で作成し直したバージョン
    以下の場合は、HTML読込時に、随時反映されるため、
    スタイル適応までに時間がかからず、
    直接HTMLにSCRIPTタグを記述した時とほぼ変わらない表示速度で、
    表示する事が出来ました。

更に、jsファイルのコードも簡略化出来ましたので、
こちらのバージョンを使用していこうと思います。

(function(){
    var DoSet = 
        {
            WR : function(str){
                str ? document.write(str) : "";
                return this;
            },
            init : function(){
                return this.WR("<meta charset='UTF-8'>")
                .WR("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />")
                .WR("<meta name='viewport' content='width=device-width, initial-scale=1'>");
            },
            JS : function(url){
                return url ? this.WR("<script type='text/javascript' src='"+url+"'></script>") : this;
            },
            CSS : function(url){
                return url ? this.WR("<link rel='stylesheet' href='"+url+"'>") : this;
            }
        };
    DoSet.init()
    .JS("//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js")
    .CSS("//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css")
    .JS("//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js");
})();

この度は、アドバイスを頂いた事で、別の角度からプログラムを見直す事が出来ました。
ご回答頂きました2人ともどうも有難う御座いました。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

上記のプログラムをさらに改変しました。

外部JSファイル内で、下記の機能を実行可能にしました。

Setting.jQuery([url]) ・・・ jQueryファイルを読み込み(URL任意指定)

// デフォルトで設定されているjQueryファイルを実行
Setting.jQuery();

// 指定したURLのjQueryファイルを実行
Setting.jQuery(url);


Setting.mobile([css],[js]) ・・・ jQuery mobileファイルを読み込み(css,jsURL任意指定)
Setting.ui([css],[js]) ・・・ jQuery uiファイルを読み込み(css,jsURL任意指定)

// デフォルトで設定されているjQuery_uiファイルを実行
Setting.jQuery().ui();

// 指定したURLのjQuery_uiファイルを実行
Setting.jQuery().ui(css,js);


Setting.wr(str) ・・・ document.write(str)を実行

// HTML読み込み途中で、タグを書き込み
Setting.wr('<div></div>');

// 以下と同一
document.write('<div></div>');


Setting.css(arr) ・・・ CSSファイルを読み込み(URL,配列任意)
Setting.js(arr) ・・・ JSファイルを読み込み(URL,配列任意)
Setting.file(arr) ・・・ 外部ファイルを読み込み(URL,配列任意、css,jsファイルのみ実行可能)

// 外部ファイルをURLを指定して読み込み
Setting.css('./test.css');

// 複数の外部ファイルをURLを指定して一括読み込み
var arr = [ './test1.css' , './test2.css' ]
Setting.css(arr);


Setting.load(func) ・・・ window.onLoadイベント発生時に実行する処理を設定

// HTML読み込み完了時の処理を追加
Setting.load(function(){
     alert('test');
});

// 複数処理 追加可能
Setting.load(function(){
     alert('test1');
}).load(function(){
     alert('test2');
});

!!! 注意事項 !!!

  • Setting以降はメソッドチェーンが可能です。
  • 既にjQueryが定義されている場合は、
    新たにjQueryを再定義する事は出来ません。
<!DOCTYPE html>
<html>
<head>
    <title>linkSetup</title>
    <script type="text/javascript" src="linkSetup.js"></script>
    <script type="text/javascript">
        $(function() {
            ・・・jQuery 本文
        })();
    </script>
</head>
<body>
    <!-- ぺージ -->
    <div data-role="page">
        <!-- ヘッダー -->
        <div data-role="header">
            <h1>linkSetup</h1>
        </div>
        <!-- コンテンツ -->
        <div data-role="content">
            <div class="ui-field-contain">
                <input type="file" id="fileItem" >
            </div>
            <div id="val"></div>
        </div>
        <!-- フッター -->
        <div data-role="footer">
            <h4><div id="test"></div></h4>
        </div>
    </div>
</body>
</html>
(function(){
    var Setting = (function(){
        var def = {
            wr : function(str){
                str ? document.write(str) : "";
                return this;
            },
            init : function(){
                return this.wr("<meta charset='UTF-8'>")
                .wr("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />")
                .wr("<meta name='viewport' content='width=device-width, initial-scale=1'>");
            },
            load : function (func){  
                var oldload = window.onload;  
                if(typeof window.onload != 'function'){  
                    window.onload = func;  
                }else{  
                    window.onload = function(){  
                        oldload();  
                        func();  
                    }  
                }
                return this;
            },
            jQuery : function(URL){
                var _URL = URL ? URL : "//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js";
                return (typeof jQuery == "undefined") ? this.wr("<script type='text/javascript' src='"+_URL+"'></script>") : this;
            },
            ui : function(css,js){
                var _ui = {
                            css : css ? css : "//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/base/jquery-ui.css",
                            js : js ? js : "//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"
                };
                return (typeof jQuery == "undefined") ? this.file([ _ui.css , _ui.js ]) : this;
            },
            mobile : function(css,js){
                var _mob = {
                            css : css ? css : "//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css",
                            js : js ? js : "//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js"
                };
                return (typeof jQuery == "undefined") ? this.file([ _mob.css , _mob.js ]) : this;
            },
            js : function(urlarr){
                var item;
                var vArr = (urlarr instanceof Array) ? urlarr : [ urlarr , ""];
                for (var i = 0; i < vArr.length; i++) {
                    item = vArr[i];
                    item ? this.wr("<script type='text/javascript' src='"+item+"'></script>") : this;
                }
                return this;
            },
            css : function(urlarr){
                var item;
                var vArr = (urlarr instanceof Array) ? urlarr : [ urlarr, ""];
                for (var i = 0; i < vArr.length; i++) {
                    item = vArr[i];
                    item ? this.wr("<link rel='stylesheet' href='"+item+"'>") : this;
                }
                return this;
            },
            file : function(arr){
                var item;
                var vArr = (arr instanceof Array) ? arr : [ arr, ""];
                for (var i = 0; i < vArr.length; i++) {
                    item = vArr[i];
                    if (item.slice(-3) == ".js") {
                        this.js(item);
                    } else {
                        if (item.slice(-4) == ".css") {
                            this.css(item);
                        }
                    }
                }
                return this;
            }
        };
        return def.init();
    })();

    Setting.jQuery().mobile()
    .load(function(){
        alert('test1')
    }).load(function(){
        alert('test2')
    });
})();

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.53%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる