当我们使用a标签做锚点定位的时候,如果有做固定顶部导航栏的话,直接定位到锚点的时候,会发现定位的位置相较于锚点往下偏移许多。如下图:
而正常情况我们需要的是这样的效果:
这里用到的方法是:根据监听浏览器的url后面hash值的变化,若有hash值改变则使整个页面向下偏移固定导航栏的高度即可;页面结构:
<div class="fixed-wrapper">
<a href="#haveBill" class="target">我是票方</a>
<a href="#haveMoney" class="target">我是资方</a>
</div>
<div class="wrapper haveBill-wrapper" id="haveBill">
<div class="left-dot">我是票方</div>
</div>
<div class="wrapper haveMoney-wrapper" id="haveMoney">
<div class="left-dot">我是资方</div>
</div>
.fixed-wrapper {
position: relative;
width: 100%;
height: 50px;
text-align: center;
top: 0;
left: 0;
line-height: 50px;
background-color: #0094ff;
z-index: 99;
}
上代码
<script>
window.onload = function () {
// 监听页面滚动条事件,避免出现顶部突然塌陷
$(window).scroll(function(){
let scrollTop = $(window).scrollTop();
let height = $('.fixed-wrapper').height();
if(scrollTop > 0) {
$('.fixed-wrapper').css({'position':'fixed'});
$('body').css({'padding-top':height});
}else {
$('.fixed-wrapper').css({'position':'relative'});
$('body').css({'padding-top':0});
}
})
if (("onhashchange" in window) && ((typeof document.documentMode === "undefined") || document.documentMode ==
8)) {
// 浏览器支持onhashchange事件
window.onhashchange = hashChangeFire; // TODO,对应新的hash执行的操作函数
} else {
// 不支持则用定时器检测的办法
setInterval(function () {
var ischanged = isHashChanged(); // TODO,检测hash值或其中某一段是否更改的函数
if (ischanged) {
hashChangeFire(); // TODO,对应新的hash执行的操作函数
}
}, 150);
}
function hashChangeFire() {
if (location.hash) {
let target = $(location.hash);
if (target.length == 1) {
let top = target.offset().top - $('.fixed-wrapper').height(); // 这里减去的高度为设置fixed元素的高度
if (top > 0) {
$('html,body').animate({
scrollTop: top
}, 300);
}
}
}
}
}
</script>
已知问题:此方法是根据hash值变化做的操作,但是当我们点击同一个锚点两次的时候,hash值并没有变化也就没有使得页面偏移,所以建议是点击之后禁用掉当前锚点;
// 获取所有的锚点
let targets = document.querySelectorAll('.target');
$('.target').on('click',function(){
// 给当前点击的锚点链接添加类名 如果之前点击过,阻止事件的触发;
if($(this).hasClass('hasClick')){
return false;
}else {
$(this).siblings().removeClass('hasClick');
$(this).addClass('hasClick');
}
})