据我所知,有两种方法可以更改URL末尾的哈希值:
下面是一个简单的示例。有两个链接按预期工作:
有没有一种方法可以实现"两全其美",即更改窗口哈希值而不滚动页面,并且触发CSS的:target伪类?
注意:我已在OS X 10.13上测试了Chrome 64和Firefox 58。
window.location.hash
和history.pushState
。但是,history.pushState
不会触发CSS的:target
伪类,因此不可行。
修改document.location.hash而不导致页面滚动的方法的答案演示了一种修改location.hash
的方法,但这种解决方法无法触发具有匹配ID的元素上的:target
伪类。下面是一个简单的示例。有两个链接按预期工作:
:target
被触发并显示选项卡,但如果需要,它们也会滚动到视图中。另外两个链接不起作用::target
未被触发,但滚动被阻止。
(function() {
function setHash(event) {
event.preventDefault();
var decoy = document.querySelector(".dummy-tabpanel");
var tabId = event.currentTarget.getAttribute('href');
var id = tabId.replace( /^#/, '' );
var tabPanel = document.getElementById(id);
decoy.style.top = document.body.scrollTop + 'px';
tabPanel.setAttribute('id', '');
decoy.setAttribute('id', id);
window.location.hash = tabId;
decoy.setAttribute('id', '');
tabPanel.setAttribute('id', id);
return false;
}
function setHashDirectly(event) {
event.preventDefault();
var tabId = event.currentTarget.getAttribute('href');
window.location.hash = tabId;
return false;
}
var tabLinks = document.querySelectorAll('a[href^="#"]');
for (var tabLink of tabLinks) {
tabLink.addEventListener("click", tabLink.classList.contains('direct') ? setHashDirectly : setHash );
}
})()
.tabs {
margin-top: 300px; // attempt to make scrolling necessary
}
.tabs [role="tabpanel"] {
display: none;
}
.tabs [role="tabpanel"]:target {
display: block;
}
.dummy-tabpanel {
position: absolute;
visibility: hidden;
}
<nav>
<ul>
<li>
<a href="#one">one (doesn't scroll or trigger <code>:target</code>)</a>
</li>
<li>
<a href="#two">two (doesn't scroll or trigger <code>:target</code>)</a>
</li>
<li>
<a href="#three" class="direct">three (triggers <code>:target</code> but scrolls)</a>
</li>
<li>
<a href="#four" class="direct">four (triggers <code>:target</code> but scrolls)</a>
</li>
</ul>
</nav>
<div class="tabs">
<div role="tabpanel" id="one">
this is the first tab (won't display)
</div>
<div role="tabpanel" id="two">
this is the two tab (won't display)
</div>
<div role="tabpanel" id="three">
this is the third tab (should display)
</div>
<div role="tabpanel" id="four">
this is the forth tab (should display)
</div>
</div>
<div class="dummy-tabpanel"></div>
注意:我已在OS X 10.13上测试了Chrome 64和Firefox 58。
:target
显示隐藏内容,但是您不想跳转到:target
目标吗? - zer00ne