ここ2週間で知ったJavascriptとHTML/CSSのTipsメモ書き

知ってる人に取っちゃ当たり前なんだけど、

今回初めてしったノウハウをメモしとく

1. bodyにonloadを追加したい場合はwindowにattachEvent/addEventListenerすべし
<body  onload="func()";>

みたいなこととをしたい場合。

(document.getElementsByTagName('body')[0]).attachEvent('onload', func, false);

としたい気持ちはわかりますが、
正しくは、こう書かないと動きません。

window.attachEvent('onload', func, false);

理由はdocument.getElementsByTagName('body')[0])を実行した時点では、
まだbodyタグの描画が終わっておらず'undefined'になってしまうから。
なので、body終了まではgetElementはつかえません。
余談だが、Google Analiticsなどinlineの広告スクリプトがdocument.writeをするのは、
逆に言うとそれしかできないからです。
もちろん、onloadをhookして、onload後に処理を開始するということはできる。

ちなみ、onloadに指定できる関数は一つだけです(たしか。確証なし、違ったらごめん)

2. ウィンドウのイベントを取得するwindowにclickイベント/プロパティはない。documentを利用すべし

windowにはclickというプロパティはありません。
なので、window.atachEvent('onclick', func); ということはできません。
documentを使いましょう。

document.attachEvent('onclick', func):
3. 複数イベントをハンドルしたい場合は、atachEvent/addEvent〜を使うべし。

一つのタグに、複数のイベントをつけるときには

<div onclick="func1(); func2();">

ではなく、attachEvent/addEvent〜を使いましょう。
コードが煩雑でなくなる、且つビューとロジックが分割できます。

4. イベントの伝達は上位 → 下位 → 上位の順番で来るようにすべし。

イベントの伝搬方式は、Mozilla/Firefoxはイベントキャプチャリング方式、IEはイベントバブリング方式。

<body onclick="func1();">
  <div onclick="func2();">
     <p onclick="func3();">
        ほげほげ
     </p>
  </div>
</body>

上記コードでpタグの領域をクリックした場合場合、FFだとfunc1()→func2()→func3()とクリックイベントが伝搬します。
IEだとfunc1()→func2()→func3()の順でクリックイベントが伝搬します。
本来、DOM2準拠であればFFの方が正しいのですが、
世間のシェアはIEが断然上、IEにあわすのが世の流れというものです。
そのため、addEventListerではaddEventListener('click', func1, false);としてイベントの伝達方向を制御しましょう。

5. イベントハンドラのthis=nullの場合applyをうまく使うべし

attachEventで追加した場合IEイベントハンドラのthisにはnullが入る。
なので、applyを利用してthisを固定する。
ココを参照するべし。(applyの利用してイベントのthisをbind(指定)させる方法(attachEventでthisを指定させる方法))

6. setTimeout/setIntervalの第1引数には、変数(object)ではなく、関数名(string)を入れるべし

setInterval/setTimeoutの第一引数はsetTimeout(func, 20);ではなくsetTimeout("func()", 20);と
通常のメソッドとは違って、関数名を入れなければならない。
また、setIntervalには関数からの引数は直接指定できない。
例えば以下は無理

function func1(arg){
  setTimeout("func1(arg)", 20);)
}

これは、setTimeout/setIntervalは、正確にはwindow.setTimeout/window.setIntervalなわけです。
なので、なのでfunc1はwindowから見えなければダメだし、argもwindowから見えないとダメなのです。
上記のコードを実行したい場合には、次のようにすればよい。

function func1(arg){
  var ARG = arg
  setTimeout("func1(ARG)", 20);)
}

また、次のようにも出来る。

function func1(arg){
  var ARG = arg
  setTimeout(function(){ func1(ARG);}, 20);
}
7. 呼び出し元の関数を知るときはarguments.caller.callleeを使うべし

イベント先などで呼び出し元の関数が知りたい場合は
arguments.caller.calleeを使うととれます。
argumentsは現在の関数に渡された引数が入る配列。
calleeは自分の自身。
callerは現在の関数の呼び出し元のコンテキスト(オブジェクト)を参照します。
なので、呼び出し元の関数名を知るにはarguments.caller.calleeとします。

8. 半透過はopacityを使うべし

具体的なコードは次の通り。

/* for IE */
var FILTER = "progid:DXImageTransform.Microsoft.Alpha(opacity=OPAVAL)";
obj.element.style.filter = FILTER.replace(/OPAVAL/, 0);
/* for Firefox*/
obj.element.style.opacity = 0.5;

IEのOpacityは0〜100、それ以外のブラウザは0〜10となります。

9. arrayのlengthを減らす場合は、length-1とする

array[1] = undefined; としても、値がundefinedになるだけで、要素(プロパティ)は減りません。
lengthを加減するこで、arrayの個数をへらせます。