高度な JavaScript フロントエンド開発でよく使用されるいくつかの API の例の詳細な説明

高度な JavaScript フロントエンド開発でよく使用されるいくつかの API の例の詳細な説明

ミューテーションオブザーバー

MutationObserver は、DOM 構造の変更を監視できるインターフェースです。

DOM オブジェクト ツリーに変更が発生すると、MutationObserver に通知されます。

API

MutationObserver は、ノード変更のコールバック関数を処理するために使用されるコールバック パラメータを受け入れ、次の 2 つのパラメータを返すコンストラクターです。

mutations : ノード変更レコードのリスト(sequence<MutationRecord>)

observer : MutationObserver オブジェクトを構築します。

MutationObserver オブジェクトには、次の 3 つのメソッドがあります。

observe : 観測対象を設定し、2 つのパラメータを受け入れます。target: 観測対象、options: オブジェクト メンバーを通じて観測オプションを設定します。

disconnect : オブザーバーによる変更の監視を停止します

takeRecords : レコードキューをクリアし、その内容を返します

// 監視するノードを選択します var targetNode = document.getElementById('root') 
// オブザーバー構成オプションを設定します var config = { attributes: true, childList: true, subtree: true } 
// ノードが変更されたときに実行される関数 var callback = function (mutationsList, observer) {
  for (var 変異の変異リスト) {
    (mutation.type == 'childList')の場合{
      console.log('子ノードが追加または削除されました。')
    } そうでない場合 (mutation.type == 'attributes') {
      console.log('' + mutation.attributeName + ' 属性が変更されました。')
    }
  }
} 
// オブザーバーインスタンスを作成し、コールバック関数に関連付けます var observer = new MutationObserver(callback) 
// 構成ファイルを使用してターゲットノードを監視します observer.observe(targetNode, config) 
// 監視を停止する observer.disconnect()

observe メソッドの options パラメータには次のオプションがあります。

childList : 対象の子ノードの追加や削除など、対象の子ノードの変更を監視しますが、子ノードとその子孫は変更しない場合は true に設定します。

attributes : ターゲット属性の変更を監視するには true に設定します

characterData : ターゲットデータの変更を監視するにはtrueに設定します

subtree : trueに設定すると、ターゲットとその子孫への変更が監視されます

attributeOldValue : 属性が true または省略されている場合は、true に設定するのと同じであり、変更前のターゲット属性値を記録する必要があることを示します。attributeOldValue が設定されている場合は、属性の設定を省略できます。

characterDataOldValue : characterData が true または省略されている場合は、true に設定するのと同じであり、変更前の対象データを記録する必要があることを示します。characterDataOldValue が設定されている場合は、characterData の設定を省略できます。

attributeFilter : すべての属性の変更を監視する必要がなく、attributes が true または ignore に設定されている場合、監視する必要がある属性のローカル名 (名前空間なし) のリストを設定します。

特徴

MutationObserver には次の機能があります。

  • 実行前にすべてのスクリプトタスクが完了するのを待ちます。つまり、非同期モードを使用します。
  • DOM の変更を 1 つずつ個別に処理するのではなく、DOM 変更レコードを配列にカプセル化して処理します。
  • DOMノードで発生するすべての変更、または特定の種類の変更を監視できます。

DOM が変更されると、MutationObserver イベントがトリガーされます。ただし、イベントとは本質的に異なります。イベントは同期的にトリガーされます。つまり、DOM が変更されると、対応するイベントがすぐにトリガーされます。一方、MutationObserver は非同期的にトリガーされ、DOM が変更された直後にトリガーされるのではなく、現在のすべての DOM 操作が完了した後にトリガーされます。

例えば、文書に1000個の段落(p要素)を連続して挿入すると、1000個の挿入イベントが連続してトリガーされ、各イベントのコールバック関数が実行され、ブラウザの遅延が発生する可能性があります。MutationObserverはまったく異なります。1000個の段落がすべて挿入された後にのみトリガーされ、トリガーされるのは1回だけです。これにより、DOMへの頻繁な変更が軽減され、パフォーマンスが大幅に向上します。

インターセクションオブザーバー

Web ページを開発する場合、要素が「ビューポート」に入ったかどうか、つまりユーザーがそれを見ることができるかどうかを知る必要があることがよくあります。

従来の実装方法は、スクロール イベントをリッスンし、ターゲット要素の getBoundingClientRect() メソッドを呼び出して、ビューポートの左上隅に対応する座標を取得し、それがビューポート内にあるかどうかを判断することです。この方法の欠点は、スクロール イベントが集中的に発生するため計算量が多くなり、パフォーマンスの問題が起こりやすいことです。

要素が表示されているかどうかを自動的に「監視」できる新しい IntersectionObserver API があり、これは Chrome 51 以降でサポートされています。 visible の本質は、ターゲット要素とビューポートが交差領域を生成することであるため、この API は「交差オブザーバー」と呼ばれます。

API

IntersectionObserver は、ブラウザによってネイティブに提供されるコンストラクターです。2 つのパラメーターを受け入れます。callback は可視性が変更されたときのコールバック関数で、option は構成オブジェクトです (このパラメーターはオプションです)。

var io = 新しい IntersectionObserver(コールバック、オプション)
// 観察を開始する io.observe(document.getElementById('example')) 
// 監視を停止する io.unobserve(element) 
// オブザーバーを閉じる io.disconnect()

複数のノードを監視する場合は、このメソッドを複数回呼び出す必要があります。

io.observe(要素A)
io.observe(要素B)

ターゲット要素の可視性が変化すると、オブザーバーのコールバック関数が呼び出されます。コールバックは通常 2 回トリガーされます。 1 回はターゲット要素がビューポートに入ったとき (表示され始める)、もう 1 回は完全にビューポートから出たとき (非表示になり始める) です。

var io = new IntersectionObserver((entries) => {
  console.log(エントリ)
})

コールバック関数のパラメータ (エントリ) は配列であり、各メンバーは IntersectionObserverEntry オブジェクトです。たとえば、2 つの観測オブジェクトの可視性が同時に変化した場合、エントリ配列には 2 つのメンバーが含まれます。

time : 可視性が変化する時間。ミリ秒単位の高精度タイムスタンプ

target : 監視対象の要素、DOMノードオブジェクト

isIntersecting : ターゲットは表示されますか?

rootBounds : ルート要素の矩形領域に関する情報、getBoundingClientRect() メソッドの戻り値。ルート要素がない場合 (つまり、ビューポートに対して直接スクロールする場合) は null が返されます。

boundingClientRect : 対象要素の矩形領域に関する情報

intersectionRect : ターゲット要素とビューポート(またはルート要素)の交差領域に関する情報

intersectionRatio : ターゲット要素の可視比率、つまり、intersectionRect と boundingClientRect の比率。完全に可視の場合は 1、完全に不可視の場合は 0 以下になります。

例えば

<html lang="ja">
  <ヘッド>
    <メタ文字セット="UTF-8" />
    <title>ドキュメント</title>
    <スタイル>
      #div1 {
        位置: 固定;
        上: 0;
        高さ: 50px;
        行の高さ: 50px;
        テキスト配置: 中央;
        背景:黒;
        色: #ffffff;
        フォントサイズ: 18px;
      }
    </スタイル>
  </head> 
  <本文>
    <div id="div1">ホーム</div>
    <div style="height: 1000px;"></div>
    <div id="div2" style="height: 100px; background: red;"></div>
    <スクリプト>
      var div2 = document.getElementById('div2')
      オブザーバー = 新しい IntersectionObserver(
        関数 (エントリ) {
          エントリ.forEach(関数 (要素, インデックス) {
            console.log(要素)
            要素が交差している場合
              div1.innerText = '私は外出中'
            } それ以外 {
              div1.innerText = 'ホームページ'
            }
          })
        },
        {
          ルート: null、
          閾値: [0, 1]
        }
      ) 
      オブザーバー.観察(div2)
    </スクリプト>
  </本文>
</html>

getBoundingClientRect と比較すると、再描画やリフローが発生しないという利点があります。

画像の遅延読み込み

画像の遅延読み込みの原理は、主に、現在の画像が可視領域に到達したかどうかを判断するコアロジックによって実現されます。これにより帯域幅が節約され、Web ページのパフォーマンスが向上します。従来の画期的な遅延読み込みは、スクロール イベントをリッスンすることで実現されますが、スクロール イベントは短時間に何度もトリガーされるため、ページのパフォーマンスに重大な影響を及ぼします。ページのパフォーマンスを向上させるために、IntersectionObserver を使用して画像の遅延読み込みを実装できます。

const imgs = document.querySelectorAll('img[data-src]')
定数設定 = {
  ルートマージン: '0px',
  閾値: 0
}
オブザーバーを新しいIntersectionObserver((entries, self) => {
  エントリ.forEach((エントリ) => {
    エントリが交差している場合
      img = entry.target とします。
      src = img.dataset.src とします。
      (ソース){
        画像ソース
        img.removeAttribute('data-src')
      }
      // 監視解除 self.unobserve(entry.target)
    }
  })
}, 設定)
imgs.forEach((画像) => {
  observer.observe(画像)
})

無限スクロール

無限スクロールの実装も簡単です。

var intersectionObserver = new IntersectionObserver(function (entries) {
  // 表示されていない場合は、if (entries[0].intersectionRatio <= 0) を返します。
  アイテムをロード(10)
  console.log('新しいアイテムをロードしました')
})
 
// 観察を開始する 交差点Observer.observe(document.querySelector('.scrollerFooter'))

getComputedStyle()

DOM2スタイルは、 document.defaultViewに getComputedStyle() メソッドを追加し、 CSSStyleDeclarationを返します。
要素の計算されたスタイルを含むオブジェクト (スタイル プロパティと同じタイプ)。

API

document.defaultView.getComputedStyle(要素[,疑似要素])
// または
window.getComputedStyle(要素[,疑似要素])

このメソッドは、計算されたスタイルを取得する要素と疑似要素文字列 (「:after」など) の 2 つのパラメータを受け入れます。疑似要素が必要ない場合は、2 番目のパラメータを null にすることができます。

<!DOCTYPE html>
<html>
  <ヘッド>
    <スタイル タイプ="text/css">
      #私のDiv {
        背景色: 青;
        幅: 100ピクセル;
        高さ: 200px;
      }
    </スタイル>
  </head>
  <本文>
    <div id="myDiv" style="background-color: red; border: 1px solid black"></div>
  </本文>
  <スクリプト>
    関数 getStyleByAttr(obj, name) {
      window.getComputedStyle を返します ? window.getComputedStyle(obj, null)[name] : obj.currentStyle[name]
    }
    ノード = document.getElementById('myDiv') とします。
    console.log(getStyleByAttr(ノード、'backgroundColor'))
    console.log(getStyleByAttr(ノード、'幅'))
    console.log(getStyleByAttr(ノード、'高さ'))
    console.log(getStyleByAttr(ノード、'border'))
  </スクリプト>
</html>

スタイルの類似点と相違点

getComputedStyle と element.style の類似点は、どちらも CSSStyleDeclaration オブジェクトを返すことです。違いは次のとおりです。

element.style は要素のインライン スタイル、つまり要素の style 属性に記述されたスタイルのみを読み取ります。一方、getComputedStyle によって読み取られるスタイルは、インライン スタイル、埋め込みスタイル、外部スタイルを含む最終的なスタイルです。

element.style は読み取りと書き込みの両方をサポートします。element.style を通じて要素のスタイルを書き換えることができます。ただし、getComputedStyle は読み取りのみをサポートし、書き込みはサポートしません。 getComputedStyleを使用してスタイルを読み取り、element.styleを使用してスタイルを変更できます。

取得バウンディングクライアント矩形

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

API

DOMRect = object.getBoundingClientRect() とします。

戻り値は DOMRect オブジェクトです。これは、要素の getClientRects() メソッドによって返される四角形のセット、つまり要素の CSS 境界サイズです。

返される結果は、要素全体を含む最小の四角形であり、境界ボックス全体をピクセル単位で表す left、top、right、bottom、x、y、width、height の読み取り専用プロパティを持ちます。幅と高さ以外のプロパティは、ビュー ウィンドウの左上隅を基準に計算されます。

アプリケーションシナリオ

1. Webページの左上隅を基準としたDOM要素の距離を取得する

以前の記述方法では、offsetParent を通じて要素を検索し、最上位の要素 body または html に再帰的に到達するまで親要素を検索していました。

// ウェブページの左上隅からのDOM要素の距離を取得します。 function offset(el) {
  varトップ = 0
  var 左 = 0
  する {
    上 += el.offsetTop
    左 += el.offsetLeft
  } while ((el = el.offsetParent)) // 互換性の問題があるため、互換性を保つ必要があります return {
    トップ: トップ、
    左: 左
  }
} 
var odiv = document.getElementsByClassName('markdown-body')
offset(a[0]) // {上: 271、左: 136}

getBoundingClientRect API によれば、次のように記述できます。

var positionX = this.getBoundingClientRect().left + document.documentElement.scrollLeft
var positionY = this.getBoundingClientRect().top + document.documentElement.scrollTop

2. 要素が可視領域内にあるかどうかを判断する

関数isElView(el) {
  var top = el.getBoundingClientRect().top // 要素の上端から表示領域の上端までの距離var bottom = el.getBoundingClientRect().bottom // 要素の下端から表示領域の上端までの距離var se = document.documentElement.clientHeight // ブラウザの表示領域の高さ。
  上端が 0 の場合
    真を返す
  } そうでない場合 (上 >= se || 下 <= 0) {
    // 見えない}
  偽を返す
}

上記は、JavaScript の高度なフロントエンド開発でよく使用されるいくつかの API の例の詳細な内容です。高度なフロントエンド API の例の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Vue Element フロントエンドアプリケーション開発 フロントエンド API インターフェースのカプセル化
  • Baidu マップ フロントエンド Web API の現在の位置を示すサンプル コード
  • よく使われるフロントエンド UI フレームワーク 12 個のまとめ
  • Baidu Maps API を使用して住所と経度と緯度を自動的に取得する JS の使用例
  • Vue によって実装されたサーバー側 API インターフェースを要求する例

<<:  キーボード上の各種特殊記号の英語読み方(知識の普及)

>>:  LeetCode の SQL 実装 (177. 給与が N 番目に高い)

推薦する

CSSを使用してアダプティブスクエアを実装する方法の例

伝統的な方法は、正方形を固定形式で書くことです。長さ=幅を直接書き、次のように固定値を書きます。 。...

Dockerコンテナでユーザーを分離する方法

前回の記事「Docker コンテナの UID と GID を理解する」では、Docker コンテナ内...

mysql バックアップ スクリプトを作成し、7 日間保存します。

スクリプトの要件: MySQL データベースを毎日バックアップし、スクリプトを 7 日間保存します。...

dockerでifconfigが利用できない問題を解決する

最近、docker を学習していたときに、docker コンテナ内のネットワーク状態を照会するために...

MySQL 接続制御プラグインの紹介

目次1. 接続制御プラグイン(connection_control)の紹介1.1 connectio...

vue+node+socket ioは複数人のインタラクションを実現し、プロセス全体を解放します

1. 背景1. フロントエンドはvue + vuex + socket.io-clientを使用しま...

CSS フォーム検証機能の実装コード

レンダリング原理フォーム要素には、正規表現(携帯電話番号、メールアドレス、IDカードなど)をカスタマ...

CSSのline-heightを継承する方法

Line-height はどのように継承されますか?30px などの特定の値を書き込むと、この値が継...

JavaScript インスタンス オブジェクトでプロトタイプ メソッドをオーバーライドする方法の詳細

目次JavaScriptでは、通常、次のコードのようにクラスを簡単に定義できます。 var サンプル...

MySQLテーブルの自動インクリメント列の初期値をリセットする方法

MySQLテーブルの自動インクリメント列の初期値をリセットする方法1. 問題の説明MySQL データ...

Linux telnetコマンドの使用

1. はじめにtelnet コマンドは、リモート ホストにログインするために使用されます。これは、T...

ウェブページのエクスペリエンス: ウェブページのカラーマッチング

<br />ウェブページの色はウェブサイトのイメージを確立する鍵の一つですが、ネットユー...

vue router-view のネストされた表示実装

目次1. ルーティング構成2. Vueページのネスト3. ネストされた関係1. ルーティング構成 定...

フレックスレイアウトの互換性の問題の概要

1. W3C バージョンの flex 2009年版フラグ: display: box; または bo...

一般的でない js 演算演算子の概要

目次2. カンマ演算子3. JavaScript Null 結合演算子 (??) 4. JavaSc...