document.elementFromPoint
APIを使用して、ある時点の要素を取得しています。しかし、私はすべての要素を持っているとは思っていません - 一部はinline
要素のように修飾されていません。したがって、私はそれの下にある要素をつかむために、非修飾要素を一時的に不可視にしています。一時的に要素を非表示にする
ここにコードの抜粋です。
import { elementQualified, elementFromPoint } from './utils';
function makeInvisible(element) {
let oldVisibility = element.style.visibility;
/* this is supposed to make the element invisible immediately, without
* any delay. When a `transition` property is set which includes the
* `visibility` property, this is sometimes unfortunately not the case. */
element.style.visibility = "hidden";
/* this is the undo function being called at the end. */
return() => {
element.style.visibility = oldVisibility;
};
}
export default function(x, y) {
var undo = [], element, last;
/* in a loop, we grab the top-most element that is at a certain coordinate
* inside the viewport. The `last` variable is preventing an infinite loop
* in cases, where `makeInvisible()` does not work. */
while (((element = elementFromPoint(x, y)) !== null) && (last !== element)) {
/*
* In order to be qualified, this element including its ancestors must
* all be qualified. For instance, if this is a block element but the
* parent for some reason is an inline element, this is not desired. */
if (withAncestors(element).every(elementQualified)) {
break;
}
/* if the element is not qualified, we make it invisible and add it to the
* start of the `undo` array which is being batch-called after this loop. */
undo.unshift(makeInvisible(element));
/* and the loop protection */
last = element;
}
/* undo all changes */
undo.forEach((fn) => fn());
/* check if we broke the loop or we have selected the topmost element
* in which case we discard the result. */
if ((last === element) || (element === document.documentElement)) {
return null;
}
return element;
}
見えなくなることになっている要素はvisibility
プロパティが含まtransition
プロパティセットを持っている場合、それはすぐに見えなくなることはありません。たとえばtransition: all 0.3s ease-in-out
とします。 element.style.visibility
をhidden
に設定した後は、0.3s
になります。その後、実際には表示されず、document.elementFromPoint
はその下の要素を選択します。その結果、document.elementFromPoint
が同じ要素の2倍を返すため、ループが壊れています。
display
プロパティを一時的に設定するつもりはありません。レイアウトが変更され、レイアウト変更が機能しないツールを作成しているためです。遷移プロパティをリセットします
カントあなたは目に見えないに要素を設定する前にトランジションを削除したら、それをバックに設定しますされていますか? – Lain
"_... display property ...レイアウトの変更を引き起こします。" "すべてのDOMを同期的に処理していて、ブラウザにページをレンダリングする前にすべてを元に戻してしまうと、そうしません。したがって、スクリプトが終了する前にスタイリングを削除すると、スクリプトに 'display:none'を設定することはページに表示されません。 – Teemu
前に 'display:none'オプションを試しました。それは私のためにレイアウトの変更やスクロールの問題を引き起こします。 – Vincent