javascriptのwindow.onloadについて教えてください。


外部サイト(ブログや他サイト)で利用する簡単なツールを作っています。

<script type="text/javascript" src="http://www.example.com/hogeA.js"></script>
といったタグを貼り付けて使うつもりです。

このツールはjqueryを使っているのですが、外部サイトがjqueryを使っているとは限らないので、hogeA.jsでjqueryをロードする必要があります。

window.onload=function() {
var script01 = document.createElement('script') ;
script01.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js' ;
script01.type = 'text/javascript' ;
document.getElementsByTagName('head')[0].appendChild(script01) ;
}

上記のような形で試しているのですが、上記コード+確認用のコード$("#hoge").text("OK");で動かしても"OK"が表示されません。window.onloadの上部にdocument.write("-<略>-");を記述するとjqueryがロードされますが、1回目はjqueryがない状態で動作し、2回目以降はjqueryが動作している想定通りの動きになります。

hogeA.jsを読んだタイミングでjqueryをロードさせるにはどのようにしたらよいでしょうか?jqueryを読み込んだ後に外部HTMLをロードさせたいと考えています。

よろしくお願いします。

回答の条件
  • URL必須
  • 1人5回まで
  • 13歳以上
  • 登録:2010/09/18 01:47:28
  • 終了:2010/09/19 00:19:32

ベストアンサー

id:pacochi No.4

ぱこち回答回数246ベストアンサー獲得回数1112010/09/18 20:26:35

ポイント70pt

先ほど回答したサイトのスクリプトを少しいじって、document.write 相当の動作をするようにしました。

(function(scripts, callback, errorback) {

    var current_position = (function (e) { if(e.nodeName.toLowerCase() == 'script') return e; return arguments.callee(e.lastChild) })(document).parentNode;

    if (typeof errorback != 'function')
        errorback = function(url) { alert('jsloader load error: ' + url) };

    var load = function(url) {
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.charset = 'utf-8';
        var current_callback;
        if (scripts.length) {
            var u = scripts.shift();
            current_callback = function() { load(u) }
        } else {
            current_callback = callback;
        }
        if (window.ActiveXObject) { // IE
            script.onreadystatechange = function() {
                if (script.readyState == 'complete' || script.readyState == 'loaded')
                    current_callback({ type:"load", target:this });
            }
        } else {
            script.onload = current_callback;
            script.onerror = function() { errorback(url) };
        }
        script.src = url;
        current_position.appendChild(script);
    }

    load(scripts.shift());
})(['http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'], function(e) { 

    $(function(){ // jQuery のおまじない


// この辺にあなたのしたい処理を書いて下さい。


        $(e.target).before('ここに document.write で書くつもりだった中身を書いて下さい。<a href="./"><img src="./test.png" /></a> とか。');

    }); // jQuery のおまじない終点

});

要らぬお節介かも知れませんが、もしお作りになるツールが、ブログパーツのような不特定のページから読み込まれるようなものでしたら、window.onload や document.write は使用しない方が良いと思います。

window.onload は他のスクリプトの onload イベントを上書きしてしまうかもしれません。 (addEventListener などを使うのなら話は別ですが。)

また、document.write は、ページによっては使えないことがあるからです。 (具体的には application/xhtml+xml のページで使えません。)

id:tmshare

ありがとうございます。サンプルまで作っていただき感謝です。


> 要らぬお節介かも知れませんが、もしお作りになるツールが、ブログパーツのような不特定のページから読み込まれる

> ようなものでしたら、window.onload や document.write は使用しない方が良いと思います。


お節介どころか、ずばりブログなどのサイトで使うためのツールを意識していました…。ご指摘いただき非常に助かります。

javascriptはさわり始めたばかりで勉強不足ですので、いただいたサンプルを元に勉強したいと思います。

試してみたところjQueryの動作は問題なさそうです。.beforeの箇所にpタグを入れて文字を出力できました。

$(e.target).before(~)にaタグを記述し、「class="nyroModal"」をタグ内に追記してjquery.nyroModalを使用しているのですが、ただのリンクとして画面遷移します。上記スクリプトの後にdocument.writeをべた書きしたスクリプトを流すと、そちらではちゃんとnyroModalが使われた動きになります。

document.writeはご指摘いただきましたので使うつもりはないのですが、動作に差があるのはなぜかなと悩んでいます。

度々で恐縮ですがもしご存じでしたら教えていただけると助かります。

2010/09/18 21:46:26

その他の回答(3件)

id:akumasyougun666 No.1

akumasyougun666回答回数94ベストアンサー獲得回数02010/09/18 01:48:47

大変申し訳ございませんが、あなたはこの質問に回答することはできません。

http://q.hatena.ne.jp

id:GoldenDawn No.2

GoldenDawn回答回数426ベストアンサー獲得回数812010/09/18 11:20:07

ポイント30pt

テストコードはこのような感じでしょうか。

window.onload=function() {
  var script01 = document.createElement('script') ;
  script01.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js' ;
  script01.type = 'text/javascript' ;
  document.getElementsByTagName('head')[0].appendChild(script01) ;
  $("#hoge").text("OK") ;
}
script>

appendChild した場合、jquery.min.js の読み込み完了前に $("#hoge").text("OK") ; を実行しようとするためうまくいきません。

setTimeout(function(){$("#hoge").text("OK")}, 1000) ;

のように遅らせるとうまくいく場合もありますが、サーバの反応が悪いと間に合わない場合もあり得ます。

次のページに読み込みを待つ例があります。

http://d.hatena.ne.jp/holidays-l/20061207/p1

id:tmshare

ありがとうございます。読み込み完了前にjqueryを使おうとしていたから表示されなかったのですね。原因がわかってすっきりしました。

setTimeoutで適当な待ちをいれたら問題なく表示できました。

リンクしてもらったURLから例を見たところ、下記の更新版があったのでこれで試してみました。

http://d.hatena.ne.jp/holidays-l/20070923/p1

問題なく動作するようだったのでこれを使おうかと思っていたところ、Google Codeからは問題なく読み込めるのですが、なぜか他のライブラリ(nyroModal)を任意のURLに指定すると読み込めませんでした。原因に関しては不明ですが、前述の方法で読み込みが出来ていますのでこれで進めてみたいと思います。

2010/09/18 16:57:10
id:pacochi No.3

ぱこち回答回数246ベストアンサー獲得回数1112010/09/18 15:06:39

ポイント30pt

現在だと、この例で言うと script01 の onload イベントや onreadystatechange イベントを見て、読み込み完了を知るような方法がよく使われているみたいです。


Hatena::Let でも、さっくりしたのが使われていたなあと思って調べたら、開発者さんのブログに載っていました。


上記の記事にあるスクリプトの後に

window.onload = function() {
 __jsloader__(['http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'], function() {

  $("#hoge").text("OK");

 });
};

と書けば、「OK」が表示されました。

id:tmshare

ありがとうございます。提示いただいたスクリプトで読み込めました。jQuery以外のライブラリ(nyroModal)も問題なく読み込めています。


このスクリプトで読み込んだ後にdocument.writeで表示する画像やリンクなどを作ろうとしたのですが、今度はここでうまくいっていません。別スクリプトにdocument.writeをべた書きして外部サイト側で2つのスクリプトを読み込ませるとうまく表示いきますが、できれば余計なスクリプトファイルは作りたくないと思っています。

もしよろしければどこに記述すればよいか教えていただけると助かります。

2010/09/18 20:33:15
id:pacochi No.4

ぱこち回答回数246ベストアンサー獲得回数1112010/09/18 20:26:35ここでベストアンサー

ポイント70pt

先ほど回答したサイトのスクリプトを少しいじって、document.write 相当の動作をするようにしました。

(function(scripts, callback, errorback) {

    var current_position = (function (e) { if(e.nodeName.toLowerCase() == 'script') return e; return arguments.callee(e.lastChild) })(document).parentNode;

    if (typeof errorback != 'function')
        errorback = function(url) { alert('jsloader load error: ' + url) };

    var load = function(url) {
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.charset = 'utf-8';
        var current_callback;
        if (scripts.length) {
            var u = scripts.shift();
            current_callback = function() { load(u) }
        } else {
            current_callback = callback;
        }
        if (window.ActiveXObject) { // IE
            script.onreadystatechange = function() {
                if (script.readyState == 'complete' || script.readyState == 'loaded')
                    current_callback({ type:"load", target:this });
            }
        } else {
            script.onload = current_callback;
            script.onerror = function() { errorback(url) };
        }
        script.src = url;
        current_position.appendChild(script);
    }

    load(scripts.shift());
})(['http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'], function(e) { 

    $(function(){ // jQuery のおまじない


// この辺にあなたのしたい処理を書いて下さい。


        $(e.target).before('ここに document.write で書くつもりだった中身を書いて下さい。<a href="./"><img src="./test.png" /></a> とか。');

    }); // jQuery のおまじない終点

});

要らぬお節介かも知れませんが、もしお作りになるツールが、ブログパーツのような不特定のページから読み込まれるようなものでしたら、window.onload や document.write は使用しない方が良いと思います。

window.onload は他のスクリプトの onload イベントを上書きしてしまうかもしれません。 (addEventListener などを使うのなら話は別ですが。)

また、document.write は、ページによっては使えないことがあるからです。 (具体的には application/xhtml+xml のページで使えません。)

id:tmshare

ありがとうございます。サンプルまで作っていただき感謝です。


> 要らぬお節介かも知れませんが、もしお作りになるツールが、ブログパーツのような不特定のページから読み込まれる

> ようなものでしたら、window.onload や document.write は使用しない方が良いと思います。


お節介どころか、ずばりブログなどのサイトで使うためのツールを意識していました…。ご指摘いただき非常に助かります。

javascriptはさわり始めたばかりで勉強不足ですので、いただいたサンプルを元に勉強したいと思います。

試してみたところjQueryの動作は問題なさそうです。.beforeの箇所にpタグを入れて文字を出力できました。

$(e.target).before(~)にaタグを記述し、「class="nyroModal"」をタグ内に追記してjquery.nyroModalを使用しているのですが、ただのリンクとして画面遷移します。上記スクリプトの後にdocument.writeをべた書きしたスクリプトを流すと、そちらではちゃんとnyroModalが使われた動きになります。

document.writeはご指摘いただきましたので使うつもりはないのですが、動作に差があるのはなぜかなと悩んでいます。

度々で恐縮ですがもしご存じでしたら教えていただけると助かります。

2010/09/18 21:46:26
  • id:pacochi
    すみません、書き忘れました。
    4番目の回答に記述したスクリプトをそのまま hogeA.js として保存して、「この辺にあなたのしたい処理を書いて下さい。」と書かれているあたりにツールのスクリプトを書き込んで下さい。
  • id:tmshare
    補足ありがとうございます。
    回答に返信として記述しましたが、画像表示やリンクもちゃんと表示されました。ありがとうございます。

    ただ、別ライブラリとして読み込んでいるnyroModalライブラリがうまく動かず悩んでいます。

    hogeA.jsの$(e.function).beforeに記述した「aタグ内のclass="nyroModal"」が利かずただのリンクとなってしまい、連続してhogeB.js(jsロードなし。画像表示とリンクをdocument.write)だとnyroModalが利きます。

    $(e.function).beforeでの動作とdocument.writeでの動作の違いがいまいちわかっていないので、もし可能でしたら教えていただけると助かります。
    度々で恐縮ですがよろしくお願いいたします。
  • id:pacochi
    すみません、ちょっとスクリプトにミスがありました。
    二つ以上の js ファイルをロードした時に表示位置がずれていました。
    以下のものに差し替えて下さい。
    (jquery.nyroModal-1.6.2.min.js のパスは適宜変えて下さい。)


    (function(scripts, callback, errorback) {

    var current_position = (function (e) { if(e.nodeName.toLowerCase() == 'script') return e; return arguments.callee(e.lastChild) })(document);

    if (typeof errorback != 'function')
    errorback = function(url) { alert('jsloader load error: ' + url) };

    var load = function(url, current_position) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.charset = 'utf-8';
    var current_callback;
    if (scripts.length) {
    var u = scripts.shift();
    current_callback = function() { load(u, current_position) }
    } else {
    current_callback = callback;
    }
    if (window.ActiveXObject) { // IE
    script.onreadystatechange = function() {
    if (script.readyState == 'complete' || script.readyState == 'loaded')
    current_callback({ type:"load", target:this });
    }
    } else {
    script.onload = current_callback;
    script.onerror = function() { errorback(url) };
    }
    script.src = url;
    current_position.parentNode.insertBefore(script, current_position);
    }

    load(scripts.shift(), current_position);
    })(['http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js', './nyroModal-1.6.2/js/jquery.nyroModal-1.6.2.min.js'], function(e) {

    $(function(){ // jQuery のおまじない

    // ここから書きたいスクリプト

    $(e.target).before('<a href="http://nyromodal.nyrodev.com/img/img2.jpg" class="nyroModal" title="3rd Street Promenade">Image</a>');
    $('a.nyroModal').nyroModal();

    // ここまで書きたいスクリプト

    }); // jQuery のおまじない終点

    });


    それと、nyroModal の問題について。
    ちゃんとした説明は難しいのですが、差し替え版のように、リンクなどを記述した後に「$('a.nyroModal').nyroModal();」と記述すれば、有効になるようです。

    document.write でリンクを記述すると、nyroModal の発動 (リンクを調べてイベントをつける動作) より早くリンクが HTML に書き込まれるのですが、今回の方法だと nyroModal の発動より後にリンクが書き込まれるみたいです。
    なので、改めて手動で発動の命令を書くと、ちゃんと調べてイベントをつけてもらえます。
  • id:tmshare
    ありがとうございます。提示いただいたサンプルで動作することを確認しました。
    何度も教えていただき、サンプルまで作っていただきありがとうございます。

    > document.write でリンクを記述すると、nyroModal の発動 (リンクを調べてイベントをつける動作) より早く
    > リンクが HTML に書き込まれるのですが、今回の方法だと nyroModal の発動より後にリンクが書き込まれるみたいです。
    > なので、改めて手動で発動の命令を書くと、ちゃんと調べてイベントをつけてもらえます。

    了解しました。nyroModalの方まで調べていただきありがとうございます。

    中身が理解できるよう、サンプルを教材に勉強させていただきます。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません