带有Intersectionobserver和InnerHTML的无限滚动

如何解决带有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浏览器> 检查> 网络标签中正常工作,但是第一次刷新后#result div意味着它不再检测到#paginate div。

这是怎么回事?我认为这是因为我正在使用innerHTMLobserver在第一次刷新#paginate div之后无法以某种方式检测到#result 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并替换为insertAdjacentHTML

由于innerHTML似乎在#paginate的第一次刷新后重设/忘记了#result,因此observer不再能够检测到#paginate来触发下次#result刷新。

我本可以将innerHTMLappendChild一起使用,但是appendChild在每次div刷新时添加一个新的#result,但我没有真的很喜欢。

作为解决方案,我将刷新的html数据插入#paginate的开头,而不重置/忘记触发id所需的元素observer下次#result刷新。

.then((html) => {
paginate.insertAdjacentHTML('beforebegin',html);
});

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-