外部JavaScriptの重複を防ぐ方法とは?

このQ&Aのポイント
  • 外部JavaScriptを使ってタグを貼り付ける際に、重複エラーが発生する問題があります。この問題を解決するために、動的な読み込みや読み込み方法の工夫が必要です。
  • 質問のメインは、外部JavaScriptの動的な読み込みの後に、明示的にimgのonloadイベントを起こす方法についてです。さらに、<script>〜</script>内で現在位置を知る方法や、複数回の重複を防ぐ他のアプローチについても教えてもらえると嬉しいです。
  • ヒントとしては、外部JSの読み込み完了を検知する方法として、onloadイベントを使用することができます。また、重複を起こさない外部JSの読み込み方法として、スクリプトのidをチェックする手法があります。
回答を見る
  • ベストアンサー

外部javascriptの重複を防ぐには

簡単なタグを貼り付けるだけで使えるブログパーツを、javascriptで作ろうとしています。 <■コード(1)> <script type="text/javascript" src="http://ex.com/js/test.js"></script> <div> <img class="imgobj" src="http://ex.com/dm.gif" width=1 height=1/> </div> 上記のように外部JSを読み、そのJSの中でimgタグのonloadイベントを記述し、そのイベントの処理でimgタグの直前にテキストを書き出すようにしています。これはidなどを意識しなくてもタグを貼りつけた場所に出力されるようにするための措置です。 上記は単独で貼り付ける場合はうまくいったのですが、同じコードを複數貼り付けると外部JSの衝突でエラーになります。よって外部JSの読み込みを動的にしてみました。 <■コード(2)> <script type="text/javascript"> var obj=""; obj = document.getElementById("example_tag"); if( !obj ){ var ele = document.createElement("script"); ele.id = "amacusplus_scriptfile"; ele.type = "text/javascript"; ele.src = "http://ex.com/test.js"; document.body.appendChild(ele); } </script> <div> <img class="imgobj" src="http://ex.com/dm.gif" width=1 height=1/> </div> このソースを同じページ内で二箇所貼り付けると、 今度は動的な外部JSの読み込みとimgタグのonload処理の発生タイミングが微妙なため挙動不審になってしまいました。成功したり失敗したり・・・。 とこのような状況で煮詰まっています。 質問は (1)外部JSの動的な読み込みの後に、明示的にimgのonloadイベントを起こすことはできないか? がメインですが、他のアプローチで解決できればそれでもいいので (2)<script>~</script>内に書いたjavascript内で、現在位置を知る方法(scriptエレメントを知る方法) (3)複数回読まれても重複を起こさない外部JSやその読み込み方法の書き方 などなにかヒントになるようなことを教えて頂きたいのです。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • otzero
  • ベストアンサー率30% (6/20)
回答No.1

JavaScript(v1.1~v1.3、IE5~6くらいの頃)は10年くらい前なので、外していたらごめんなさい。 (基礎は変わらないものと信じていますので)記憶が正しいという仮定で回答させて頂きます。 (1)外部JSの動的な読み込みの後に、明示的にimgのonloadイベントを起こすことはできないか? 使用するブラウザで回答が異なる可能性がありますが、出来なかったと記憶しております。 # JavaScriptはオライリーの書籍が群を抜いて詳しかったです。 # というより基礎が書かれた日本語書籍は調べた限り、これしかありませんでした。 # 即実践で用いることの出来るサンプルコードというのは無いのですが、言語やDomの理解には役立ちます。 # http://www.oreilly.co.jp/books/9784873113296/ onloadイベントは、 サーバーからWebクライアントに情報を読み込みを開始した際(ブラウザによっては読み込み後)に発生いたします。 そのため、DomのDocumentオブジェクトのイベントになります。() imgのonloadは、Documentのonloadイベントを呼び出すことになります。 imgだけを読み込みたい場合したい場合は、 考え方として、無理をしていることになります。 (2)<script>~</script>内に書いたjavascript内で、現在位置を知る方法(scriptエレメントを知る方法) エレメントを知る方法であれば、先のオライリーの書籍の「繰り返し」文の書き方を参照してください。 これを知っているかどうかは、差が大きいです。 およそ、こんな書き方 for (obj in document) { document.write(obj.name, "<br>"); } (3)複数回読まれても重複を起こさない外部JSやその読み込み方法の書き方 当時は、ブラウザの更新に当たる機能を利用してやりくりしていましたが、 今では、このようなことをAjaxという分野で行うようです。 HttpRequestやAjaxなどでWebやブラウザを探してみてください。 # お勧めページなどを紹介出来るほどの知識はありません。 答えを思考で出せるレベルの回答出来ず申し訳ないです(^^;

akirou
質問者

お礼

ご回答ありがとうございます。 (2)DOMを辿ってというのは理解していたのですが、スクリプトが今まさに走った該当箇所は特定できないのではないか?と思っていました。がBODY内で記述したSCRIPTでは実行時に「ページがそこまでしかロードされていない状態」のようなのでなんとかなりそうです。(色んなブラウザで試す必要がありそうですが) (3)こちらも私の勘違いだったようで、javascriptでは関数の重複定義は問題無かったです。テスト時にエラーとなったのはjQueryを利用したイベント検知のところだったようです、失礼しました。

その他の回答 (1)

  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.2

何をやりたいのかよくわかりませんが… >そのJSの中でimgタグのonloadイベントを記述し、そのイベントの処理で >imgタグの直前にテキストを書き出すようにしています。 >これはidなどを意識しなくてもタグを貼りつけた場所に出力されるように >するための措置です。 複数あるみたいですが、いちいちソースでスクリプトタグを挿入するのなら、imgタグにあるクラス設定がされているものが対象となるなどのルールで一律に処理できるのではないでしょうか? 書き込むテキストが違うのか同じなのかもご質問文からは判断できませんが、方法はいろいろありそう。 また、 >imgタグのonloadイベントを記述し~ の必要も理解できません。 行ないたい処理がテキストの挿入であるのならば、ロードと無関係に処理しても問題なさそうにも思えますし、それなりの理由があるとしても、全部がロードされた後で一括処理ということで、bodyのonloadでもよさそうに思えますが? >(1)外部JSの動的な読み込みの後に、明示的にimgのonloadイベントを起こすことはできないか? jsの読込みのタイミングにもよると思われます。小さな画像であれば(ご提示のサンプルでは1×1px)スクリプト読み込み前に画像の読込みが終了している可能性もあるでしょう。 明示的(←意味がよくわかりませんが)にするのなら、<img>タグ内にonloadイベントを記しておくのが確実かと思われます。 あるいは、スクリプトで画像要素を生成して、同時にonloadイベントを設定しておくとか。 >(2)<script>~</script>内に書いたjavascript内で、現在位置を知る方法(scriptエレメントを知る方法) HTML読み込み中に実行されるスクリプトであれば、その時点でのソース内の<script>タグの一番最後のものが自分自身のスクリプトです。 それ以後の要素は(まだ処理されていないので)取得できませんが、それ以前の要素であればそこから辿って取得することも可能です。 >(3)複数回読まれても重複を起こさない外部JSやその読み込み方法の書き方 特別なことは不要と思います。 文書構成がよくわからないので、複数回実行されても問題のないように記述するとしか。 ご提示の「■コード(2)」では固定のidを用いたスクリプトになっているので、このような書き方は(エラーにはならなくても)生成されるソースが文法違反になる可能性が高いです。(同じidの要素が複数生成される) また、id=example_tagの要素の存在をチェックしながら、id=amacusplus_scriptfileの要素を生成しているのも意図が不明です。

akirou
質問者

お礼

自己解決したのですが補足をさせて頂きます。 まずこれまでの過程を無視していきなりコード(1)を示したために「なぜonload?」となったかと思います、申し訳ありません。 そもそもやりたいことは端的に言うと「外部js(test.js)内の関数Aで、コードを貼りつけた部分にHTMLを書き出したい」でした。 普通に考えればdocument.writeでよさそうなのですが、その関数Aは非同期通信の結果をHTMLに整形してdocument.witeで吐き出すので、メインページのロード完了後に関数A内のdocument.writeが実行されるとFireFoxなどではメインページ全体が書き換わってしまう、という問題がありました。 これを避けるためにはコードを貼りつけた部分のエレメントを特定したい。しかしIDは付けれない。だったらparentNodeなどで相対的にエレメントを取得すればよい。そのためには基準となるエレメントが何かしら必要。ということで、imgエレメントのonloadイベントから処理をキックすれば、その親ノードが識別できるようになるので関数A内でinnerHTMLが使える、という考え方でした。 ちょっと色々と勘違い及び間違いが混在しているため上記すべてのご指摘について綺麗な返答ができません、申し訳ありません。 最終的には ・外部JSは重複しても問題ないので動的にはしない。 ・>HTML読み込み中に実行されるスクリプトであれば、その時点でのソース内の<script>タグの一番最後のものが自分自身のスクリプトです。    このアドバイスにあるようにscriptsコレクションから最後の要素を拾って、その親を辿ってinnerHTML先を決める。 ・イベントは使わない。 この方法でなんとかなりそうです。(クロスブラウザ確認はこれからですが) ありがとうございました。 なお >また、id=example_tagの要素の存在をチェックしながら、id=amacusplus_scriptfileの要素を生成 こちらはID名の記載ミスでした、すみません。

関連するQ&A

  • 外部JavaScriptの書き方

    外部JavaScriptの書き方 <script language="JavaScript" src="data.js"></script> 上記data.jsから、他サーバーの外部javascriptを読み出すには 以下のよな書き方で正しいでしょうか? document.open(); document.write('<script language="JavaScript" src="http://hoge.com/data.js"></script>'); document.close();

  • 外部javascriptを動的に読み込むには

    お世話になっております。 何度か質問させていただいているjavascrip初心者です。 外部jsファイルをボタンクリックなど何かのイベントで動的に読み込む方法がないか模索しています。 http://foofoo77.web.fc2.com/thickbox/test_index.html ↑上記ページは「書き換える」ボタンを押すと javascriptのappendChildで <div id="target1">書き換え</div> の中にscriptタグが追加される動きにしています。 書き換え後に「クリックしてみてください!」をクリックすると thickboxが動作する動きにしたいと思っています。 ieだとうまく挙動するのですが、firefoxだとthickboxは動作してくれません。 どうすればうまく挙動させれることができるこができますでしょうか? ご教授よろしくお願いいたします。 ※今回はthickboxのjs読み込みで試していますが、実際にやりたいことはもっと読み込みが重いjsの動的な読み込みです。

  • javascriptの外部呼び出し

    ttp://cache-cache.tea-nifty.com/kids/2005/04/ec10_38ba.html このサイトのjavascriptを外部呼び出ししたいのですが、 どこからどこまでを記述して●●●.jsで保存して、 <script type="text/javascript" src="●●●.js"></script> と、呼び出せばいいのでしょうか? また、表示させたい場所(<body>~</body>の間)には どのように記述すればいいでしょうか?

  • Javascript外部ファイルの読み込みについて(ブラウザにキャッシュさせたい)

    現在、製作中のサイトにおいて、webページが表示されるまで、5秒~15秒程度かかる事態が発生しています。 該当サイトでは、prototype.js等のjavascriptのライブラリを使用しており、合計で5個のjsファイルを読み込んでいます。 jsファイルの読み込み箇所を削除するとサクサクと快適になるので、jsファイルの読み込みに問題があると考え、jsファイルを圧縮したり(http://dean.edwards.name/packer/等)、ブラウザにキャッシュさせるために<script src=""での読み込み時に引数「?version=1」を追加してみたりしていますが、あまり改善しません。 読み込みの数を減らすため、prototype.jsとjquery.jsを統合するなども試してみました。(統合後のサイズは116KB) 利用環境によってはそれほど気にならない速度なのですが、IE6の環境でかなり重い場合がありますので、改善方法を探しています。 一回目の表示はともかく、2回目以降も毎回トップページ表示に5秒以上かかるのは問題がありますので…。 現時点で原因は、外部jsファイルがキャッシュされず毎回サーバーに読みにいっているために遅くなっていると思うのですが…。 ブラウザに外部ファイルをキャッシュさせる方法は何かないのでしょうか? ちなみに、重くなる環境で、他のサイト(外部JSファイル読み込み多数)のサイトを表示しても、2回目以降は重くなりません。ブラウザのキャッシュの削除も一度試しています。 参考に、現在のスクリプト呼び出し部分を記述します。 ---------------------ソースここから--------------------------- <script type='text/javascript' src='js/prototype-1602-and_jquery.js?version=1'></script> <script type='text/javascript' src='js/js.js?version=1'></script> <script type="text/javascript" src="js/lib/jquery_auto_j.js?version=1"></script> <script type='text/javascript' src='js/scriptaculous-js-181/src/scriptaculous.js?load=effects'></script> <script type='text/javascript' src='js/lightview.js?version=1'></script> ---------------------ソースここまで--------------------------- また、スクリプトはPHPで作っていますので、キャッシュを許可する記述を以下のようにしています。 ---------------------ソースここから--------------------------- session_cache_limiter('private_no_expire'); session_start(); ---------------------ソースここまで--------------------------- また、現状ではjsファイルの読み込みが原因かと考えていますが、それ以外でも改善点などがあれば、それをご指摘頂ければありがたいです。 宜しくお願い致します。 確認環境:windows XP、 IE6 HP作成スクリプト:PHP

  • javascriptの中でjavascriptを呼びだしたいのです。

    javascriptで質問です。 javascriptの中でjavascriptを呼びだしたいのです。 実際にやるとエラーになりますが、方法はありますでしょうか。 xが1のとき、script1.js xが2のとき、script2.js のように実行を分けたいので、このような処理を したいのですが。 何卒よろしくお願いいたします。 <script type="text/javascript"> <script type='text/javascript' src='http://www.domain.com/script1.js'></script>"; </script>

  • jQuery.jsを使ったhtml外部読み込み

    教えてください。 現在Jqueryを使用して外部htmlを読み込ませようとしていますが、 うまくいきません・・・ ■本体html <head> <script src="js/jquery-1.8.3.min.js"></script> </head> <body> <script type="text/javascript" src="sample.js"></scrip> <div id="sample"></div> </body> ■sample.js // JavaScript Document $(function(){ $("#sample").load("sample.html"); }); ■読み込ませるsample.html 特に設定なし このような感じですが、全然読み込めません。。。 javascriptを外部リンクにしているのは、読み込むhtmlが複数ある為、 headの見栄えが悪くなるからという個人的な意見です・・・ 済みませんがお知恵をお貸しください!!

  • jQueryで質問です。

    jQueryで質問です。 オブジェクトA、Bがあるとします。 Aをドラッグすると、mousedownかdragstartの段階で要素がBに置き換わってドラッグさせるような動きは可能でしょうか。 作成中のソースを記載します。 <html> <head> <title>test</title> <script type="text/javascript" src="./jquery.min.js"></script> <script type="text/javascript" src="./ui/jquery.ui.core.js"></script> <script type="text/javascript" src="./ui/jquery.ui.widget.js"></script> <script type="text/javascript" src="./ui/jquery.ui.mouse.js"></script> <script type="text/javascript" src="./ui/jquery.ui.draggable.js"></script> <script type="text/javascript" src="./ui/jquery.ui.droppable.js"></script> <script type="text/javascript"> $(function(){ obj1 = $("#box"); obj2 = $('<div style="width:200px;height:200px;background:red;">B</div>'); obj1 .mousedown( function(){ obj1.replaceWith(obj2); obj2.draggable(); } ); }); </script> </head> <body> <div style="width:200px; height:100px; background: #cccccc;" id="box">A</div> </body> </html> これだと、Aのドラッグを一度解除して、Bをドラッグすると上手くいきますが、1回のモーションでBをドラッグさせたいのです。 宜しくお願いします。

  • javascriptのalertで文字化けが解消されません。(外部js

    javascriptのalertで文字化けが解消されません。(外部jsファイル読込による) htmlファイル <meta http-equiv="Content-Script-Type" content="text/javascript"> <script language="JavaScript" src="**/**.js" charset="shift_jis"></script> いろいろ調べまして、charset="shift_jis"を指定したり、utf-8にしましたがうまくいきません。 jsファイル function testalert() { alert('テスト'); } ご教授をよろしくお願いします。

  • 【javascript】2つ同時に上手く動かない

    javascript初心者です。 現在作成している画面に2つのjavascriptを動かしたいと思っております。 しかしながら、一つずつでは動くのですが、同時に表示すると上手く動作しません。 いい方法などありましたらご教授お願い致します。 【htmlのヘッド】 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script type="text/javascript" src="js/jquery.coda-slider-2.0.js" charset="utf-8"></script> <script type="text/javascript" src="js/jquery.easing.1.3.js"></script> <script type="text/javascript" src="js/sm_scroll.js"></script> <script type="text/javascript" src="js/jcaption.min.js"></script> <script type="text/javascript" charset="utf-8"> $(function(){ $('#coda-slider-1').codaSlider({ autoSlide:false, autoHeight:false, autoSlideStopWhenClicked:false, autoSlideInterval:10000, firstPanelToLoad:1, dynamicArrows: false, }); }); </script> <script type="text/javascript" src="js/prototype.js"></script> <script type="text/javascript" src="js/scriptaculous.js?load=effects,builder"></script> <script type="text/javascript" src="js/lightbox.js"></script> 【上部のjavascript】 Coda-Slider 参照URL:http://phpjavascriptroom.com/exp3.php?f=include/ajax/jquery_plugin_slider/coda_slider.inc&ttl=%E8%A8%AD%E7%BD%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB 【下部のjavascript】 litebox 参照URL:http://lokeshdhakar.com/projects/lightbox2/ javascript内が初期化されているのが問題なのでしょうか? 解決の方法などありませんでしょうか? 以上、宜しくお願い致します。

  • javascriptをCSSに書き込むと動作しません。何故ですか?

    下記のjavascriptをCSSに書き込みました。拡張子は.jsとしました。 jsのフォルダにtopmuv.jsというファイル名にしました。 <script type="text/javascript"> <!-- function blink() { if (!document.all) { return; } for (i = 0; i < document.all.length; i++) { obj = document.all(i); if (obj.className == "blink") { if (obj.style.visibility == "visible") { obj.style.visibility = "hidden"; } else { obj.style.visibility = "visible"; } } } setTimeout("blink()", 500); } // --> </script> </head> <body onload="blink()"> htmlの読み込みは <LINK rel="stylesheet" href="js/topmuv.js" type="text/javascript"> と書いています。 この場合、上記javascriptのソースをシート上にダイレクトに書き込むと正常に動作しますがcssにすると動作しません。 何が悪いのでしょうか? 詳しい方宜しくお願いします。

専門家に質問してみよう