#このチュートリアルの動作環境: Windows7 システム、vue3 バージョン、DELL G3 コンピューター。3 つの方法: 1. offsetTop とscrollTop を使用して要素の位置を取得し、それが viewPortHeight (ビュー ポートの距離) 以下であるかどうかを判断します。 2. getBoundingClientRect() を使用して判定します。構文は「element object.getBoundingClientRect()」です。 3. IntersectionObserver を使用して判定します。指定された要素と表示領域が重なっているかどうかだけを確認します。
日々の開発では、ターゲット要素がビュー ウィンドウ内にあるか、ビュー ウィンドウからの距離が一定の値 (100 ピクセルなど) 未満であるかを判断する必要があることがよくあります。
画像の遅延読み込みoffsetTop、scrollTop
getBoundingClientRect
Intersection Observer
について詳しく見てみましょう。 clientWidth
clientHeight:
clientWidth: 要素コンテンツ領域の幅と左右のパディング幅を足したもの、つまり
clientWidth = content padding
clientHeight
: 要素のコンテンツ領域の高さに、上部と下部のパディングの高さを加えたもの、つまり clientHeight = content padding
ここでは、
client 要素にマージンが含まれていないことがわかります。
シリーズの属性は次のとおりです。
scrollWidth
と
#scrollLeft プロパティと
scrollTop プロパティはどちらも、要素の現在のスクロール状態を決定し、要素のスクロール位置を設定できます
垂直スクロールscrollTop > 0
水平スクロール
##要素のスクロール位置をリセットするには、要素の 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 }
# #戻り値は、
left オブジェクトです。 #x、
y、
width、および
height プロパティ。 [学習ビデオ共有:
vue ビデオ チュートリアル ,
web フロントエンド ビデオ ]
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">const target = document.querySelector(&#39;.target&#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 および
要素がウィンドウ内にある場合、要素は次の 4 つの条件を満たしている必要があります。
top が 0
より大きいか等しい 左が 0 より大きいか等しいto 0bottom はウィンドウの高さ以下です
right はウィンドウの幅以下です
Intersection Observer
即重叠观察者,从这个命名就可以看出它用于判断两个元素是否重叠,因为不用进行事件的监听,性能方面相比getBoundingClientRect
会好很多
使用步骤主要分为两步:创建观察者和传入被观察者
创建观察者
const options = { // 表示重叠面积占被观察者的比例,从 0 - 1 取值, // 1 表示完全被包含 threshold: 1.0, root:document.querySelector('#scrollArea') // 必须是目标元素的父级元素 }; 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('.target'); 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('<div class="target"></div>') .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 サイトの他の関連記事を参照してください。