You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript单页应用中如何触发元素的CSS :target伪选择器状态?

如何通过JavaScript触发元素的CSS :target伪选择器状态

核心问题在于:浏览器的:target状态完全绑定到当前URL的哈希值,只有当URL哈希对应页面中存在的元素时,该元素才会进入:target状态。你之前的代码仅更新了路径部分,未将哈希同步到URL中,手动触发hashchange事件也无法让浏览器识别未在URL中存在的哈希。

解决步骤

  1. 导航时将完整的路径+哈希同步到浏览器历史记录,而非仅更新路径
  2. 确保页面渲染完成后,URL哈希能对应到已存在的DOM元素(同步渲染可直接操作,异步渲染需等待DOM更新)
  3. 无需手动触发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 00:01:02