目录
主要实现两个功能:点击目录定位到页面内容、滚动页面内容定位到目录
一、scrollIntoView方法
Element的scrollIntoView()方法会滚动元素的父容器,使被调用scrollIntoView()的元素对用户可见(滚动到页面可视范围内)
一般用法:
element.scrollIntoView(); // 等同于element.scrollIntoView(true)
element.scrollIntoView(alignToTop); // Boolean型参数
element.scrollIntoView(scrollIntoViewOptions); // Object型参数
参数:
1、alignToTop(可选)
值 | 作用 | 等价配置 |
true | 元素的顶端将和其所在滚动区的可视区域的顶端对齐 | scrollIntoViewOptions: {block: "start", inline: "nearest"} |
false | 元素的底端将和其所在滚动区的可视区域的底端对齐 | scrollIntoViewOptions: {block: "end", inline: "nearest"} |
2、scrollIntoViewOptions
参数 | 是否必填 | 作用 | 默认值 |
behavior | 可选 | 定义动画过渡效果 | "auto"或 "smooth" 之一。默认为 "auto" |
block | 可选 | 定义垂直方向的对齐 | "start", "center", "end", 或 "nearest"之一。默认为 "start" |
inline | 可选 | 定义水平方向的对齐 | "start", "center", "end", 或 "nearest"之一。默认为 "nearest" |
二、scrollTop和offsetTop
1、scrollTop() 方法返回或设置匹配元素的滚动条的垂直位置。如果该方法未设置参数,则返回以像素计的相对滚动条顶部的偏移。
$(selector).scrollTop(offset)
参数 | 描述 |
offset | 可选。规定相对滚动条顶部的偏移,以像素计 |
2、offsetTop()方法返回当前元素相对于其 offsetParent 元素的顶部内边距的距离(像素值)。
topPos = element.offsetTop
三、具体实现
1、页面滚动,定位到目录
let cur = 0;
//滚动函数
function autoActive(e) {
//获取滚动区域滚动距离
var scrollTopLength = $(".right")[0].scrollTop;
//获取内容块
var childs = $(".child");
//默认第一个内容块
var idx = 0;
//判断滚动到哪一个内容块
for (let i = 0; i < childs.length - 1; i++) {
if (scrollTopLength < childs[i].offsetTop) {
idx = i-1
break
}
}
//有变化,修改对应菜单的classname(加上此判断,防止多次触发)
if(cur!=idx){
for(let i=0;i<menuList.length-1;i++){
//添加class
if(i==idx){
if(!$(".menuitem")[i].classList.contains("active")){
$(".menuitem")[i].classList.add("active");
}
}else{//移除其他菜单的class
if($(".menuitem")[i].classList.contains("active")){
$(".menuitem")[i].classList.remove("active");
}
}
}
cur = idx;
}
};
//滚动区域监听
$(".right")[0].addEventListener("scroll", autoActive);
2、点击目录,定位到页面
//菜单监听点击事情
$('.menuitem').on('click',e=>{
//清除右侧滚动监听(防止意外事件)
$(".right")[0].removeEventListener("scroll", autoActive);
//绑定的key值
let key = e.target.dataset.key;
//内容块聚焦到视口顶部
$('#'+key)[0].scrollIntoView({ block: "start", behavior: "smooth" });
//设置点击的菜单的选中状态
$('#m_'+key).siblings().removeClass("active");
$('#m_'+key).addClass("active");
//滚动事件监听(弃用)
// $(".right")[0].addEventListener("scroll", autoActive);
//判断是否滚动完毕,再次添加滚动事件
let temp = 0;
setTimeout(function judge(){
let temp1 = $(".right")[0].scrollTop;
if (temp != temp1) { //两次滚动高度不等,则认为还没有滚动完毕
setTimeout(judge,100);
temp = temp1; //滚动高度赋值
} else{
$(".right")[0].addEventListener("scroll", autoActive);
temp = null; //放弃引用
}
},100);
});
四、示例地址
https://736755244.github.io/scrollIntoView/scrollIntoView.html