vue は要素が表示領域にあるかどうかをどのように判断しますか?

青灯夜游
リリース: 2022-11-29 19:21:10
オリジナル
6342 人が閲覧しました

3 つの方法: 1. offsetTop とscrollTop を使用して要素の位置を取得し、それが viewPortHeight (ビュー ポートの距離) 以下であるかどうかを判断します。 2. getBoundingClientRect() を使用して判定します。構文は「element object.getBoundingClientRect()」です。 3. IntersectionObserver を使用して判定します。指定された要素と表示領域が重なっているかどうかだけを確認します。

vue は要素が表示領域にあるかどうかをどのように判断しますか?

#このチュートリアルの動作環境: Windows7 システム、vue3 バージョン、DELL G3 コンピューター。

可視領域とは

可視領域とは、以下に示すように、Web の閲覧に使用するデバイス上で肉眼で見える領域です。

vue は要素が表示領域にあるかどうかをどのように判断しますか?日々の開発では、ターゲット要素がビュー ウィンドウ内にあるか、ビュー ウィンドウからの距離が一定の値 (100 ピクセルなど) 未満であるかを判断する必要があることがよくあります。

画像の遅延読み込み
    #リストの無限スクロール
  • ##広告要素の露出を計算
  • クリック可能なリンクのプリロード
  • 要素が表示領域にあるかどうかを判断する 3 つの方法

要素が表示領域にあるかどうかを判断するには、次のようにします。一般的に次の 3 つのメソッドを使用します:

offsetTop、scrollTop

  • getBoundingClientRect

  • Intersection Observer

  • #メソッド 1、offsetTop、scrollTop

##offsetTop、上部の外側の境界線の間のピクセル距離要素とそれを含む要素の上部内側の境界線、その他offset プロパティを次の図に示します。

について詳しく見てみましょう。 clientWidth

clientHeightvue は要素が表示領域にあるかどうかをどのように判断しますか?:

clientWidth: 要素コンテンツ領域の幅と左右のパディング幅を足したもの、つまり clientWidth = content padding

  • clientHeight: 要素のコンテンツ領域の高さに、上部と下部のパディングの高さを加えたもの、つまり clientHeight = content padding
  • ここでは、client 要素にマージンが含まれていないことがわかります。
  • 最後に、
scroll

シリーズの属性は次のとおりです。

scrollWidth

scrollHeight
    は、主に要素の実際の内容を決定するために使用されます。
  • #scrollLeft プロパティと scrollTop プロパティはどちらも、要素の現在のスクロール状態を決定し、要素のスクロール位置を設定できます

  • 垂直スクロールscrollTop > 0水平スクロール

    scrollLeft > 0
    • ##要素のスクロール位置をリセットするには、要素の
    • scrollLeft
    • scrollTop を 0 に設定します。
  • #上記の属性は読み取り専用であり、アクセスするたびに再起動する必要があります。

判定の実装方法を見てみましょう:

式は次のとおりです。

el.offsetTop - document.documentElement.scrollTop <= viewPortHeight
ログイン後にコピー
  • コード実装:
function isInViewPortOfOne (el) {
    // viewPortHeight 兼容所有浏览器写法
    const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight 
    const offsetTop = el.offsetTop
    const scrollTop = document.documentElement.scrollTop
    const top = offsetTop - scrollTop
    return top <= viewPortHeight
}
ログイン後にコピー

メソッド 2: getBoundingClientRect

# #戻り値は、

left
top

rightbottom、## を含む

DOMRect

オブジェクトです。 #xywidth、および height プロパティ。 [学習ビデオ共有: vue ビデオ チュートリアル , web フロントエンド ビデオ ]<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">const target = document.querySelector(&amp;#39;.target&amp;#39;); const clientRect = target.getBoundingClientRect(); console.log(clientRect); // { // bottom: 556.21875, // height: 393.59375, // left: 333, // right: 1017, // top: 162.625, // width: 684 // }</pre><div class="contentsignin">ログイン後にコピー</div></div>属性に対応する関係図は次のとおりです: ページがスクロールすると、top および

left
属性値がそれに応じて変化します

要素がウィンドウ内にある場合、要素は次の 4 つの条件を満たしている必要があります。

vue は要素が表示領域にあるかどうかをどのように判断しますか?top が 0

より大きいか等しい 左が 0 より大きいか等しいto 0bottom はウィンドウの高さ以下ですright はウィンドウの幅以下です

実装コードは次のとおりです。
  • うわー
  • 方法3:Intersection Observer

    Intersection Observer 即重叠观察者,从这个命名就可以看出它用于判断两个元素是否重叠,因为不用进行事件的监听,性能方面相比getBoundingClientRect会好很多

    使用步骤主要分为两步:创建观察者和传入被观察者

    创建观察者

    const options = {
      // 表示重叠面积占被观察者的比例,从 0 - 1 取值,
      // 1 表示完全被包含
      threshold: 1.0, 
      root:document.querySelector(&#39;#scrollArea&#39;) // 必须是目标元素的父级元素
    };
    
    const callback = (entries, observer) => { ....}
    
    const observer = new IntersectionObserver(callback, options);
    ログイン後にコピー

    通过new IntersectionObserver创建了观察者 observer,传入的参数 callback 在重叠比例超过 threshold 时会被执行`

    关于callback回调函数常用属性如下:

    // 上段代码中被省略的 callback
    const callback = function(entries, observer) { 
        entries.forEach(entry => {
            entry.time;               // 触发的时间
            entry.rootBounds;         // 根元素的位置矩形,这种情况下为视窗位置
            entry.boundingClientRect; // 被观察者的位置举行
            entry.intersectionRect;   // 重叠区域的位置矩形
            entry.intersectionRatio;  // 重叠区域占被观察者面积的比例(被观察者不是矩形时也按照矩形计算)
            entry.target;             // 被观察者
        });
    };
    ログイン後にコピー
    传入被观察者

    通过 observer.observe(target) 这一行代码即可简单的注册被观察者

    const target = document.querySelector(&#39;.target&#39;);
    observer.observe(target);
    ログイン後にコピー

    案例分析

    实现:创建了一个十万个节点的长列表,当节点滚入到视窗中时,背景就会从红色变为黄色

    Html结构如下:

    <div class="container"></div>
    ログイン後にコピー

    css样式如下:

    .container {
        display: flex;
        flex-wrap: wrap;
    }
    .target {
        margin: 5px;
        width: 20px;
        height: 20px;
        background: red;
    }
    ログイン後にコピー

    container插入1000个元素

    const $container = $(".container");
    
    // 插入 100000 个 <div class="target"></div>
    function createTargets() {
      const htmlString = new Array(100000)
        .fill(&#39;<div class="target"></div>&#39;)
        .join("");
      $container.html(htmlString);
    }
    ログイン後にコピー

    这里,首先使用getBoundingClientRect方法进行判断元素是否在可视区域

    function isInViewPort(element) {
        const viewWidth = window.innerWidth || document.documentElement.clientWidth;
        const viewHeight =
              window.innerHeight || document.documentElement.clientHeight;
        const { top, right, bottom, left } = element.getBoundingClientRect();
    
        return top >= 0 && left >= 0 && right <= viewWidth && bottom <= viewHeight;
    }
    ログイン後にコピー

    然后开始监听scroll事件,判断页面上哪些元素在可视区域中,如果在可视区域中则将背景颜色设置为yellow

    $(window).on("scroll", () => {
        console.log("scroll !");
        $targets.each((index, element) => {
            if (isInViewPort(element)) {
                $(element).css("background-color", "yellow");
            }
        });
    });
    ログイン後にコピー

    通过上述方式,可以看到可视区域颜色会变成黄色了,但是可以明显看到有卡顿的现象,原因在于我们绑定了scroll事件,scroll事件伴随了大量的计算,会造成资源方面的浪费

    下面通过Intersection Observer的形式同样实现相同的功能

    首先创建一个观察者

    const observer = new IntersectionObserver(getYellow, { threshold: 1.0 });
    ログイン後にコピー

    getYellow回调函数实现对背景颜色改变,如下:

    function getYellow(entries, observer) {
        entries.forEach(entry => {
            $(entry.target).css("background-color", "yellow");
        });
    }
    ログイン後にコピー

    最后传入观察者,即.target元素

    $targets.each((index, element) => {
        observer.observe(element);
    });
    ログイン後にコピー
    可以看到功能同样完成,并且页面不会出现卡顿的情况

    以上がvue は要素が表示領域にあるかどうかをどのように判断しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート