点击锚点链接时显示隐藏容器并定位锚点的JS实现问题
解决隐藏容器内锚点链接失效问题
我在一个容器中设置了指向另一个默认隐藏容器内锚点的链接,当两个容器都显示时链接正常工作,但“Anchors”容器隐藏时链接失效。需求是:点击链接时,自动显示对应的容器并定位到锚点位置。
原尝试代码
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script> <div class="toggle docutils container"> <div class="header docutils container"> <p><strong>Keywords</strong></p> </div> <pre class="literal-block"> <a class="reference internal" href="#ref1"><span class="std std-ref">ref1</span></a> value = 1 <a class="reference internal" href="#ref2"><span class="std std-ref">is_planar</span></a> value= 2 </pre> </div> <div class="toggle docutils container"> <div class="header docutils container"> <p><strong>Anchors</strong></p> </div> <p id="ref1">ref1 anchor <p id="ref2">ref2 anchor </div>
CSS
.toggle .header { display: block; clear: both; } .toggle .header p:before { content: " ▶ "; } .toggle .header.open p:before { content: " ▼ "; }
JavaScript
$(document).ready(function() { $(".toggle > *").hide(); $(".toggle .header").show(); $(".toggle .header").click(function() { $(this).parent().children().not(".header, .wy-table-responsive").toggle(400); $(this).parent().children(".wy-table-responsive").children().toggle(400); $(this).parent().children(".header").toggleClass("open"); $(this).parent().children(".wy-table-responsive").toggleClass("open"); }); // Add click event listeners to links with href pointing to anchors in hidden section $("a[href^='#']").click(function(event) { event.preventDefault(); // Prevent default behavior of link var targetId = $(this).attr("href").substring(1); // Get the id of the target anchor $(document.location.targetId).slideDown().prev().addClass('active'); }); });
解决方案
原代码中$(document.location.targetId)的写法错误,无法正确定位目标元素。调整点击事件逻辑,先展开锚点所在的隐藏容器,再滚动到锚点位置即可解决问题:
修正后的JavaScript代码
$(document).ready(function() { $(".toggle > *").hide(); $(".toggle .header").show(); // 容器展开/收起逻辑 $(".toggle .header").click(function() { const $parent = $(this).parent(); $parent.children().not(".header, .wy-table-responsive").toggle(400); $parent.children(".wy-table-responsive").children().toggle(400); $(this).toggleClass("open"); $parent.children(".wy-table-responsive").toggleClass("open"); }); // 锚点链接点击逻辑 $("a[href^='#']").click(function(event) { event.preventDefault(); const targetId = $(this).attr("href"); const $target = $(targetId); // 目标元素存在时执行逻辑 if ($target.length) { const $toggleContainer = $target.closest(".toggle"); const $header = $toggleContainer.find(".header"); // 容器未展开则触发展开 if (!$header.hasClass("open")) { $header.click(); } // 等待展开动画完成后滚动到锚点 setTimeout(() => { $target[0].scrollIntoView({ behavior: 'smooth', block: 'start' }); }, 400); // 与toggle动画时长保持一致 } }); });
关键说明
- 定位目标容器:用
closest(".toggle")精准找到锚点所在的隐藏容器,避免操作错误容器。 - 复用展开逻辑:直接调用容器头部的点击事件,保持代码逻辑统一,减少冗余。
- 延迟滚动:容器展开有400ms动画,等待动画完成后再滚动,确保定位位置准确。
- 平滑滚动:使用
scrollIntoView实现平滑定位,提升用户体验。
内容的提问来源于stack exchange,提问作者GMV871
相关产品推荐
相关产品推荐

