JavaScript单页应用中如何触发元素的CSS :target伪选择器状态?
如何通过JavaScript触发元素的CSS :target伪选择器状态
核心问题在于:浏览器的:target状态完全绑定到当前URL的哈希值,只有当URL哈希对应页面中存在的元素时,该元素才会进入:target状态。你之前的代码仅更新了路径部分,未将哈希同步到URL中,手动触发hashchange事件也无法让浏览器识别未在URL中存在的哈希。
解决步骤
- 导航时将完整的路径+哈希同步到浏览器历史记录,而非仅更新路径
- 确保页面渲染完成后,URL哈希能对应到已存在的DOM元素(同步渲染可直接操作,异步渲染需等待DOM更新)
- 无需手动触发
hashchange事件,浏览器会自动识别URL哈希并设置:target状态
修改后的代码
JavaScript
for (const $anchor of document.querySelectorAll(`a`)) { $anchor.innerHTML = $anchor.getAttribute(`href`); $anchor.addEventListener(`click`, onClick); } render(`/js`); function onClick(event) { const fullHref = event.target.getAttribute(`href`); const [path, hash] = fullHref.split(`#`); // 当前URL已匹配则直接返回 if (fullHref === location.pathname + location.hash) { return; } event.preventDefault(); // 先渲染目标页面 render(path); // 更新URL为完整的路径+哈希 window.history.pushState({}, ``, fullHref); // 存在哈希时滚动到目标元素(浏览器自动处理:target状态) if (hash) { const $target = document.getElementById(hash); if ($target) { $target.scrollIntoView(); } } } function render(pageName) { const page = document.getElementById(pageName).innerHTML; document.getElementById(`output`).innerHTML = page; }
CSS
#output { height: 200px; outline: 1px solid #00000060; width: 300px; } *:target { background: gold; }
HTML
<template id="/js"> <h1 id="target1">Target 1</h1> <h1 id="target2">Target 2</h1> </template> <template id="/other"> <h1 id="target3">Target 3</h1> <h1 id="target4">Target 4</h1> </template> <ul> <li><a href="/js#target1" target="_self"></a></li> <li><a href="/js#target2" target="_self"></a></li> <li><a href="/other#target3" target="_self"></a></li> <li><a href="/other#target4" target="_self"></a></li> </ul> <p>Current "page":</p> <div id="output"></div>
关键说明
- 直接将完整的
path#hash写入历史记录,让浏览器URL哈希与目标元素ID对应,浏览器会自动为匹配元素添加:target状态 - 无需手动触发
hashchange,URL变更本身会让浏览器处理哈希关联的元素 - 若为异步渲染场景,需用
requestAnimationFrame或setTimeout等待DOM更新完成后再修改URL
内容的提问来源于stack exchange,提问作者RobertAKARobin
相关产品推荐
相关产品推荐

