Tag Archives: Javascript

[Javascript]Javascriptの実行順序(document.readyStateとかdeferとかasyncとか)

aycn属性とかdefer属性とか実際にどういうタイミングで実行されるのか
よくわからなくなってきたので、実際に確認してみた。

内容としては、以下のタイミングで測ってみた。

  1. document.readyState: loading
  2. document.readyState: interactive
  3. document.readyState: complete
  4. DOMContentLoaded
  5. onload
  6. 外部js
  7. 外部js(asyncで呼び出し)
  8. 外部js(deferで呼び出し)
  9. 外部js DOM追加
  10. 外部js DOM追加かつasyncで呼び出し)
  11. 外部js DOM追加かつdeferで呼び出し)

サンプルのページとしては、以下の3つで試してみました。
通常パターン
imgタグを遅延させる
scriptタグを遅延させる

結果を見ると基本的には、
loading→interactive→defer属性が実行→DOMContentLoaded→aync属性実行→complete→onload
なんですが、パターン3だけおもしろい結果で、aync属性がinteractiveより前に実行されてます。
非同期実行だから?いまいちayncの動きがわからないですね。
ちなみに外部jsを参照するscriptタグをDOM追加で入れた場合は、ayncもdeferも関係ないってことですね。

似たような記事がありましたね。

javascriptの実行順序の注意
http://0xfffffff7.hatenablog.com/entry/2013/12/09/215256

【2014.2.7 追記】
IE8以前だと「DOMContentload」が存在しないため、一般的に言われている
「documentElement.doScroll(“left”);」でできるかどうかで判断する処理をを追加してみた。

window.attachEvent("onload",function(){addevent("onload")});
var ie_contentloaded = function(){
	try{
		document.documentElement.doScroll("left");
		addevent("doScroll(\"left\")")
	}catch(a){
		window.setTimeout(ie_contentloaded, 1)
	}
};
ie_contentloaded();

実行してみると、キャッシュが効いていないときは、DOMContentloadedとほぼ同じタイミングですが
キャッシュが効いてる場合は一番最後になってしまいますね。
利用する際は注意が必要ですね。

[JavaScript]Googleコンバージョンタグ、リマーケティングタグを非同期で実行する方法

Googleコンバージョンタグ、リマーケティングタグを非同期で実行する方法がわかったのでメモ。
GoogleTagManagerの動きを見て勝手にやってるだけなので、実際に使うときはちゃんと確認したほうがいいです。

<script type="text/javascript" src="http://www.googleadservices.com/pagead/conversion_async.js">
</script>
<script type="text/javascript">
 window.google_trackConversion({
   google_conversion_id : 00000000000,
   google_conversion_language : "en",
   google_conversion_format : "3",
   google_conversion_label : "XXXXXXX",
   google_conversion_value : 0}
);
</script>

conversion.jsではなく、conversion_async.jsってのが注意。

複数のコンバージョンタグ、リマーケティングタグがある場合は、引数を変えてgoogle_trackConversionを複数叩けばOK。

[JavaScript]HTMLコメントの取得

JSでHTMLのコメントを取得できるってしらなかった。。。

ちゃんとコメントもオブジェクトとして扱われているのですね。
目からウロコです。

忘れないようにサンプルコードをメモ。

// すべてのNodeを取得
var d = document.getElementsByTagName("body")[0].childNodes;
// Nodeごとにループ
for (i=0;i<d.length;i++){
  // NodeType=8(Comment Node)の場合
  if(d[i].nodeType == 8){
    // 「.date」でデータを取得
    alert(d[i].data);
  }
}

[JavaScript]document.writeの実行順序(IEがバカ過ぎる)

document.writeで外部jsを呼び出し、その中で定義された関数を
実行しようとしても、IEだけ、うまくいかない。
setTimeoutとかを仕込み、関数が定義されるまでループさせたりして
回避してたけど、なぜそうなるのか気になったので、試してみた。

書いたjsはこんな感じのシンプルなもの。

<script>
document.write('a');
document.write('<scr' + 'ipt src="./b.js"></scr' + 'ipt>');
document.write('c');
</script>

b.jsの中身はこれ。

document.write('b');

とりあえず、FFで実行してみる。
(結果)
abc

ま、そうですよね。

IEで実行してみる。
(結果)
acb

え?なぜ?
しかも、bが若干遅いし。
あほか。

Chrome,Safariでも見てみたけど、普通に「abc」
⇒サンプル

(javascript)クロージャ

JavaScriptもだいぶわかるようになったなと思ったらつまずきました。

クロージャ

いろいろ調べてみたが、イマイチ頭に入ってこない。。。

実際にコードを書いてみてなんとなくですが、把握できた。

function func1(){
  var x = 0;
  return function(){alert(x); x++;}
}

f = func1();

f(); // 0
f(); // 1
f(); // 2

この場合でいうと「x」の値が保持されているのがみそらしい。
さらにこの「x」に対してアクセスができない。

たとえば、仮に以下のようにしたとしても、
結果は同じ。

function func1(){
  var x = 0;
  return function(){alert(x); x++;}
}

x = 5;
f = func1();

f(); // 0
f(); // 1
f(); // 2

こんなふうにも書いてみた。

function func1(){
  var x = 0;
  return function(){alert(x); x++;}
}

f = func1();

f(); // 0
f(); // 1

g = func1();

g(); // 0
f(); // 2
g(); // 1

f,gはそれぞれ変数宣言したタイミングで、関数と「x」の状態(オブジェクトみたいな?)が入っているような感じか。。。

試に以下のようにしてみると、また結果が変わってくる

function func1(){
  var x = 0;
  return function(){alert(x); x++;}
}

f = func1();

f(); // 0
f(); // 1

g = f;

g(); // 2
f(); // 3
g(); // 4

なんとなく、わかったようなわかっていないような。。。

とりあえず、jsについてまだまだってことがわかったので
オライリーでも買おう。

(参考サイト)
[JavaScript] 猿でもわかるクロージャ超入門 まとめ
JavaScript クロージャとレキシカルスコープ
クロージャ – Wikipedia