一 背景知识:
1.1 #号的作用
#代表网页中的一个位置。其右面的字符,就是该位置的标识符。
就代表网页index.html的print位置。浏览器读取这个URL后,会自动将print位置滚动至可视区域。
为网页位置指定标识符,有两个方法:
一是使用锚点,比如<a name="print"></a>,
二是使用id属性,比如<div id="print">。
HTTP请求不包括#.
2.2 a元素与URL对象
URL对象是浏览器的原生对象,可以用来构造、解析和编码 URL。一般情况下,通过window.URL可以拿到这个对象。
元素和元素都部署了这个接口。这就是说,
它们的 DOM 节点对象可以使用 URL 的实例属性和方法。
例如:我们利用a标签来获取一些东西
// <a href="#box1">我跳到box1</a>
// 上面时html代码
var a = document.querySelector('a');
console.log(a.href); //返回整个 URL
console.log(a.hash); //返回片段识别符,以井号#开头
console.log(a.hostname); //返回域名
console.log(a.search); //返回查询字符串,以问号?开头
二 锚点定位含义
锚点其实就是可以让页面定位到某个位置上的点。在高度较高的页面中经常见到。
// 锚点跳转有两种形式:
*1. a标签 + name / href 属性
*2. 使用标签的id属性
三 锚点定位实现
1、利用#
缺点:url会发生改变,会在url最后面加上片段识别符#box2,这样就改变了URL的路径,这是我们不想看到的.因为再次刷新的时候回出现问题.
<a href="#box1">我跳到box1</a>
<a href="#" name="#box2">我跳到box2</a>
<div id="box1"></div>
<div id="box2"></div>
2、scrollTop.offset
1、这种方法url不会发生改变,阻止了a标签的默认行为.所以a标签不会跳转.
2、 document.querySelector(target).offsetTop;
$(target).offset().top 都是去求出盒子参照body定位对应的top值,这是因为offet家族的定义是:
如果元素自身是非固定定位,并且所有的父元素都没有定位,那么他的定位父级是body .
3、 上面代码的target得到格式都是#box1,此时在原生中利用属性选择器来获取元素要很多.
document.querySelector(target) 等价于
document.querySelector('#box1')
<script>
var aList = document.querySelectorAll('a');
//给每一个a标签注册点击事件
for( var i=0;i < aList.length;i++){
aList[i].addEventListener('click', function(e){
//阻止a标签的默认行为
e = e || window.event;
e.preventDefault();
//获取整个href路径
//var target = this.href;
//获取#片段识别符
var target = this.hash;
//获取box参照于body定位的top值
var offsetTop = document.querySelector(target).offsetTop;
//将页面跳转到对应的位置
document.documentElement.scrollTop = offsetTop;
});
}
</script>
3、srollIntoView
含义
scrollIntoView 是 HTMLElement 集合下的一个 API,每一个 HTML 元素都拥有这个 API。它的作用就和字面意思一样:滚动到可视区。
Element 接口的 scrollIntoView()方法会滚动元素的父容器,使被调用 scrollIntoView()的元素对用户可见。
语法
语法:
element.scrollIntoView(); // 等同于 element.scrollIntoView(true)
element.scrollIntoView(alignToTop); // Boolean 型参数
element.scrollIntoView(scrollIntoViewOptions); // Object 型参数
参数解释:
alignToTop:它是一个 Boolean 值,它用来规定元素出现在可视区后与可视区的对齐方式,为 true 代表顶端对齐,false 代表低端对齐。
scrollIntoViewOptions:它是一个对象,该参数主要是配置元素的动画效果以及位置的,它有一下 3 个属性:
behavior:它定义元素出现在可视区内过程的动画,有 auto 和 smooth 两种选择。
block:定义元素的垂直方向的对齐方式,有"start", “center”, “end”, 或 “nearest” 4 个选项,默认 start。
inline:定义元素水平对齐方式,有"start", “center”, “end”, 或 “nearest"4 个选项,默认"nearest”。
有些小伙伴可能发现两个参数都能定义元素的对齐方式,它们之间有什么联系呢?当 alignToTop 为 true 时,scrollIntoViewOptions: {block: “start”, inline: “nearest”}这是它的默认值,当 alignToTop 为 false 时,scrollIntoViewOptions: {block: “end”, inline: “nearest”}这是它的默认值。
<body>
<div class="box">
<div class="left">
<p>第一段内容</p>
<p>第二段内容</p>
<p>第三段内容</p>
</div>
<div class="right">
<div class="content">
我是第一段内容
</div>
<div class="content">
我是第二段内容
</div>
<div class="content">
我是第三段内容
</div>
</div>
</div>
</body>
<script>
// 获取三个标题元素
let pDomList = document.getElementsByTagName('p');
// 获取三段内容元素
let contentDomList = document.getElementsByClassName('content');
// 添加点击事件
for (let index = 0; index < pDomList.length; index++) {
pDomList[index].addEventListener('click', () => {
contentDomList[index].scrollIntoView({
behavior: 'smooth',
block: 'start',
inline: 'start'
})
})
}
</script>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 100vw;
height: 100vh;
display: flex;
overflow: hidden;
}
.left {
width: 300px;
height: 100%;
border-right: 2px solid green;
}
p {
height: 40px;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border: 1px solid #ccc;
}
.right {
flex: 1;
overflow: auto;
}
.content {
width: 100%;
height: 1000px;
border-top: 1px solid yellow;
padding: 20px;
box-sizing: border-box;
}
</style>