offsetLeft の罠

こちらのさいとう先生の画像を切り取ろうとしたときのこと。

あれ、ずれてる...
offsetParent をたどって行けば、良いんじゃなかったっけ (´・ω・`)

    let e = ...
    let x = 0, y = 0;
    do {
        x += e.offsetLeft;
        y += e.offsetTop;
    } while (e = e.offsetParent);

    console.log(x, y);

(468, 1455) と計算されるけど、Firefox のものさしツールで測ってみると (514, 1454)。
46px も足りてない。


# ↓に たどり着くまで、かなりの日数が経ってます
画像の offsetParent の DIV には、border-left が指定されてる。

.NA_articleFigure {
    position: relative;
    border-left: 46px solid #fff;
}

ああ、border の分を足してあげなきゃダメなんだ(border で位置を調整するんじゃねえよ


ぴったり。

汎用的にやるためには、box-sizing も考慮してあげなきゃいけない。
こんな感じか。

    let e = ...
    let x = 0, y = 0;
    do {
        x += e.offsetLeft;
        y += e.offsetTop;
        if (e.offsetParent) {
            let {borderTopWidth, borderLeftWidth, boxSizing} =
						window.getComputedStyle(e.offsetParent);
            if (boxSizing != "border-box") {
                x += parseFloat(borderLeftWidth);
                y += parseFloat(borderTopWidth);
            }
        }
    } while (e = e.offsetParent);

    console.log(x, y);

→ (514, 1455)




今どきは、getBoundingClientRect() 使おうね、って話でした。

    let e = ...
    let {x, y} = e.getBoundingClientRect();
    x += document.documentElement.scrollLeft;
    y += document.documentElement.scrollTop;

    console.log(x, y);

→ (513.75 1455.8) : なんだ、この小数点……