プロが教える店舗&オフィスのセキュリティ対策術

簡単なタグを貼り付けるだけで使えるブログパーツを、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やその読み込み方法の書き方

などなにかヒントになるようなことを教えて頂きたいのです。
よろしくお願いします。

A 回答 (2件)

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やブラウザを探してみてください。

# お勧めページなどを紹介出来るほどの知識はありません。


答えを思考で出せるレベルの回答出来ず申し訳ないです(^^;
    • good
    • 0
この回答へのお礼

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

(2)DOMを辿ってというのは理解していたのですが、スクリプトが今まさに走った該当箇所は特定できないのではないか?と思っていました。がBODY内で記述したSCRIPTでは実行時に「ページがそこまでしかロードされていない状態」のようなのでなんとかなりそうです。(色んなブラウザで試す必要がありそうですが)

(3)こちらも私の勘違いだったようで、javascriptでは関数の重複定義は問題無かったです。テスト時にエラーとなったのはjQueryを利用したイベント検知のところだったようです、失礼しました。

お礼日時:2011/11/16 00:57

何をやりたいのかよくわかりませんが…




>その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の要素を生成しているのも意図が不明です。
    • good
    • 0
この回答へのお礼

自己解決したのですが補足をさせて頂きます。
まずこれまでの過程を無視していきなりコード(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名の記載ミスでした、すみません。

お礼日時:2011/11/16 01:13

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!