Tiga kaedah: 1. Gunakan offsetTop dan scrollTop untuk mendapatkan kedudukan elemen dan tentukan sama ada ia kurang daripada atau sama dengan viewPortHeight (lihat jarak port). 2. Gunakan getBoundingClientRect() untuk menilai, sintaksnya ialah "elemen object.getBoundingClientRect()". 3. Gunakan IntersectionObserver untuk menilai, cuma semak sama ada elemen yang ditentukan dan kawasan yang kelihatan bertindih.
Persekitaran pengendalian tutorial ini: sistem windows7, versi vue3, komputer DELL G3.
Kawasan yang boleh dilihat ialah kawasan yang boleh dilihat dengan mata kasar pada peranti yang kami gunakan untuk menyemak imbas web, seperti yang ditunjukkan di bawah
Dalam pembangunan harian, kita selalunya perlu menentukan sama ada elemen sasaran berada dalam tetingkap paparan atau jarak dari tetingkap paparan kurang daripada nilai (seperti 100 px), jadi untuk melaksanakan beberapa fungsi biasa, seperti:
Untuk menentukan sama ada sesuatu elemen berada dalam kawasan yang boleh dilihat, kami biasanya menggunakan tiga kaedah:
offsetTop, scrollTop
getBoundingClientRect
Pemerhati Persimpangan
, jarak piksel antara sempadan luar atas elemen dan Sempadan dalam atas unsur yang mengandungi offsetTop
atribut lain adalah seperti yang ditunjukkan dalam rajah di bawah: offset
dan clientWidth
: clientHeight
clientWidth
clientWidth = content padding
clientHeight
clientHeight = content padding
tidak disertakan Margin client
adalah seperti berikut: scroll
dan scrollWidth
digunakan terutamanya untuk menentukan saiz sebenar kandungan elemenscrollHeight
boleh menentukan keadaan tatal semasa elemen dan menetapkan kedudukan tatal elemen scrollLeft
scrollTop
scrollTop > 0
Tatal mendatarscrollLeft > 0
elemen kepada 0 untuk menetapkan semula kedudukan tatal elemen scrollLeft
scrollTop
Atribut di atas adalah baca sahaja dan setiap akses mesti dimulakan semula
Formulanya adalah seperti berikut:
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 }
, DOMRect
, left
, top
, right
, bottom
, x
dan atribut y
. [Belajar perkongsian video: width
tutorial video vueheight
, video bahagian hadapan web]
const target = document.querySelector('.target'); const clientRect = target.getBoundingClientRect(); console.log(clientRect); // { // bottom: 556.21875, // height: 393.59375, // left: 333, // right: 1017, // top: 162.625, // width: 684 // }
Apabila halaman menatal, nilai atribut
dan akan berubah dengan sewajarnya top
left
Jika elemen berada dalam tetingkap, maka Ia mesti memenuhi empat syarat berikut:
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); });
Atas ialah kandungan terperinci Bagaimanakah vue menentukan sama ada elemen berada dalam kawasan yang boleh dilihat?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!