ホームページ > 記事 > ウェブフロントエンド > JavaScript_javascript のヒントで Web ページ内の要素の位置を計算する
プロジェクトのニーズにより、正常に見えることを確認するためにテスト中に Web ページ要素のスクリーンショットが必要です。以前方法を紹介する記事を書きました。まず、WebDriver を使用して全画面のスクリーンショットを撮り、次にターゲット要素 (DOM 要素) の位置に応じてスクリーンショットをトリミングし、必要な位置を保持します。
iframe というものを理解するまで、そのコードは正常に動作していました。 iframe (通常のフレームも同じですが、フレームは現在あまり一般的ではありません。ここでは例として iframe のみを使用します) 内のコンテンツは独立した Web ページとみなされ、Window オブジェクトも親 Web ページから分離されます。 WebDriver の WebElement.getLocation() メソッドは、この WebElement とそれが配置されている Window との位置関係のみを返すことができます。実装には問題ありませんが、全画面スクリーンショットには iframe の内容が含まれるだけでなく、コンテンツには親ページのコンテンツも含まれる場合があるため、切り取るときにスクリーンショット内のターゲット要素の位置を知る必要があります。そこで問題は、どの会社が最高の掘削機技術を持っているかということです。スクリーンショットに対する要素の位置を計算するにはどうすればよいですか?
この問題は別のカテゴリで議論する必要があります。その理由は、Chrome と Firefox ではスクリーンショットの動作が異なるためです。 Chrome のスクリーンショットは、現在表示されている (ビューポート) Web ページのコンテンツです。たとえば、Web ページの実際のサイズが Chrome のウィンドウ サイズを超える場合、Chrome のスクリーンショットの位置に応じてウィンドウに表示されるコンテンツが異なります。表示される内容。したがって、現在表示されているコンテンツに対するターゲット要素の位置を計算する必要があります。 Firefox は、現在のウィンドウ サイズに関係なく、Web ページ全体のコンテンツをキャプチャできる方法を使用します。したがって、Firefox の場合、要素の絶対位置 (絶対位置) を計算する必要があります。
要素の位置を取得するには、Element.getBoundingClientRect() メソッドを使用する必要があります。このメソッドは、この要素が配置されている Windows の現在表示されているコンテンツに対するこの要素の位置を返します。この要素は、上、左、右、下という 4 つの値で表されます。クリッピングサイズについては、計算せずに要素自体の長さと幅から取得できます。最上位の Window に対するターゲット要素の位置を計算するには、親 Window の上部と左を順番に追加するだけです。コードは次のとおりです:
function calcViewportLocation(element) { var currentWindow = window; var rect = element.getBoundingClientRect(); // 元素的位置 var top = rect.top; var left = rect.left; while (currentWindow.frameElement != null) { // 处理父级 Window element = currentWindow.frameElement; currentWindow = currentWindow.parent; rect = element.getBoundingClientRect(); if (rect.top > 0) { top += rect.top; } if (rect.left > 0) { left += rect.left; } } return [Math.round(top), Math.round(left)]; }
上記のコードは Chrome では機能しますが、Firefox では要素の絶対位置を計算する必要もあります。ここでは Window.pageXOffset が必要です。 pageXOffset (scrollX) は、現在の Window の水平スクロール バーのスクロール位置を表し、この値を左上に追加して、ターゲット要素の水平絶対位置を取得します。もちろん、iframe も特別に扱うことができます:
function calcAbsolutLocation(element) { var top = 0; var left = 0; var currentWindow = window; while (element != null) { rect = element.getBoundingClientRect(); var pageYOffset = currentWindow.pageYOffset; var pageXOffset = currentWindow.pageXOffset; if (typeof pageYOffset === 'undefined') { // IE8 currentDocument = currentWindow.document; var bodyElement = (currentDocument.documentElement || currentDocument.body.parentNode || currentDocument.body); pageYOffset = bodyElement.scrollTop; pageXOffset = bodyElement.scrollLeft; } top += rect.top + pageYOffset; left += rect.left + pageXOffset; element = currentWindow.frameElement; currentWindow = currentWindow.parent; if (element != null) { style = window.getComputedStyle(element); top += parseInt(style.borderTopWidth, 10); left += parseInt(style.borderLeftWidth, 10); } } return [Math.round(top), Math.round(left)]; }
IE8はpageXOffsetとscrollXをサポートしていないため、IE8では特別な処理、つまりコード中の「IE8」とマークされている部分が必要になります。これら 2 つの Javascript コードを前の記事の WebElement.getLocation() に置き換えることで、iframe 内の特定の要素のスクリーンショットを撮ることができます。