トラックバック(0)Javascriptライブラリ'prototype.js'のabsolutize()メソッド或はrelativize()メソッドは視覚上の位置は変えることなく要素の配置方法だけを'absolute'もしくは'relative'に変えてくれる便利な(例えば、その要素をドラッグしたい時等は'static'のままだと無理)メソッドだ。absolutize()メソッドはループの中で使うと思った結果にならない。下記のような簡単なHTMLコードがあったとする。/>これらimg要素のpositionはすべてstaticだとする。それらに対して下記のスクリプトを実行してみる。elem.absolutize();});すると結果は4枚とも同じ位置に来てしまう。要は視覚上の位置が変わってしまう訳だ。なるのかよくよく考えてみるとちゃんとした理由がある。理由がわかってしまえば全然納得のいく話なのだがつまりはこういう事だ。要素オブジェクト「$('img')」をeach()に渡す時はDOMの上から順番に渡していく事になる。この場合はまず"AAA.JPG"が渡される。"AAA.JPG"に対してabsolutize()メソッドが実行される。'absolute';)要素のtopプロパティとleftプロパティに先ほど記憶しておいた値を設定すると、こんな感じだと僕は捉えている。最初の要素("AAA.JPG")の元々の相対位置が(top:0,left:0)だとしたら'absolute'に変わった後のtopプロパティとleftプロパティも0になる。次の要素("BBB.JPG")に移る訳だがここで注意が必要。"BBB.JPG"の元々の視覚上の位置が(top:0,left:120)だったとしてもこの時点では(top:0,left:0)に変わってしまっている。いうと、最初の要素("AAA.JPG")が'absolute'に変わった時点で通常のレイアウトからは独立してしまっているからだ。いままで"AAA.JPG"が長男だったがもういなくなっちゃったので"BBB.JPG"が長男になっちゃった。結局はその流れの繰り返しになるのですべての要素は(top:0,left:0)になってしまう。この場合、ループを2回まわす事で対処する事はできる1回目のループはtopプロパティとleftプロパティの取得。topプロパティとleftプロパティの設定(この時点ではまだposition:staticなので視覚上の位置は変わらず)。2回目のループでabsolutize()メソッドの実行。これで目的は達成出来るがループを2回処理している時点でなんか嫌な感じがする。一つの対処法としてeach()に渡す前に「$('img')」を逆さにしておく方法がある。通常のJavascriptで得られる要素オブジェクト群(document.getElementsByTagName等から得られるNodeListといわれる物)は配列のようで配列ではないので、例えば配列用のメソッド(Array.shiftやArray.join)は使えない。elem.absolutize();});こうする事が出来る。すれば最後の要素から処理してくれるので、この場合兄弟オブジェクトのレイアウトに変更は生じない。下記のサンプルを実行すれば違いが一発で分かる。左側が通常のループ処理。右側はreverse()処理を施したループ処理。各要素は'absolute'した後はドラッグして動かす事が出来る。