简体   繁体   English

具有延迟加载的交叉口观察器

[英]Intersection Observer with lazy loading

i want to achieve this behaviour from this example with images https://codepen.io/ryanfinni/pen/jONBEdX .我想从这个例子中用图像https://codepen.io/ryanfinni/pen/jONBEdX实现这种行为。 the only difference it's that instead on toggling the img visibility, for every div that it's in view, i want to make an call to an endpoint to retrieve the data and ppulate the html by sendind the corresponding data-id as a parameter.唯一的区别是,在切换 img 可见性时,对于它在视图中的每个 div,我想调用端点以检索数据并通过发送相应的数据 ID 作为参数来填充 html。

what i have so far it's working only for the first item.到目前为止,我所拥有的仅适用于第一项。 how can i make it work for all the items that i have and target them by the data-id, similar to this example with data.src我怎样才能使它适用于我拥有的所有项目并通过 data-id 定位它们,类似于这个带有 data.src 的示例

function handleIntersection(entries) {
  entries.map((entry) => {
    if (entry.isIntersecting) {
      entry.target.src = entry.target.dataset.src;
      entry.target.classList.add('loaded')
      observer.unobserve(entry.target);
    }
  });
}

here is my code这是我的代码

 const LIST = document.querySelector('.city-list'); async function getData() { try { let response = await fetch('https://raw.githubusercontent.com/ashes27/infinite/master/ids.json'); if (response.status == 200) { let data = await response.json(); return data; } else { throw new Error(response.status); } } catch (error) { console.log(error); } } getData().then((data) => { for (const details in data.data.items) { const LI = document.createElement('li'); const TITLE = document.createElement('h2'); TITLE.className = 'city-title'; TITLE.innerText = data.data.items[details].title; LI.appendChild(TITLE); LIST.appendChild(LI); for (const id in data.data.items[details].ids) { const DIV = document.createElement('div'); DIV.setAttribute('data-id', data.data.items[details].ids[id]); DIV.className = 'wrapper'; const markup = ` <div class="city-wrapper" > <div class="result-wrapper"> <div class="image-wrapper"> <img src=""/> </div> <div class="content-wrapper"> <div class="content-info"> <div class="info-wrapper"> <h2></h2> <span class="address"></span> </div> </div> <p class="description"></p> </div> </div> </div> </div> `; DIV.innerHTML = markup; LI.appendChild(DIV); } } }); var observer = new IntersectionObserver( function (entries) { if (entries[0].isIntersecting === true) { observer.unobserve(document.querySelector('.city-list')); const getInfo = async function (post) { let infoResponse = await fetch('https://raw.githubusercontent.com/ashes27/infinite/master/single-item.json'); let info = await infoResponse.json(); return info; }; getInfo().then((info) => { console.log(info); let itemsInfo = info.data.items; const DIV = LIST.querySelector('.wrapper'); console.log(DIV); const markup = ` <div class="city-wrapper" > <div class="result-wrapper"> <div class="image-wrapper"> <img src="${itemsInfo.mainImgUrl}"/> </div> <div class="content-wrapper"> <div class="content-info"> <div class="info-wrapper"> <h2>${itemsInfo.visitTitle}</h2> <span class="address">${itemsInfo.address}</span> </div> </div> <p class="description">${itemsInfo.mainDescription}</p> </div> </div> </div> </div> `; DIV.innerHTML = markup; }); } }, { threshold: [0] } ); observer.observe(document.querySelector('.city-list'));
 .city-wrapper { height: 440px; } img { width: 400px; }
 <div style="height: 400px;"></div> <div style="height: 400px;"></div> <div style="height: 400px;"></div> <div style="height: 400px;"></div> <div style="height: 400px;"></div> <div style="height: 400px;"></div> <div style="height: 400px;"></div> <div style="height: 400px;"></div> <ul class="city-list"> </ul>

thanks in advance!提前致谢!

You've told your observer to watch for an intersection of .city-list with the viewport.您已经告诉您的观察者注意.city-list与视口的交集。 But you want to know when any of the .wrapper elements (the ones with the data-id ) in the list gets (or is about to get) visible.但是您想知道列表中的任何.wrapper元素(具有data-id的元素)何时(或即将)可见。

Therefor you have to .observe() these div.wrapper elements and not the complete list:因此,您必须.observe()这些div.wrapper元素,而不是完整列表:

observer.observe(DIV);

To remove an element that has just become visible you have to use the target property of the current IntersectionObserverEntry :要删除刚刚变得可见的元素,您必须使用当前IntersectionObserverEntrytarget属性:

observer.unobserve(entries[0].target);

The data-id you're looking for is also available through the same property:您正在寻找的data-id也可以通过相同的属性获得:

const dataId = entries[0].target.dataset.id;

As we're going to "observe" multiple elements we have to adjust the logic accordingly:当我们要“观察”多个元素时,我们必须相应地调整逻辑:

entries.forEach(entry => {
  // ...
});

A complete, but slightly reduced (dummy data, no getInfo() ) example:一个完整但略微减少的(虚拟数据,没有getInfo() )示例:

 const observer = new IntersectionObserver( function (entries) { entries.forEach(entry => { if (entry.isIntersecting === true) { observer.unobserve(entry.target); // remove the current item from the "watchlist" console.log(entry.target.dataset.id); // the id you're looking for } }); }, { threshold: [0] } ); async function getData() { // dummy data return Promise.resolve({ data: { items: { city1: { title: "City 1", ids: [1, 2, 3] }, city2: { title: "City 2", ids: [4, 5, 6] } } } }) }; getData().then((data) => { const LIST = document.querySelector('.city-list'); for (const details in data.data.items) { const LI = document.createElement('li'); const TITLE = document.createElement('h2'); TITLE.className = 'city-title'; TITLE.innerText = data.data.items[details].title; LI.appendChild(TITLE); LIST.appendChild(LI); for (const id in data.data.items[details].ids) { const DIV = document.createElement('div'); DIV.setAttribute('data-id', data.data.items[details].ids[id]); DIV.className = 'wrapper'; const markup = `<div class="city-wrapper" >...</div>`; DIV.innerHTML = data.data.items[details].ids[id] + "<br />" /* so the ID is directly visible */ + markup; LI.appendChild(DIV); observer.observe(DIV); // add the current DIV to the "watchlist" } } });
 .city-wrapper { height: 440px; } img { width: 400px; }
 <ul class="city-list"></ul>

Or here: https://jsfiddle.net/sDSJrPqw/L0wd6kja/5/或在这里: https://jsfiddle.net/sDSJrPqw/L0wd6kja/5/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM