学习时间:
JavaScript元素三大系列
学习内容:
javascript三系列
1、熟练掌握offset系列
2、熟练掌握client系列
3、掌熟练掌握scroll系列
4、掌握scroll兼容性问题
1.offset系列
offset译为偏移、补偿和位移,所以offset相关的属性可以动态的获取元素的位置(偏移),大小……等.
1.1 offsetParent 获取父元素
导图:
- 获取该元素带有定位的父元素。
- 如果元素自身有fixed固定定位,则offsetParent返回结果为null。
- 如果找到存在定位的父元素,offsetParent将返回该父元素。
- 如果没有任何一个父元素(不断向上,找到为之)存在定位,offsetParent将返回body
- body元素的offsetParent是null
案例:
1.2 offsetWidth和offsetHeight
导图:
- 获取元素自身(包括padding、border、width/height)的宽度或高度。
- offsetWidth = padding + border + width;
- offsetHeight = padding + border + height;
- 也就是说盒子模型中除了margin不要,其他的都要
- 返回值为Number类型,不带单位
1.3 offsetLeft和offsetTop
导图:
- 获取当前元素到最近的定位父盒子(也可以是间接父级)的左侧或顶部偏移量(边距)。
- 如果父元素或祖先元素没有定位,则以body为基准。
- offsetLeft或offsetTop从父元素的padding开始算,而不是父元素的border
- 返回值为Number类型,不带单位
1.4 offset系列于与stye的区别
offset系列:
- 可以获取任意样式表中的样式值
- 获取的数值无单位
- offsetTop和offsetLeft是和父级元素作比较
- offsetWidth和offsetHeight包含padding、border、width
- offset系列是只读属性,无法设置属性
style:
- 只能获取行内样式表中的样式值
- 获取的数值有单位,即px
- style.top和style.left是和自作比较,当然也可以自绝父相,和父元素比较
- style.width和style.height获取的只是单纯的宽度和高度
- style是可读可写的属性,也就是说使用style既可以获取,也可以设置。
1.5 总结
总结思维导图:
总的来说offset属性在开发中基本上是用于获取元素自身整体的宽高、与带定位的父元素的偏移量以及父级元素对象,但是它对于我们来说还是比较重要的,因为我们可以使用这个属性来计算元素触发事件后运动距离的动态效果……等。
案例1:拖拽登录框移动
算法导图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bGEmWMRc-1606666801493)(E:\前端\Java Script\笔记\元素移动.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>元素移动</title>
<style>
* {
padding: 0;
margin: 0;
}
.btn {
width: 80px;
height: 20px;
}
.big {
width: 100%;
height: 580px;
background-color: rgba(0, 0, 0, .3);
overflow: hidden;
display: none;
position: relative;
}
.box {
width: 200px;
height: 200px;
background-color: skyblue;
text-align: center;
position: absolute;
left: 520px;
top: 120px;
}
</style>
</head>
<body>
<input type="button" value="点击登录" class="btn">
<div class="big">
<div class="box">
<h3>登录</h3>
<div>
<label>账号:</label>
<input type="text">
</div>
<div>
<label>密码:</label>
<input type="password">
</div>
</div>
</div>
<script>
window.onload = function() {
var btn = document.querySelector(".btn");
var big = document.querySelector(".big");
var box = document.querySelector(".box");
btn.onclick = function(e) {
btn.style.display = "none";
big.style.display = "block";
}
box.addEventListener("mousedown", function(e) {
var x = e.clientX - box.offsetLeft;
var y = e.clientY - box.offsetTop;
document.onmousemove = function(e) {
var left = e.clientX - x;
var top = e.clientY - y;
box.style.left = left + "px";
box.style.top = top + "px";
}
})
document.addEventListener("mouseup", function() {
// 删除事件
this.onmousemove = null;
this.onmouseup = null;
})
}
</script>
</body>
</html>
案例2:电商放大镜功能
算法导图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v4h0e2uF-1606666801495)(E:\前端\Java Script\笔记\放大镜.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>放大镜</title>
<style>
* {
padding: 0;
margin: 0;
background-color: #f1f1ff;
}
body {
/* 清除浮动 */
overflow: hidden;
}
.left {
width: 430px;
height: 430px;
background: transparent url(./images/oppo.png) fixed;
/* 自绝父相 */
position: relative;
float: left;
}
.shade {
width: 218.4px;
height: 218.4px;
background-color: rgba(0, 0, 0, .3);
display: none;
/* 自绝父相 */
position: absolute;
}
.imgBox {
width: 430px;
height: 430px;
background-color: pink;
float: left;
margin-left: 10px;
/* 父相 */
position: relative;
overflow: hidden;
display: none;
}
.img {
/* 子绝 */
position: absolute;
width: 860px;
height: 860px;
}
</style>
</head>
<body>
<div class="left">
<div class="shade"></div>
</div>
<div class="imgBox">
<img src="./images/oppo.png" alt="你好" class="img">
</div>
<script>
window.onload = function() {
// 获取左边的大盒子
var left = document.querySelector(".left");
// 获取获取左边盒子内的大盒子
var son = document.querySelector(".shade");
var imgBox = document.querySelector(".imgBox");
var img = document.querySelector(".img");
// 给左边的大盒子添加鼠标移入事件
left.addEventListener("mouseover", function(e) {
son.style["display"] = "block";
imgBox.style["display"] = "block";
})
// 给子盒子添加移动时触发的事件
son.addEventListener("mousemove", function(e) {
// 获取光标的坐标
var cursorX = e.pageX;
var cursorY = e.pageY;
// 遮罩左边距离大盒子左边框的距离
this.style["left"] = cursorX - son.clientWidth / 2 + "px";
this.style["top"] = cursorY - son.clientHeight / 2 + "px";
// offsetTop 和 offsetLeft 求的是当前元素(与具有定位的父元素)的上左边距离
//如果父元素没有定位,则以body为基准
if (son.offsetLeft <= 0) {
this.style["left"] = "0px";
} else if (son.offsetLeft >= left.offsetWidth - son.offsetWidth) {
this.style["left"] = left.offsetWidth - son.offsetWidth + "px";
}
if (son.offsetTop <= 0) {
this.style["top"] = "0px";
} else if (son.offsetTop >= left.offsetHeight - son.offsetHeight) {
this.style["top"] = left.offsetHeight - son.offsetHeight + "px";
}
img.style["left"] = -son.offsetLeft * 2 + "px";
img.style["top"] = -son.offsetTop * 2 + "px";
})
}
</script>
</body>
</html>
2. client系列
client有客户、客户端的意思。使用client系列的相关属可以动态的获取元素的边框大小、元素大小……等相关信息。
2.1 clientTop和clientLeft
- clientTop属性用于获取当前元素上边框的大小或粗细
- clientLeft属性用于获取当前元素左边框的大小或粗细
- 返回值为Number类型,不带单位
2.2 clientWidth和clientHeight
- 获取当前元素在页面上的可见宽度或高度(padding、width/height)的大小,切记:不包括border。
- clientWidth = padding + width;
- clientHeight = padding + height;
- 返回值为Number类型,不带单位
3. scroll系列
scroll译为滚动。使用scroll系列的属性可以动态获取该元素的大小,滚动距离或被卷走的距离。
由于浏览器的高度是固定的,但是一般页面的高度会远远大于浏览器的高度,有时候页面的宽度也会大于浏览器的宽度,所以scroll系列一般讨论的是网页整体与浏览器之间的关系。
3.1 scrollLeft和scrollTop
- scrollLeft:获取某个元素被其父级元素卷到左侧的距离。
- scrollTop:获取某个元素被其父级元素卷到上侧的距离。
- 页面被卷去的部分:如果浏览器的高度或宽度不足以显示整个页面时,会自动出现滚动条,当滚动条向下或向右滑动时,页面左侧或上部会逐渐隐藏,隐藏的页面宽度或高度就是被卷去的部分,而滚动条在滚动的时候就会触发onscroll事件,即滚动条滚动事件。
3.2 scrollWidth和ScrollHeight
- 获取当前元素自身的实际宽度或高度(padding、width/height),切记:不包含border。
- scrollWidth = padding + width;
- scrollHeight = padding + height;
- 返回值为Number类型,不带单位。
案例:淘宝侧边栏
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>淘宝左侧菜单</title>
<style>
div {
width: 800px;
height: 1000px;
background-color: rgba(0, 0, 0, .2);
margin: 0 auto;
position: relative;
margin-top: 10px;
}
ul {
position: absolute;
left: 1000px;
top: 400px;
}
li {
list-style: none;
font-size: 12px;
width: 30px;
height: 35px;
border: 1px solid black;
line-height: 17.5px;
text-align: center;
background-color: pink;
}
.two {
line-height: 35px;
}
#top {
display: none;
}
</style>
</head>
<body>
<div></div>
<div></div>
<div></div>
<ul>
<li>品质好货</li>
<li>好店直播</li>
<li>实惠热卖</li>
<li>猜你喜欢</li>
<li class="two">反馈</li>
<li id="top">返回顶部</li>
<li>暴恐举报</li>
</ul>
<script>
window.onload = function() {
var ul = document.querySelector("ul");
var a = document.querySelector(".two");
var li = document.querySelector("#top");
document.addEventListener("scroll", function() {
var top = document.documentElement.scrollTop;
if (top > 500) {
ul.style.position = "fixed";
ul.style.top = "-6px";
li.style.display = "block";
} else {
li.style.display = "none";
}
li.addEventListener("click", function() {
document.documentElement.scrollTop = 0;
})
})
}
</script>
</body>
</html>
4. window.pageXoffset和window.pageYoffset
- window.pageXoffset:表示X轴滚动条向右滚动过的像素数(表示文档向右滚动过的像素数)。IE9之前不兼容该属性,可使用body元素的scrollLeft代替。
- window.pageYoffset:表示Y轴滚动条向下滚动过的像素数(表示文档向下滚动过的像素数)。IE9之前不兼容该属性,可使用body元素的scrollTop代替。
- 返回值为整数类型,并且是只读属性,不带单位
- window.pageXoffset、window.pageYoffset属性 == scrollLeft、scrollTop属性。
5 . scroll兼容性解决方案
由于页面被卷去的属性存在兼容性问题,并且window.pageYoffset属性在IE9之后才出现,所有整个技术在各大浏览器上都存在争议和兼容性问题。
所以为了解决这个问题,我们可以创建一个对象来通过短路来获取属性值。
function Scroll() {
this.left = (window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft || 0);
this.top = (window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop || 0);
}
6、三系列应用场景
- offset系列经常用于获取元素的位置
- client系列经常用于获取元素的大小
览器上都存在争议和兼容性问题。
所以为了解决这个问题,我们可以创建一个对象来通过短路来获取属性值。
function Scroll() {
this.left = (window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft || 0);
this.top = (window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop || 0);
}
6、三系列应用场景
- offset系列经常用于获取元素的位置
- client系列经常用于获取元素的大小
- scroll系列经常用于获取文档的滚动距离