使用 Intersectionobserver 和 InnerHTML 的无限滚动

我正在尝试进行无限滚动(不使用 jQuery)以在页面中显示更多结果。我正在使用 anIntersectionObserver来检测调用的 div #paginate,每次它进入屏幕时,#resultdiv 都会被刷新。

var result = document.querySelector('#result');

var paginate = document.querySelector('#paginate');


var observer = new IntersectionObserver(entries => {

if (entries.some(entry => entry.isIntersecting))

{

var pagination = 10;

fetch('/kernel/search.php?pagination='+pagination)

.then((response) => {

return response.text();

})

.then((html) => {

result.innerHTML = html;

});

}

});


observer.observe(paginate);

这是带有 HTML 的完整代码视图:


<html>

<body>


<div class="row justify-content-sm-center justify-content-md-center justify-content-lg-center justify-content-xl-start no-gutters min-vw-100" id="result">

<div class="col-sm-11 col-md-11 col-lg-9-result col-xl-4-result order-0">


<div class="card mx-3 mt-3">

<div class="card-body">

<a class="text-decoration-none" href="?topic=result-1">

<h5 class="card-title"> 

Result 1    

</h5>

</a>

<p class="card-text text-truncate"> 

Result 1 description.</p>

</div>

</div>


<div class="card mx-3 mt-3">

<div class="card-body">

<a class="text-decoration-none" href="?topic=result-2">

<h5 class="card-title"> 

Result 2    

</h5>

</a>

<p class="card-text text-truncate"> 

Result 2 description.</p>

</div>

</div>


<div class="alert alert-light text-dark text-center border mx-3 my-3" id="paginate">

More results

</div>


</div>

</div>


<script>    

var result = document.querySelector('#result');

var paginate = document.querySelector('#paginate');


var observer = new IntersectionObserver(entries => {

if (entries.some(entry => entry.isIntersecting))

{

var pagination = 10;

fetch('/kernel/search.php?pagination='+pagination)

.then((response) => {

return response.text();

})

.then((html) => {

result.innerHTML = html;

});

}

});


observer.observe(paginate);

</script>


</body>

</html>

它有效,但它只在第一次有效,之后不会刷新#resultdiv。我可以在Web Browser > Inspect > Networkfetch选项卡中看到工作,但在第一次刷新 div 后没有任何活动,这意味着它不再检测到div。#result#paginate


这里发生了什么?我认为这是因为我正在使用 aninnerHTML并且在 div的第一次刷新之后observer以某种方式无法检测到div 。我该如何解决这个问题?#paginate#result


繁花如伊
浏览 210回答 4
4回答

扬帆大鱼

看来您是#paginate在第一次更新后删除的,因为它在#result.

翻过高山走不出你

.scroll我用 jQuery 和函数完成了它,并像这样使用了 ajax,也许我的代码可以帮助您并使其适应您的需求。$('#customersList').scroll(function () {&nbsp; &nbsp; if ($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight - 5000) {&nbsp; &nbsp; &nbsp; &nbsp; // Do your stuff here.&nbsp; &nbsp; &nbsp; &nbsp; getCustomers();&nbsp; &nbsp; }})function getCustomers(){&nbsp; &nbsp; let $customerList = $('#customersList');&nbsp; &nbsp; let offset&nbsp; &nbsp; &nbsp; &nbsp; = ($customerList.attr('data-offset')) ?&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; $customerList.attr('data-offset') : 0;&nbsp; &nbsp; if ($customerList.data('requestRunning')) {&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp; &nbsp; $customerList.data('requestRunning', true);&nbsp; &nbsp; return $.ajax({&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; type: "GET",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data: {offset: offset},&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; url : routes.routes.customers.get&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; .done(function (data) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let _htmlCustomersList = ($customerList.is(':empty')) ? '' : $customerList.html();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let response&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= data.data;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (response) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (const i in response) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let v = JSON.parse(response[i]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _htmlCustomersList += '<div class="client-group edit" data-id="' + v['id'] + '"></div><hr>';&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; offset = parseInt(offset) + 200;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $customerList.attr('data-offset', offset).html(_htmlCustomersList);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; .always(function () {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $customerList.data('requestRunning', false);&nbsp; &nbsp; &nbsp; &nbsp; });}我的 getCustomer 函数在到达页面末尾之前运行,并且每次加载 200 个以上的项目。我希望这可以帮助你一点点

隔江千里

#result div 是内容的主要包装器,使用 innerHTML 更新 div 的内容,将导致替换 div 内的整个内容...除了 innerHTML 是绝对的,并且会删除任何 DOM 对象(及其事件)因此是不好的做法这一事实之外,它也不是一个好的解决方案,因为您希望在滚动时附加而不是替换数据我建议在分页上方添加一个 div,它将保存添加的数据,例如:...<div id="result"></div><div class="alert alert-light text-dark text-center border mx-3 my-3" id="paginate">More results</div>然后对添加的内容使用某种附加,例如:.then((html) => {let res = new DOMParser().parseFromString(html, "text/xml");document.getElementById("result").appendChild(res);});希望有帮助

SMILET

我已将其删除innerHTML并替换为insertAdjacentHTML.因为似乎在第一次刷新后innerHTML重置/忘记了,所以无法再检测到触发下一次刷新。#paginate#resultobserver#paginate#result我本可以使用innerHTMLwithappendChild来做同样的事情,但每次刷新appendChild都会添加一个新的,我不太喜欢。div#result作为解决方案,我html在开始之前插入刷新的数据#paginate而不重置/忘记它是触发下一次刷新id所需的元素。observer#result.then((html)&nbsp;=>&nbsp;{ paginate.insertAdjacentHTML('beforebegin',&nbsp;html); });
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript