【锚点】自制锚点 可绑定在任意元素上
最常用的锚点:利用a标签
但更多的情况是,导航栏样式复杂,不适合使用a标签。本文使用 li 标签,同理也可以绑定在 div 等元素上
a标签锚点 (复习part)
<body>
<nav>
<a href="#1">锚点1</a>
<a href="#2">锚点2</a>
</nav>
<main>
<div id="1">内容1</div>
<div id="2">内容2</div>
</main>
</body>
解释:a标签的href内容,绑定对应的id值
<!--样式参考-->
nav{
width: 140px;
height: 100%;
position: fixed;
}
nav a{
display: block;
}
main{
position: fixed;
left: 140px;
height: 100%;
width: 100%;
overflow: auto;
}
任意标签锚点
使用dom原生操作方法 scrollIntoView
<body>
<nav>
<ul>
<li class="active" name="A">锚点A</li>
<li name="B">锚点B</li>
<li name="C">锚点C</li>
<li name="D">锚点D</li>
<li name="E">锚点E</li>
<li name="F">锚点F</li>
</ul>
</nav>
<header></header>
<main>
<div class="module" id="A">
<span></span><span>内容A</span>
</div>
<div class="module" id="B">
<span></span><span>内容B</span>
</div>
<div class="module" id="C">
<span></span><span>内容C</span>
</div>
<div class="module" id="D">
<span></span><span>内容D</span>
</div>
<div class="module" id="E">
<span></span><span>内容E</span>
</div>
<div class="module" id="F">
<span></span><span>内容F</span>
</div>
</main>
</body>
重点: 锚点操作
<script>
// 点击锚点
$('nav li').on('click',function(){
//高亮状态更新
$('nav li.active').removeClass('active');
$(this).addClass('active');
//对应dom 移动到最上方
//scrollIntoView(),参数可空,这里的 behavior: "smooth" 是缓慢移动
//**注意这个方法只是原生dom的操作方法,jquery不能用**
document.getElementById($(this).attr("name")).scrollIntoView({ behavior: "smooth" });
})
</script>
<!--样式参考-->
body,ul,li{
margin: 0;
padding: 0;
}
nav{
top: 49px;
left: 0px;
height: calc(100% - 49px);
z-index: 999;
position: absolute;
background-color: rgb(58, 65, 85);
text-align: center;
width: 180px;
}
nav ul{
margin-top: 14px;
list-style: none;
}
nav ul li{
width: 122px;
height: 14px;
cursor: pointer;
font-size: 14px;
padding: 17px 0px;
margin-bottom: 8px;
padding-left: 30px;
color: rgba(255, 255, 255, 0.7);
list-style: none;
}
nav ul li:hover{
opacity: 1;
color: white;
}
nav ul li.active{
opacity: 1;
color: white;
background: linear-gradient(90deg, rgba(86, 115, 255, 0) 0%, #5673FF 56%, rgba(86, 115, 255, 0) 100%);
}
header{
width: 100%;
height: 30px;
padding: 9px 0px;
border-bottom: 1px solid #697088;
background-image: linear-gradient(-180deg, #171F36 0%, #222B46 100%);
}
main{
margin-left: 240px;
width: calc(100% - 240px);
position: absolute;
overflow: auto;
height: calc(100% - 50px);
}
main>div{
font-size: 18px;
font-weight: bold;
padding: 30px 0;
height: 400px;
}
main>div span:first-child{
width:10px;
height:10px;
border-radius:50%;
background: #5673FF;
margin-right:12px;
display:inline-block;
}
这里给 ul 和 li 设置 margin: 0; padding: 0;
,是为了li能够居中显示
<body>
<nav></nav>
<header></header>
<main></main>
</body>
$(function(){
//初始化页面
let anchorHtml = '<ul>';
let moduleHtml = '';
for(let i=0;i<7;i++){
anchorHtml += `<li ${i==0?' class="active" ':''}>锚点${String.fromCharCode(65+i)}</li>`;
moduleHtml += `<div class="module"><span></span><span>内容${String.fromCharCode(65+i)}</span></div>`
}
anchorHtml+='</ul>';
$('nav').html(anchorHtml);
$('main').html(moduleHtml);
// 锚点 点击事件
$('nav li').on('click',function(){
$('nav li.active').removeClass('active');
$(this).addClass('active');
document.getElementsByClassName("module")[$(this).index()].scrollIntoView({ behavior: "smooth" });
})
})
附加:锚点随页面滚动更新高亮状态
重点: 锚点 双向绑定
<script>
// 点击锚点
$('nav li').on('click',function(){
$('nav li.active').removeClass('active');
$(this).addClass('active');
document.getElementsByClassName("module")[$(this).index()].scrollIntoView({ behavior: "smooth" });
})
//页面滚动,锚点随页面滚动更新高亮状态
var modules=$(".module");
$('main').scroll(function () {
for (var i = 0; i < modules.length-1 ; i++) {
if($(this).scrollTop()<modules[i+1].offsetTop){ //遍历 计算该dom到容器顶端的高度
$("nav li").eq(i).addClass("active").siblings("li").removeClass("active");
break;
}
}
})
</script>
附加:scrollview中停止滚动的监听
在 dom.scrollIntoView({ behavior: “smooth” }) 时,如果 scroll 监听同时存在的话,会出现锚点的高亮异常变跳动或停在非点击行的情况。
因为 scrollIntoView 没有开始和结束的标志,所以采用手动开关 scroll 监听
// 点击锚点
$('nav li').on('click',function(){
$('nav li.active').removeClass('active');
$(this).addClass('active');
$('main').off('scroll'); //*在scrollIntoView之前关闭监听
document.getElementsByClassName("module")[$(this).index()].scrollIntoView({ behavior: "smooth" });
window.setTimeout(function(){main_body_scroll()},3000) //*在结束之后重新打开监听。(一般3s足够了,若内容过长,也可适当增加)
})
main_body_scroll(); //初始化scroll监听
function main_body_scroll(){
var modules=$(".module");
$('main').scroll(function () {
for (var i = 0; i < modules.length-1 ; i++) {
if($(this).scrollTop()<modules[i+1].offsetTop){ //遍历 计算该dom到容器顶端的高度
$("nav li").eq(i).addClass("active").siblings("li").removeClass("active");
break;
}
}
})
}
附加:目标元素滚动到容器最上方 而不是整个页面最顶处
在使用锚点时,默认滚动到网页最顶处,而一般页面最上方都有标题
📍适用于a标签锚点和任意标签锚点
解决方案:将该容器设置成 position: absolute; height: calc(100% - 50px); overflow: auto;
或者 position: fixed; height:100%; overflow: auto;
(position设置成absolute或者fixed都可以,主要是为了设置高度 重点:height一定要设置且不能超过页面总高度,尤其是在position设置成absolute时,不然页面也会出滚动条,导致锚点计算出问题)
有任何问题,欢迎评论交流!