CSS 使用文档片段的锚元素选择器
CSS selector for anchor element using document fragment
考虑以下示例代码
<body>
<nav>
<a href="#s1">First Section</a>
<a href="#s2">Section 2</a>
</nav>
<main>
<section id="s1">
<p>Example paragraph
<p>Paragraph 2
</section>
<section id="s2">
<p>Example paragraph
<p>Paragraph 2
</section>
</main>
</body>
我可以 select section
select 与
编辑
section {
background: #fff;
}
section:target {
background: #f00;
}
但我想针对select编辑它的a
仅使用HTML/CSS,我可以想象它像
a[href=:target] {
font-weight: bold;
}
或
a:target(href) {
font-weight: bold;
}
我能想出的唯一解决办法是
HTML:
<body>
<div id="s1"><div id="s2">
<nav>
<a href="#s1">First Section</a>
<a href="#s2">Section 2</a>
</nav>
<main>
<section name="s1">
<p>Example paragraph
<p>Paragraph 2
</section>
<section name="s2">
<p>Example paragraph
<p>Paragraph 2
</section>
</main>
</div></div>
</body>
CSS:
#s1:target a[href="#s1"],
#s2:target a[href="#s2"] {
font-weight: bold;
}
section {
background: #fff;
}
#s1:target section[name="s1"],
#s2:target section[name="s2"] {
background: #f00;
}
不过,我不喜欢这样,因为它引入了不必要的元素(目标 div
)。
没有 JavaScript 是否有干净的方法来做到这一点?
虽然 :target
伪 class 存在用于匹配命名锚点或具有与当前 URL 片段对应的 ID 的元素,但 CSS 不提供用于匹配指向当前 URL 片段的链接的选择器。
没有 JavaScript 就没有干净的方法可以做到这一点。为了适应 CSS(section
元素不能具有 name
属性),我更愿意使用 JavaScript 而不是使用无语义元素和无效属性污染标记。
hashchange
事件是 well-supported,所以如果您负担得起,只需监听该事件并在正确的元素上切换 class:
var navLinks = document.querySelectorAll('nav > a');
window.onhashchange = function() {
for (var i = 0; i < navLinks.length; i++) {
if (navLinks[i].href.match(/(#.*)/)[1] == window.location.hash) {
navLinks[i].className = 'selected';
} else {
navLinks[i].className = '';
}
}
};
var navLinks = document.querySelectorAll('nav > a');
window.onhashchange = function() {
for (var i = 0; i < navLinks.length; i++) {
if (navLinks[i].href.match(/(#.*)/)[1] == window.location.hash) {
navLinks[i].className = 'selected';
} else {
navLinks[i].className = '';
}
}
};
section {
background: #fff;
}
section:target {
background: #f00;
}
a.selected {
font-weight: bold;
}
<nav>
<a href="#s1">First Section</a>
<a href="#s2">Section 2</a>
</nav>
<main>
<section id="s1">
<p>Example paragraph
<p>Paragraph 2
</section>
<section id="s2">
<p>Example paragraph
<p>Paragraph 2
</section>
</main>
基于 BoltClock 代码,2021 年:
window.addEventListener("hashchange", event => {
document.querySelectorAll("nav > a").forEach(link => {
if (new URL(link).hash == new URL(event.newURL).hash) {
link.classList.add("selected");
} else {
link.classList.remove("selected");
}
});
});
您可能还想在加载时设置它
for (const link of document.querySelectorAll("nav > a")) {
if (new URL(link).hash == location.hash) {
link.classList.add("selected");
break;
}
};
考虑以下示例代码
<body>
<nav>
<a href="#s1">First Section</a>
<a href="#s2">Section 2</a>
</nav>
<main>
<section id="s1">
<p>Example paragraph
<p>Paragraph 2
</section>
<section id="s2">
<p>Example paragraph
<p>Paragraph 2
</section>
</main>
</body>
我可以 select section
select 与
section {
background: #fff;
}
section:target {
background: #f00;
}
但我想针对select编辑它的a
仅使用HTML/CSS,我可以想象它像
a[href=:target] {
font-weight: bold;
}
或
a:target(href) {
font-weight: bold;
}
我能想出的唯一解决办法是
HTML:
<body>
<div id="s1"><div id="s2">
<nav>
<a href="#s1">First Section</a>
<a href="#s2">Section 2</a>
</nav>
<main>
<section name="s1">
<p>Example paragraph
<p>Paragraph 2
</section>
<section name="s2">
<p>Example paragraph
<p>Paragraph 2
</section>
</main>
</div></div>
</body>
CSS:
#s1:target a[href="#s1"],
#s2:target a[href="#s2"] {
font-weight: bold;
}
section {
background: #fff;
}
#s1:target section[name="s1"],
#s2:target section[name="s2"] {
background: #f00;
}
不过,我不喜欢这样,因为它引入了不必要的元素(目标 div
)。
没有 JavaScript 是否有干净的方法来做到这一点?
虽然 :target
伪 class 存在用于匹配命名锚点或具有与当前 URL 片段对应的 ID 的元素,但 CSS 不提供用于匹配指向当前 URL 片段的链接的选择器。
没有 JavaScript 就没有干净的方法可以做到这一点。为了适应 CSS(section
元素不能具有 name
属性),我更愿意使用 JavaScript 而不是使用无语义元素和无效属性污染标记。
hashchange
事件是 well-supported,所以如果您负担得起,只需监听该事件并在正确的元素上切换 class:
var navLinks = document.querySelectorAll('nav > a');
window.onhashchange = function() {
for (var i = 0; i < navLinks.length; i++) {
if (navLinks[i].href.match(/(#.*)/)[1] == window.location.hash) {
navLinks[i].className = 'selected';
} else {
navLinks[i].className = '';
}
}
};
var navLinks = document.querySelectorAll('nav > a');
window.onhashchange = function() {
for (var i = 0; i < navLinks.length; i++) {
if (navLinks[i].href.match(/(#.*)/)[1] == window.location.hash) {
navLinks[i].className = 'selected';
} else {
navLinks[i].className = '';
}
}
};
section {
background: #fff;
}
section:target {
background: #f00;
}
a.selected {
font-weight: bold;
}
<nav>
<a href="#s1">First Section</a>
<a href="#s2">Section 2</a>
</nav>
<main>
<section id="s1">
<p>Example paragraph
<p>Paragraph 2
</section>
<section id="s2">
<p>Example paragraph
<p>Paragraph 2
</section>
</main>
基于 BoltClock 代码,2021 年:
window.addEventListener("hashchange", event => {
document.querySelectorAll("nav > a").forEach(link => {
if (new URL(link).hash == new URL(event.newURL).hash) {
link.classList.add("selected");
} else {
link.classList.remove("selected");
}
});
});
您可能还想在加载时设置它
for (const link of document.querySelectorAll("nav > a")) {
if (new URL(link).hash == location.hash) {
link.classList.add("selected");
break;
}
};