如何用JavaScript或jQuery实现类似Facebook的整div懒加载效果?
实现整个Div的懒加载(类似Facebook效果)
要实现整个div内容的同步懒加载,核心是监听div是否进入视口,当它出现在用户视野内时再渲染完整内容。下面提供两种可行方案:
方案1:使用原生Intersection Observer API(推荐,性能更优)
这种方式是现代浏览器推荐的懒加载方案,无需依赖jQuery,性能更稳定。
步骤1:改造HTML结构
把需要懒加载的div内容暂存到data-content属性中,同时设置占位区域避免布局跳动:
<style type="text/css"> .lazyload { background:#f3f3f3; padding:10px; margin:10px; border-radius:6px; min-height: 300px; /* 设置占位高度,防止滚动时布局跳动 */ } .lazyload img{border-radius:6px;} .placeholder { display: flex; align-items: center; justify-content: center; height: 100%; color: #999; } </style> <div class="lazyload" data-content='<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSEgT2riAqvy_1iVAA3tKeG1JkTKnBA2g4lFQ&usqp=CAU" width="100%"><h2> A Post Title </h2><p> Lprem ipsum dolor. This is a simple dummy text </p>'> <div class="placeholder">加载中...</div> </div>
步骤2:编写监听逻辑
// 初始化Intersection Observer实例 const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const lazyDiv = entry.target; // 将预存内容插入div lazyDiv.innerHTML = lazyDiv.dataset.content; // 移除监听,避免重复触发 observer.unobserve(lazyDiv); } }); }, { rootMargin: '200px 0px' // 提前200px开始加载,提升用户体验 }); // 给所有懒加载div添加监听 document.querySelectorAll('.lazyload').forEach(div => { observer.observe(div); });
方案2:使用jQuery结合滚动监听(兼容旧浏览器)
如果需要兼容不支持Intersection Observer的旧浏览器,可以用jQuery的滚动监听方案:
步骤1:HTML结构(和方案1一致)
<style type="text/css"> .lazyload { background:#f3f3f3; padding:10px; margin:10px; border-radius:6px; min-height: 300px; } .lazyload img{border-radius:6px;} .placeholder { display: flex; align-items: center; justify-content: center; height: 100%; color: #999; } </style> <div class="lazyload" data-content='<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSEgT2riAqvy_1iVAA3tKeG1JkTKnBA2g4lFQ&usqp=CAU" width="100%"><h2> A Post Title </h2><p> Lprem ipsum dolor. This is a simple dummy text </p>'> <div class="placeholder">加载中...</div> </div>
步骤2:jQuery逻辑
$(document).ready(function() { // 判断元素是否进入视口(含提前触发范围) function isInViewport(element) { const rect = element.getBoundingClientRect(); return ( rect.top <= $(window).height() + 200 && // 提前200px触发加载 rect.bottom >= -200 ); } // 加载懒加载内容 function loadLazyDivs() { $('.lazyload').each(function() { if (isInViewport(this) && !$(this).hasClass('loaded')) { $(this).html($(this).data('content')).addClass('loaded'); } }); } // 页面初始化时先检查一次 loadLazyDivs(); // 滚动和窗口 resize 时触发检查 $(window).on('scroll resize', loadLazyDivs); });
关键注意事项
- 占位高度:必须给
.lazyload设置min-height,否则滚动时会出现布局跳动的问题。 - 提前加载:通过
rootMargin(方案1)或提前判断距离(方案2)让内容在进入视口前就开始加载,减少用户等待感。 - 避免重复加载:加载完成后要移除监听或添加
loaded类标记,防止逻辑重复触发。
内容的提问来源于stack exchange,提问作者Md. Ibrahim
相关产品推荐
相关产品推荐

