🙌
Capybaraでエレメントの絶対位置を取得する。
概要
Capybaraとrspecでテストを書いていて、エレメントが正しい位置にあるかチェックするためにdocumentの左上端からのピクセル数を取得しようと思いました。位置の取得自体はJavascriptでTipsがいっぱいあるので、それを落とし込めばいいのですが、ちょっとクセっぽいところがあったので記事にしました。
コード
def calc_document_offset_rect(element)
rect = element.evaluate_script <<~JS
(() => {
let el = this;
let top = 0, left = 0;
const width = el.offsetWidth;
const height = el.offsetHeight;
while (el !== undefined && el !== null) {
top += el.offsetTop;
left += el.offsetLeft;
el = el.offsetParent;
}
return {
top,
left,
width,
height,
bottom: top + height,
right: left + width
};
})();
JS
rect.symbolize_keys
end
解説
javascriptのコードはこの辺を参考にしました。
elelment.evaluate_script('this.getBoundingClientRect()')
とやると動くのでevaluate_script
に渡すスクリプトの中ではthis
はエレメント自体を指すのですが、var
やlet
、cont
などで変数を宣言するとうまく動かないようです。
変数を使うには示したコードのように関数を作って即時呼び出しする必要があるようです。(() => {})()
のところですね。また即時関数ですが(function(){})()
だとthis
がundefinedになるので() => {}
とアロー関数を使う必要があります。
rect.symbolize_keys
はrails特有のメソッドですが、返り値のキーはシンボルの方が扱いやすいと思うので変換しました。rails無しなら
rect.map{|k,v| [k.to_sym, v] }.to_h
でイケるかと。
Discussion