使用 Intersectionobserver 和 InnerHTML 的无限滚动
Infinite Scroll With Intersectionobserver & InnerHTML
我正在尝试无限滚动(没有 jQuery)以在页面中显示更多结果。我正在使用 IntersectionObserver
来检测一个名为 #paginate
的 div 并且每次它进入屏幕时, #result
div 都会被刷新。
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>
它有效,但它只在第一次有效并且之后不会刷新 #result
div。我可以看到 fetch
在 Web Browser > Inspect > Network 选项卡中工作,但是#result
div 第一次刷新后没有 activity,这意味着它不再检测到 #paginate
div。
这是怎么回事?我认为这是因为我正在使用 innerHTML
并且 observer
在 #result
的第一次刷新后以某种方式无法检测到 #paginate
div div。我该如何解决?
我用 jQuery 和 .scroll
函数做到了,并像这样使用 ajax,也许我的代码可以帮助您并根据您的需要进行调整。
$('#customersList').scroll(function () {
if ($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight - 5000) {
// Do your stuff here.
getCustomers();
}
})
function getCustomers(){
let $customerList = $('#customersList');
let offset = ($customerList.attr('data-offset')) ?
$customerList.attr('data-offset') : 0;
if ($customerList.data('requestRunning')) {
return;
}
$customerList.data('requestRunning', true);
return $.ajax({
type: "GET",
data: {offset: offset},
url : routes.routes.customers.get
})
.done(function (data) {
let _htmlCustomersList = ($customerList.is(':empty')) ? '' : $customerList.html();
let response = data.data;
if (response) {
for (const i in response) {
let v = JSON.parse(response[i]);
_htmlCustomersList += '<div class="client-group edit" data-id="' + v['id'] + '"></div><hr>';
}
offset = parseInt(offset) + 200;
$customerList.attr('data-offset', offset).html(_htmlCustomersList);
}
})
.always(function () {
$customerList.data('requestRunning', false);
});
}
我的 getCustomer 函数在到达页面末尾之前运行并且每次加载 200 个以上的项目。
希望对您有所帮助
您似乎在第一次更新后删除了 #paginate
,因为它在 #result
.
请使用缩进:)
#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);
});
希望对您有所帮助
我已经删除了 innerHTML
and replaced it with insertAdjacentHTML
.
因为innerHTML
好像reset/forget#paginate
在#result
第一次刷新后,所以observer
检测不到#paginate
触发下一个 #result
刷新。
我本可以使用 innerHTML
和 appendChild
来做同样的事情,但是 appendChild
在每次 #result
刷新时添加一个新的 div
,我没有这样做很喜欢
作为解决方案,我在 #paginate
开始之前插入刷新的 html
数据,而没有 resetting/forgetting 它是 id
[=16] 所需的元素=] 触发下一个 #result
刷新。
.then((html) => {
paginate.insertAdjacentHTML('beforebegin', html);
});
我正在尝试无限滚动(没有 jQuery)以在页面中显示更多结果。我正在使用 IntersectionObserver
来检测一个名为 #paginate
的 div 并且每次它进入屏幕时, #result
div 都会被刷新。
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>
它有效,但它只在第一次有效并且之后不会刷新 #result
div。我可以看到 fetch
在 Web Browser > Inspect > Network 选项卡中工作,但是#result
div 第一次刷新后没有 activity,这意味着它不再检测到 #paginate
div。
这是怎么回事?我认为这是因为我正在使用 innerHTML
并且 observer
在 #result
的第一次刷新后以某种方式无法检测到 #paginate
div div。我该如何解决?
我用 jQuery 和 .scroll
函数做到了,并像这样使用 ajax,也许我的代码可以帮助您并根据您的需要进行调整。
$('#customersList').scroll(function () {
if ($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight - 5000) {
// Do your stuff here.
getCustomers();
}
})
function getCustomers(){
let $customerList = $('#customersList');
let offset = ($customerList.attr('data-offset')) ?
$customerList.attr('data-offset') : 0;
if ($customerList.data('requestRunning')) {
return;
}
$customerList.data('requestRunning', true);
return $.ajax({
type: "GET",
data: {offset: offset},
url : routes.routes.customers.get
})
.done(function (data) {
let _htmlCustomersList = ($customerList.is(':empty')) ? '' : $customerList.html();
let response = data.data;
if (response) {
for (const i in response) {
let v = JSON.parse(response[i]);
_htmlCustomersList += '<div class="client-group edit" data-id="' + v['id'] + '"></div><hr>';
}
offset = parseInt(offset) + 200;
$customerList.attr('data-offset', offset).html(_htmlCustomersList);
}
})
.always(function () {
$customerList.data('requestRunning', false);
});
}
我的 getCustomer 函数在到达页面末尾之前运行并且每次加载 200 个以上的项目。
希望对您有所帮助
您似乎在第一次更新后删除了 #paginate
,因为它在 #result
.
请使用缩进:)
#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);
});
希望对您有所帮助
我已经删除了 innerHTML
and replaced it with insertAdjacentHTML
.
因为innerHTML
好像reset/forget#paginate
在#result
第一次刷新后,所以observer
检测不到#paginate
触发下一个 #result
刷新。
我本可以使用 innerHTML
和 appendChild
来做同样的事情,但是 appendChild
在每次 #result
刷新时添加一个新的 div
,我没有这样做很喜欢
作为解决方案,我在 #paginate
开始之前插入刷新的 html
数据,而没有 resetting/forgetting 它是 id
[=16] 所需的元素=] 触发下一个 #result
刷新。
.then((html) => {
paginate.insertAdjacentHTML('beforebegin', html);
});