jsでの位置計算を徹底的に理解するのに役立つ記事

jsでの位置計算を徹底的に理解するのに役立つ記事

導入

この記事に関係する API のリスト:

  1. スクロール関連API
  2. クライアント関連API
  3. オフセット関連API
  4. Element.getBoundingClientRectAPi
  5. ウィンドウ.getComputedStyleApi

よく知られているオープンソース ライブラリの API 定義とアプリケーション シナリオに基づいて、これらの API をレイヤーごとに分析します。仕事における要素位置計算に関連するほとんどのシナリオを処理するのに十分です。

位置計算 API を使用する場合は特に注意する必要があります。不適切に使用すると、レイアウトのスラッシングが発生し、ページのレンダリングに影響する可能性があります。

スクロール

まず、スクロール関連のプロパティとメソッドを見てみましょう。

要素.スクロール()

Element.scroll() メソッドは、指定された要素内の特定の座標までスクロールするために使用される Element インターフェースです。

element.scroll(x座標, y座標)
要素.スクロール(オプション)
  • x 座標は、要素の左上領域の水平方向に表示したいピクセルを指します。
  • y座標は、要素の左上領域の垂直方向に表示したいピクセルを指します。

つまり、element.scroll(x,y) は要素のスクロール バーを対応する x,y 位置までスクロールします。

また、element.scroll(options) を呼び出し、追加の構成を渡すこともサポートしています。

{
    左: 番号、 
    上: 番号、
    動作: 'smooth' | 'auto' // スムーズスクロールまたはデフォルトの直接スクロール}

要素.scrollHeight/scrollWidth

Element.scrollHeight この読み取り専用プロパティは、オーバーフローによりビューに表示されないコンテンツを含む、要素のコンテンツの高さの測定値です。

scrollHeight の値は、スクロール バーを使用せずに要素の内容をビューポート内に収めるために必要な要素の最小の高さに等しくなります。 垂直スクロール バーがない場合、scrollHeight 値は、要素のビューがそのコンテンツすべてを埋めるのに必要な最小の clientHeight と等しくなります。要素のパディングは含まれますが、要素の境界線とマージンは含まれません。 scrollHeight には、::before や ::after などの疑似要素も含まれます。

つまり、要素にスクロール バーがない場合、Element.scrollHeight は常に clientHeight と同じになります。
ただし、スクロール バーが表示された場合、scrollHeight は要素の非表示コンテンツの高さを参照します。スクロール バーが表示された場合、scrollHeight は常に clientHeight よりも大きくなります。

  • Element.scrollWidth これも、オーバーフローによりビューに表示されないコンテンツを含む、要素のコンテンツ幅の読み取り専用プロパティです。

原理は scrollHeight と同じですが、高さではなく幅である点が異なります。

簡単に言えば、要素にスクロール バーがない場合、スクロールとクライアントは同じ値になります。スクロール バーがある場合、クライアントは表示されている現在の要素の高さ/幅のみを計算しますが、スクロールは表示されている現在の要素の高さ/幅だけでなく、現在の要素のスクロール バーによって非表示になっているコンテンツの高さ/幅も計算します。

clientWidth/height + [スクロールバーの非表示コンテンツの幅/高さ] = scrollWidth/Height

要素.scrollLeft/scrollTop

  • Element.scrollTop プロパティは、要素のコンテンツを垂直方向にスクロールするピクセル数を取得または設定します。
  • Element.scrollLeft プロパティを使用すると、要素のスクロール バーから要素の左側までの距離を読み取ったり設定したりできます。

要素のコンテンツ方向が rtl (右から左) の場合、スクロール バーは右端 (コンテンツが始まる場所) に配置され、scrollLeft 値は 0 になることに注意してください。この時点で、スクロール バーを右から左にドラッグすると、scrollLeft は 0 から負の数に変わります。

ScrollLeft/Top は、日常業務でスクロールバーを操作するためによく使用される API です。設定可能な値です。スクロール バーの位置は、さまざまな値に応じて制御できます。

実際、これら 2 つの属性は、上記の Element.scroll() と同じ効果を実現できます。

実際の仕事で、スクロール操作が頻繁に必要な場合は、モバイル/Web 用のユニバーサル js スクロール ライブラリである better-scroll を使用することを個人的には推奨します。内部スクロールは要素の変換に基づいており、関連する再形成/逆流はトリガーされません。

現在の要素にスクロールバーがあるかどうかを判定する

スクロール バーが表示されるということは、要素のスペースがコンテンツの表示領域よりも大きくなることを意味します。この現象に基づいて、スクロール バーを表示するかどうかを決定するルールを取得できます。

エクスポートconst hasScrolled = (要素、方向) => {
  if (!element || element.nodeType !== 1) 戻り値:
  if (方向 === "垂直") {
    element.scrollHeight > element.clientHeight を返します。
  } それ以外の場合 (方向 === "水平") {
    element.scrollWidth > element.clientWidth を返します。
  }
};

ユーザーが一番下までスクロールしたかどうかを判定する

基本的に、要素にスクロール バーが表示されると、現在の要素の高さ + スクロール バーの高さ = 要素自体の高さ (非表示部分を含む) が決定されます。

element.scrollHeight - element.scrollTop === element.clientHeight

クライアント

マウスイベント.クライアントX/Y

MounseEvent.clientX/Y も、イベントが発生したときのアプリケーション クライアント領域の水平座標を提供する読み取り専用プロパティです。

たとえば、クライアント領域の左上隅をクリックすると、ページに垂直/水平スクロールがあるかどうかに関係なく、マウス イベントの clientX/Y 値は 0 になります。

実際、MouseEvent.clientX/Y は現在のビューポート (ブラウザの表示領域) を基準に計算されます。

非常にわかりやすい写真を再投稿します:

要素.clientHeight/clientWidth

Element.clientWidth/clinetHeight プロパティは、要素の固有の幅をピクセル単位で表します。このプロパティにはパディングが含まれますが、境界線、余白、垂直スクロール バー (存在する場合) は含まれません。

インライン要素と CSS スタイルのない要素の clientWidth プロパティの値は 0 になります。

スクロールバーが表示されない場合は、Element.clientWidth/Height === Element.scrollWidth/Height

要素.clientTop/clientLeft

Element.clientLeft は、要素の左境界の幅をピクセル単位で表します。要素のテキスト方向が右から左 (RTL) で、コンテンツのオーバーフローにより左側に垂直スクロール バーが表示される場合、このプロパティにはスクロール バーの幅が含まれます。 clientLeft には左マージンと左パディングは含まれません。 clientLeft は読み取り専用です。

同様に、Element.clientTop は要素の上境界線の幅を表し、これも読み取り専用プロパティです。

これら 2 つのプロパティは日常生活ではほとんど使用されませんが、似た名前を持つこれらのプロパティを混同しないようにするためにも知っておく必要があります。

オフセット

マウスイベント.offsetX/offsetY

MouseEvent インターフェイスの読み取り専用プロパティ offsetX/Y は、イベント オブジェクトとターゲット ノードのパディング エッジ間の X/Y 軸方向のオフセットを指定します。

offest を使用したことがある学生なら、この属性を深く理解していると思います。これは、親要素の左/上に対するオフセットです。

トリガー要素は e.target であることに注意してください。イベント オブジェクトに子要素が含まれている場合は、子要素の内側に移動するときに特に注意してください。e.offsetX/Y は、子要素の左上隅からのオフセットです。

オフセット幅/オフセット高さ

HTMLElement.offsetWidth/Height は、要素のレイアウトの幅/高さを返す読み取り専用プロパティです。

いわゆるレイアウト幅は、上で説明した clientHeight/Width および offsetHeight/Width に相対的です。境界線とスクロール バー (ある場合) の幅/高さは含まれません。

OffsetWidth/offsetHeight は、要素の境界線、水平/垂直線の余白、垂直/水平スクロールバー (スクロールバー) (存在する場合)、および CSS で設定された幅を含む、要素のレイアウトの幅/高さを返します。

オフセット上/左

HTMLElement.offsetLeft は、HTMLElement.offsetParent ノードの左境界からの現在の要素の左上隅のオフセットのピクセル値を返す読み取り専用プロパティです。

返されるオフセットは、HTMLElement.offsetParent ノードの左端を基準としていることに注意してください。

HTMLElement.offsetParent とは何ですか?

HTMLElement.offsetParent は読み取り専用プロパティであり、要素を含む最も近い (包含階層の観点から) 配置された要素、または最も近い table、td、th、body 要素へのポインターを返します。要素の style.display が "none" に設定されている場合、offsetParent は null を返します。 offsetParent は、offsetTop と offsetLeft がパディング境界を基準にしているため便利です。 --MDN より

簡単に言えば、現在の要素の祖先コンポーネント ノードに table、td、th がなく、位置指定要素の position 属性が relative、absolute などである場合、offsetLeft/offsetTop は body の左隅/上隅からのオフセットを返します。

祖先要素の中に位置指定された要素(または上記のタグ要素)がある場合、それを要素の offsetParent と呼ぶことができます。要素の offsetLeft/offsetTop 値は、その要素の左境界の左側/上境界の上側から offsetParent 要素の左境界までの距離に等しくなります。

この写真を見てみましょう:

要素のボディからのオフセットを計算する

要素と本体の間の距離を取得する必要があるが、親要素に位置指定された要素があるかどうかを判断できない場合 (コンポーネント開発では、ほとんどの場合、親ノードに位置指定された要素があるかどうかは明確ではありません)。このとき、jqery の offset() に似たメソッドを実装する必要があります。つまり、現在の要素の本体に対するオフセットを取得します。

  • 親要素に位置指定された要素があるかどうか不明なため、 offsetLeft/offsetTop を直接使用して取得することはできません。
  • 現在の offsetParent が body でない場合は、再帰を使用してオフセットを解決し、累積します。
  • body 要素に到達するまで、上方向に再帰的に継続し、offsetParent に offset を追加します。
const getOffsetSize = function(Node: any, offset?: any): any {
  オフセットの場合
    オフセット = {
      x: 0,
      年: 0
    };
  }
  if (Node === document.body) は offset を返します。
  offset.x = offset.x + Node.offsetLeft;
  offset.y = offset.y + Node.offsetTop;
  getOffsetSize(Node.offsetParent, offset) を返します。
};

注意: ここでは parentNode は使用できません。前述のように、offsetLeft/top は parentNode のオフセットではなく、HTMLElement.offsetParent のオフセットを参照します。

要素.getBoundingClientRect

使用法

Element.getBoundingClientRect() メソッドは、要素のサイズとビューポートに対する位置を返します。

element.getBoundingClientRect() は、ビューポートの左上隅を基準とした位置を返します。

element.getBoundingClientRect() によって返される高さと幅は、要素の表示領域の幅と高さ (具体的なサイズはボックスのサイズによって決まります) であり、スクロール バーが非表示になっているコンテンツは含まれません。

ヒント: 標準ボックス モデルの場合、要素のサイズは幅/高さ + パディング + 境界線幅の合計に等しくなります。 box-sizing: border-box の場合、要素のサイズは幅/高さに等しくなります。

rectObject = object.getBoundingClientRect();

戻り値は DOMRect オブジェクトです。これは、要素の getClientRects() メソッドによって返される四角形のセット、つまり要素の CSS 境界サイズです。返される結果は、要素全体を含む最小の四角形であり、境界ボックス全体をピクセル単位で表す left、top、right、bottom、x、y、width、height の読み取り専用プロパティを持ちます。幅と高さ以外のプロパティは、ビュー ウィンドウの左上隅を基準に計算されます。

幅と高さは要素のサイズを計算するために使用され、その他の属性はビューポートの左上隅を基準とします。

ビューポート領域(またはその他のスクロール可能な要素)内のスクロールは、境界四角形を計算するときに考慮されます。つまり、スクロール位置が変わると、top プロパティと left プロパティの値がすぐに変わります(したがって、それらの値はビューポートに対する相対値であり、絶対値ではありません)。 Web ページ全体の左上隅を基準としたプロパティ値を取得する必要がある場合は、現在のスクロール位置 (window.scrollX および window.scrollY 経由) を top プロパティ値と left プロパティ値に追加するだけです。この方法では、現在のスクロール位置に依存しない値を取得できます。

要素がビューポート内に表示されるかどうかを計算します

利点は、要素からビューポートまでの距離がビューポートのサイズよりも小さいことです。

負の値になった場合でも、その要素はかつて画面に表示されたが、現在は表示されていないことを意味することに注意してください。 (滑るように)

これは、vue-lazy イメージ遅延読み込みライブラリのソースコードが判断される方法です。

 isInView():ブール値 {
    const rect = this.el.getBoundingClientRect()
    rect.top < window.innerHeight && rect.left < window.innerWidth を返します
  }

rect.top < window.innerHeight の場合、現在の要素がすでにページに表示されていることを意味し、left についても同様です。

ウィンドウの取得スタイル

使用法

Window.getComputedStyle() メソッドは、アクティブなスタイルシートを適用し、それらの値に含まれる可能性のある基礎となる計算を解決した後、要素のすべての CSS プロパティの値を報告するオブジェクトを返します。 プライベート CSS プロパティ値には、オブジェクトによって提供される API を介して、または CSS プロパティ名を使用して単純にインデックス付けすることによってアクセスできます。

style = window.getComputedStyle(要素、[pseudoElt]);

要素

  • 計算されたスタイルを取得するために使用される要素。

pseudoElt オプション

  • 一致する疑似要素を指定する文字列。通常の要素の場合は省略(または null)する必要があります。

返されるスタイルは、要素のスタイルが変更されると自動的に更新されるライブ CSSStyleDeclaration オブジェクトです。

要約する

js での位置計算に関するこの記事はこれで終わりです。js での位置計算に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • js と jQuery でマウスの現在の x 座標と y 座標を取得するためのコード
  • JSを使用して現在の地理的位置を取得する方法の概要
  • jsはブラウザ内の要素の絶対位置を取得します
  • jsは、スクロールバーが特定の位置までスクロールすると自動的にtrを配置することを認識します。
  • 要素の相対的なウィンドウ位置を取得するための js 実装コード
  • JS で DOM 要素の絶対位置を取得する詳細な例
  • JS を使用してポップアップの新しいページ ウィンドウの位置とサイズを制御する方法
  • マウスの位置を取得するjsの例の詳細な説明
  • 現在の地理的位置を取得するJSメソッド
  • マウスの現在の位置を取得するjs

<<:  MySQL における ${param} と #{param} の違い

>>:  Linux は suid vim.basic ファイルを使用して権限昇格を実現します。

推薦する

H5ゲームをnginxサーバーにデプロイする方法の詳細な説明

自己学習型ゲーム開発の道において、最も充実した瞬間は、自分でミニゲームを作り、友達と共有して試しにプ...

Win Server 2019 サーバーの IIS 構成と Web サイトの簡単な公開

1.まずサーバーにリモート接続する2. サーバーマネージャーを開く 3役割と機能の追加 4サーバープ...

JS+AJAX は、州、市、地区のドロップダウン リストのリンクを実現します。

この記事では、州、市、地区のドロップダウンリストのリンクを実現するためのJS + AJAXの具体的な...

MySQL の lru リンク リストの簡単な分析

1. 従来のLRUリンクリストについて簡単に説明するLRU:最も最近使われなかったものLRU リンク...

メタタグにおける http-equiv 属性の使用の概要

metaはhtml言語のhead領域にある補助タグです。おそらく、これらのコードは不要だと思うかもし...

vuex データの永続化のための 2 つの実装ソリューション

目次ビジネス要件:解決策 1: vuex-persistedstate解決策2: vuex-pers...

Docker に Zookeeper を素早くインストールする方法の詳細なチュートリアル

Docker で Zookeeper を素早くインストール会社を変わってから長らくZookeeper...

Dockerがコンテナを起動するたびに、IPとホストが指定した操作が実行されます。

序文Dockerを使ってHadoopクラスタを起動するたびに、ネットワークカードの再バインド、IPの...

JS変数ストレージのディープコピーとシャローコピーの詳しい説明

目次可変タイプとストレージスペーススタックメモリとヒープメモリ基本的なデータ型参照タイプグラフィック...

CentOS での Django プロジェクトのデプロイに関する詳細なチュートリアル

基本環境パゴダ設置サービスパゴダにインストールされた[Pythonプロジェクトマネージャー]パゴダに...

MySQL 5.7.21 のインストールと設定方法のグラフィックチュートリアル (ウィンドウ)

ウィンドウ環境にmysql5.7.21をインストールします。詳細は次のとおりです。 1. MySQL...

Ubuntuがインターネットに接続できない場合の解決策

問題の説明:デスクトップ コンピューターとキャンパス ネットワークを使用して、有線モードでインターネ...

MySQL Server 8.0.3 のインストールと設定方法のグラフィックチュートリアル

この文書はMySQL Server 8.0.3のインストールと設定方法を参考のために記録したものです...

HTMLで細い線のテーブルを作成する簡単な例

この細線の表を作成する方法については、Baidu で検索すると、表に対して border="...

MySQL データベースでよく使用される SQL ステートメントの詳細と概要

この記事では、MySQL データベースでよく使用される SQL ステートメントを例を使用して説明しま...