点击Load more按钮时滚动到新显示卡片区域顶部的问题
解决点击Load More后滚动位置偏移的问题
嘿,我帮你排查了这个滚动总是跑到锚点下方的问题,主要是DOM更新时机没跟上,还有锚点设置的小细节导致的,咱们来一步步修复它:
问题根源
你调用.show()显示隐藏卡片后,浏览器需要重新计算元素布局,但你立刻就去获取offset().top,这时候拿到的还是元素显示前的旧位置,自然滚动就不准了。另外,把锚点插在item内部,item的内边距、外边距也会影响滚动目标的位置,其实完全不需要额外加锚点~
修复后的完整代码
我调整了代码逻辑,去掉了多余的锚点,并且确保在DOM渲染完成后再计算滚动位置:
var total = $(".container > div").length; if(total > 3){ $(".container").after('<button id="loadmore">Load more</button>'); $(".container > div").slice(3).hide(); } $("body").on("click", "#loadmore", function(){ $(".scroll__anchor").remove(); const $container = $(this).siblings(".container"); // 显示接下来3张卡片 const $newVisibleItems = $container.find(".item:hidden").slice(0, 3).show(); // 所有卡片都显示完就移除按钮 if($container.find(".item:hidden").length === 0){ $(this).remove(); } // 等待浏览器完成DOM重绘后再计算滚动位置 requestAnimationFrame(() => { // 直接取最后一张刚显示的卡片的顶部位置作为目标 const targetTop = $container.find(".item:visible:last").offset().top; $('html, body').animate({ scrollTop: targetTop }, 500); }); })
body{ height: 1500px; } .container{ display: flex; flex-direction: row; flex-wrap: wrap; max-width: 1000px; justify-content: center; } .container .item{ border: 1px solid darkblue; padding: 20px 10px; width: 28%; margin-bottom: 30px; margin-right: 10px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <div class="container"> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> <div class="item">Item</div> </div>
关键优化点
- 去掉多余的锚点元素:直接使用最后一张可见卡片的
offset().top作为滚动目标,避免锚点在item内部带来的位置偏差。 - 用requestAnimationFrame延迟计算:确保浏览器完成新卡片的渲染和布局更新后,再获取准确的位置值,解决了滚动位置不准的核心问题。
- 修正了选择器的错误:你之前写的
$("\.container")里的反斜杠是多余的,正确的类选择器是$(".container"),否则会导致选择器失效。
如果滚动后还是有点小偏差(比如想离顶部留点空隙),可以给targetTop减去一个固定值,比如:
const targetTop = $container.find(".item:visible:last").offset().top - 20; // 往上偏移20px
这样调整后,点击Load More按钮时,页面就会精准滚动到新显示卡片区域的顶部啦~
内容的提问来源于stack exchange,提问作者Freddy
相关产品推荐
相关产品推荐

