Positionオブジェクト(4)
offsetParentメソッド
【抜粋】 offsetParent: function(element) { if (element.offsetParent) return element.offsetParent; if (element == document.body) return element; while ((element = element.parentNode) && element != document.body) if (Element.getStyle(element, 'position') != 'static') return element; return document.body; },
引数の要素のoffsetParentを返却するメソッド、なのですが。正直、何故存在するのか分かりません^^; 要素にoffsetParentが存在しないケースを想定しているようなのですが、どういう時に該当するのかが分からず。。。そもそも、他のメソッドの多くが要素のoffsetParentプロパティを使用しているのに対し、このoffsetParentメソッドを使用しているのは後述cloneメソッド一箇所だけです。更に、「スタイルpositionがstaticでない」というのを返却要素の条件にしているのも変です(無指定の場合も該当してしまう)。
・・・謎です><;
例は省かせてください・・・。
withinメソッド
【抜粋】 // caches x/y coordinate pair to use with overlap within: function(element, x, y) { if (this.includeScrollOffsets) return this.withinIncludingScrolloffsets(element, x, y); this.xcomp = x; this.ycomp = y; this.offset = this.cumulativeOffset(element); return (y >= this.offset[1] && y < this.offset[1] + element.offsetHeight && x >= this.offset[0] && x < this.offset[0] + element.offsetWidth); },
引数xをページ上X座標、引数yをページ上Y座標とし、引数elementがこれを含んでいるかを判定するメソッド。includeScrollOffsetsプロパティがtrueの場合(スクロール要素がドラッガブル要素を含んでいる場合等)は、次のwithinIncludingScrolloffsetsメソッドに処理を任せます。
コメントの意味は
「overlapメソッドを使用する場合、(このメソッドを使用して)X/Y座標の組を取得すること」
X/Y座標はoffsetプロパティに格納されます。これを後述overlapメソッドで使用しています。
例は「Positionオブジェクト(1) - Backstage of theater.js」のincludeScrollOffsetsプロパティを参照してください。
withinIncludingScrolloffsetsメソッド
【抜粋】 withinIncludingScrolloffsets: function(element, x, y) { var offsetcache = this.realOffset(element); this.xcomp = x + offsetcache[0] - this.deltaX; this.ycomp = y + offsetcache[1] - this.deltaY; this.offset = this.cumulativeOffset(element); return (this.ycomp >= this.offset[1] && this.ycomp < this.offset[1] + element.offsetHeight && this.xcomp >= this.offset[0] && this.xcomp < this.offset[0] + element.offsetWidth); },
includeScrollOffsetsプロパティがtrueの場合(スクロール要素がドラッガブル要素を含んでいる場合等)、withinメソッドから処理を任されるメソッド。withinメソッドと機能はほぼ一緒ですが、こちらは要素のスクロール量を考慮して判定します(要素のスクロール分は加算し、ページのスクロール分は除いています)。
前述したように、使用前にdeltaXおよびdeltaYプロパティを設定する必要があるため、prepareメソッドを呼び出さなければなりません。
こちらも例は「Positionオブジェクト(1) - Backstage of theater.js」のincludeScrollOffsetsプロパティを参照してください。
overlapメソッド
【抜粋】 // within must be called directly before overlap: function(mode, element) { if (!mode) return 0; if (mode == 'vertical') return ((this.offset[1] + element.offsetHeight) - this.ycomp) / element.offsetHeight; if (mode == 'horizontal') return ((this.offset[0] + element.offsetWidth) - this.xcomp) / element.offsetWidth; },
引数elementの要素に対する、ある座標の「相対位置」(具体的な意味は後述)を返却するメソッド。「ある座標」はY座標がycompプロパティ、X座標がxcompプロパティ。この値のセットは前述withinメソッドで行われます。コメントに「【訳】直前にwithinメソッドが呼び出される必要がある」と書かれているのはこのためです。また、offsetプロパティにも引数elementの要素の座標が設定されている必要があり、これもwithinメソッドで設定されます。
よって、以下のように使用します。
【参考】使用例 要素elemに対する座標(x,y)の「相対位置」取得 Position.within($('elem'), x, y); var ox = Position.overlap('horizontal', $('elem')); //横の相対位置 var oy = Position.overlap('vertical', $('elem')); //縦の相対位置
「相対位置」というのは私が付けた表現です^^; 以下のような値を意味します。
横位置(horizontal)
要素に対する座標の位置 | 左外側 | 左端 | 内側 | 右端 | 右外側 |
---|---|---|---|---|---|
返却値 | 1より上 | 1 | 0より上〜1未満 | 0 | 0未満 |
縦位置(vertical)
要素に対する座標の位置 | 上外側 | 上端 | 内側 | 下端 | 下外側 |
---|---|---|---|---|---|
返却値 | 1より上 | 1 | 0より上〜1未満 | 0 | 0未満 |
「http://www.imgsrc.co.jp/~kuriyama/prototype/prototype.js.html#Position」から表現を借りると、「最初の矩形と重なり、左上の座標が指定された座標であるような矩形を考える。返される値は、二番目の矩形が十分大きいとして幅や高さが重なっている(最初の矩形からみた)割合となる。 」つまり、座標(x,y)をposition:left、topとする無限に大きい要素を考えると、引数の要素elementと重なっている割合になる、ということです(座標が要素から外れるとそうともいえないのですが^^;)。だからoverlapという名前になっているようです。
名前だけみると、要素と要素の重なり割合を返却するメソッドのように思えますが、そうではないです・・・。その算出には利用できますが。
【例】 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 //EN"> <html> <head> <title></title> <style> <!-- .mark{ background-color:red; width:50px; height:50px; } #mark0{ background-color:blue; position:absolute; top:100px; left:100px; width:200px; height:200px; } #mark1{ position:absolute; top:50px; left:50px; } #mark2{ position:absolute; top:100px; left:100px; } #mark3{ position:absolute; top:200px; left:200px; } #mark4{ position:absolute; top:300px; left:300px; } #mark5{ position:absolute; top:350px; left:350px; } #test{ position:absolute; top:320px; left:50px; } --> </style> <script language="javascript" src="prototype.js" charset="utf-8"></script> <script> <!-- function test(){ var str = ""; var offset; offset = Position.cumulativeOffset($('mark1')); Position.within($('mark0'), offset[0], offset[1]); str += "mark0 & mark1 (horizontal) : " + Position.overlap('horizontal', $('mark0')) + "</br>"; str += "mark0 & mark1 (vertical) : " + Position.overlap('vertical', $('mark0')) + "</br>"; offset = Position.cumulativeOffset($('mark2')); Position.within($('mark0'), offset[0], offset[1]); str += "mark0 & mark2 (horizontal) : " + Position.overlap('horizontal', $('mark0')) + "</br>"; str += "mark0 & mark2 (vertical) : " + Position.overlap('vertical', $('mark0')) + "</br>"; offset = Position.cumulativeOffset($('mark3')); Position.within($('mark0'), offset[0], offset[1]); str += "mark0 & mark3 (horizontal) : " + Position.overlap('horizontal', $('mark0')) + "</br>"; str += "mark0 & mark3 (vertical) : " + Position.overlap('vertical', $('mark0')) + "</br>"; offset = Position.cumulativeOffset($('mark4')); Position.within($('mark0'), offset[0], offset[1]); str += "mark0 & mark4 (horizontal) : " + Position.overlap('horizontal', $('mark0')) + "</br>"; str += "mark0 & mark4 (vertical) : " + Position.overlap('vertical', $('mark0')) + "</br>"; offset = Position.cumulativeOffset($('mark5')); Position.within($('mark0'), offset[0], offset[1]); str += "mark0 & mark5 (horizontal) : " + Position.overlap('horizontal', $('mark0')) + "</br>"; str += "mark0 & mark5 (vertical) : " + Position.overlap('vertical', $('mark0')) + "</br>"; Element.update('view', str); } //--> </script> </head> <body> <div id="mark0"></div> <div id="mark1" class="mark">MARK1</div> <div id="mark2" class="mark">MARK2</div> <div id="mark3" class="mark">MARK3</div> <div id="mark4" class="mark">MARK4</div> <div id="mark5" class="mark">MARK5</div> <div id="test"> <button onclick="test();">TEST</button> <div id="view"></div> </div> </body> </html>
要素の左上座標取得にcumulativeOffsetメソッドを使用しました。
【上記例の実行結果】 mark0 & mark1 (horizontal) : 1.25 mark0 & mark1 (vertical) : 1.25 mark0 & mark2 (horizontal) : 1 mark0 & mark2 (vertical) : 1 mark0 & mark3 (horizontal) : 0.5 mark0 & mark3 (vertical) : 0.5 mark0 & mark4 (horizontal) : 0 mark0 & mark4 (vertical) : 0 mark0 & mark5 (horizontal) : -0.25 mark0 & mark5 (vertical) : -0.25