英文:
Javascript: link to anchor in hidden container
问题
我有一个容器中的链接,另一个容器中的锚点默认隐藏。
当两个容器都显示时,链接可以正常工作,但当“锚点”容器隐藏时,链接不起作用。
我想要做的是:点击链接时,显示相关容器并跳转到锚点所在的位置。
以下是我尝试的代码,但成功有限(也可以查看这个Fiddle):
$(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");
});
// 为指向隐藏部分锚点的 href 添加点击事件监听器
$("a[href^='#']").click(function(event) {
event.preventDefault(); // 阻止链接的默认行为
var targetId = $(this).attr("href").substring(1); // 获取目标锚点的 id
$(document.location.targetId).slideDown().prev().addClass('active');
});
});
.toggle .header {
display: block;
clear: both;
}
.toggle .header p:before {
content: " ▶ ";
}
.toggle .header.open p:before {
content: " ▼ ";
}
<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>
<p id="ref2">ref2 anchor</p>
</div>
这段代码使用了jQuery来实现所需的功能。希望这对你有帮助。
英文:
I have links in a container with anchors in another container hidden by default.
When both container are showing, the link works without problem, but when the "Anchors" container is hidden, the link does not work.
What I would like to do : on the click of the link, show the relative container and go to the line of the anchor.
Here is what I did, without much success (also as a Fiddle):
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
$(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');
});
});
<!-- language: lang-css -->
.toggle .header {
display: block;
clear: both;
}
.toggle .header p:before {
content: " ▶ ";
}
.toggle .header.open p:before {
content: " ▼ ";
}
<!-- language: lang-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>
<!-- end snippet -->
答案1
得分: 1
看起来有一些相对较小的问题:
- 你从
targetId
中移除了#
,但是如果你要将其与$()
一起使用来按ID查找某个元素,你需要保留它,因为它表示ID选择器。 $(document.location.targetId)
查找document.location
上名为targetId
的属性,然后使用其值作为$
的参数。我认为你想要使用你刚刚创建并填充的targetId
变量。- 你实际上没有滚动到任何地方,只是向下滑动。
我通过以下方式修复了这些问题,不移除 #
,只是使用 $(targetId)
来获取元素,并在 slideDown
的完成回调中使用内置的 "smooth" 动画将目标滚动到视图中:
$(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(); // 阻止链接的默认行为
var targetId = $(this).attr("href"); // 获取目标锚点的ID
var target = $(targetId);
target
.slideDown(() => {
target[0].scrollIntoView({ behavior: "smooth" });
})
.prev()
.addClass('active');
});
});
我还在它们之间插入了一个元素,以便我们可以看到滚动。
(另外,你没有关闭段落标签。我知道大多数情况下你不需要关闭它们,但它会影响格式化程序 [以及其他人阅读你的代码的思维],我建议你关闭它们。我在上面已经这样做了。)
英文:
Looks like there were a couple of relatively-minor problems:
- You were removing the
#
fromtargetId
, but if you're going to use it with$()
to look something up by ID, you need that as it's what indicates an ID selector. $(document.location.targetId)
looks for a property calledtargetId
ondocument.location
, then uses its value as the argument to$
. I think you wanted to just use thetargetId
variable you'd just created and filled in.- You weren't actually scrolling to anything, just sliding it down.
I've fixed that below by not stripping the #
, just using $(targetId)
to get the element, and using the completion callback for slideDown
to scroll the target into view (using the built-in "smooth" animation):
<!-- begin snippet: js hide: false console: false babel: false -->
<!-- language: lang-js -->
$(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"); // Get the id of the target anchor
var target = $(targetId);
target
.slideDown(() => {
target[0].scrollIntoView({ behavior: "smooth" });
})
.prev()
.addClass('active');
});
});
<!-- language: lang-css -->
.toggle .header {
display: block;
clear: both;
}
.toggle .header p:before {
content: " ▶ ";
}
.toggle .header.open p:before {
content: " ▼ ";
}
<!-- language: lang-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 style="height: 50em">A bunch of space so we can see scrolling</div>
<div class="toggle docutils container">
<div class="header docutils container">
<p><strong>Anchors</strong></p>
</div>
<p id="ref1">ref1 anchor</p>
<p id="ref2">ref2 anchor</p>
</div>
<!-- end snippet -->
I also inserted an element between them so we could see the scrolling.
(Also, you weren't closing your paragraphs tags. I realize you don't have to much of the time, but it messes with formatters [and with the minds of other people reading your code], I suggest doing it. I've done it above.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论