1. 元素偏移量 offset 系列
1.1 offset 概述
offset 翻译过来就是偏移量, 我们使用 offset 系列相关属性可以动态的得到该元素的位置(偏移)、大小等。
- 获得元素距离带有定位父元素的位置
- 获得元素自身的大小(宽度高度)
- 注意: 返回的数值都不带单位
offset 系列常用属性:
1.2 offset 与 style 区别
offset
1.offset 可以得到任意样式表中的样式值
2.offset 系列获得的数值是没有单位的
3.offsetWidth 包含padding+border+width
4. offsetWidth 等属性是只读属性,只能获取不能赋值
5. 所以,我们想要获取元素大小位置,用offset更合适
style
1.style 只能得到行内样式表中的样式值 2.style.width 获得的是带有单位的字符串 3.style.width 获得不包含padding和border 的值 4.style.width 是可读写属性,可以获取也可以赋值 5.所以,我们想要给元素更改值,则需要用style改变
offset 翻译过来就是偏移量, 我们使用 offset 系列相关属性可以动态的得到该元素的位置(偏移)、大小等。
- 获得元素距离带有定位父元素的位置
- 获得元素自身的大小(宽度高度)
<style>
* {
margin: 0;
padding: 0;
}
.father {
width: 200px;
height: 200px;
background-color: brown;
margin: 100px;
overflow: hidden;
position: relative;
/*参照物*/
}
.son {
width: 100px;
height: 100px;
background-color: black;
margin: 50px;
}
</style>
<div class="father">
<div class="son"></div>
</div>
<script>
var father = document.querySelector('.father');
var son = document.querySelector('.son');//可以得到该元素的位置(偏移) 注意不带单位
console.log(father.offsetTop);//100
console.log(father.offsetLeft);//100 //它以带有定位的父亲为准 如果有父亲或者父亲没有定位,则以body为准
console.log(son.offsetTop);//50
console.log(son.offsetLeft);//50 //可以得到元素的大小 padding+border+width
console.log(son.offsetWidth);//124
console.log(son.offsetHeight); //返回带有定位的父亲 否则返回的是body
console.log(son.offsetParent);
console.log(father.offsetParent);
console.log(father.parentNode);//返回父亲,是最近一级的父亲 亲爸爸 不管父要有没有定位
</script>
案例:获取鼠标在盒子内的坐标
案例分析 ① 我们在盒子内点击,想要得到鼠标距离盒子左右的距离。 ② 首先得到鼠标在页面中的坐标(e.pageX, e.pageY) ③ 其次得到盒子在页面中的距离 ( box.offsetLeft, box.offsetTop) ④ 用鼠标距离页面的坐标减去盒子在页面中的距离,得到 鼠标在盒子内的坐标 ⑤ 如果想要移动一下鼠标,就要获取最新的坐标,使用鼠标移动事件 mousemove
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 200px;
height: 200px;
background-color: brown;
margin: 100px;
color: #fff;
}
</style>
<div class="box"></div>
<script>
var box = document.querySelector('.box');
box.addEventListener('mousemove', function (e) {
// console.log(e.pageX);
// console.log(e.pageY);
// console.log(box.offsetLeft);
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
this.innerHTML = 'x坐标是' + x + 'y坐标是' + y
})
</script>
案例:模态框拖拽
弹出框,我们也称为模态框。 1. 点击弹出层, 会弹出模态框, 并且显示灰色半透明的遮挡层。 2. 点击关闭按钮,可以关闭模态框,并且同时关闭灰色半透明遮挡层。 3. 鼠标放到模态框最上面一行,可以按住鼠标拖拽模态框在页面中移动。 4. 鼠标松开,可以停止拖动模态框移动。
案例分析 ① 点击弹出层, 模态框和遮挡层就会显示出来 display:block; ② 点击关闭按钮,模态框和遮挡层就会隐藏起来 display:none; ③ 在页面中拖拽的原理: 鼠标按下并且移动, 之后松开鼠标 ④ 触发事件是鼠标按下 mousedown, 鼠标移动mousemove 鼠标松开 mouseup ⑤ 拖拽过程: 鼠标移动过程中,获得最新的值赋值给模态框的left和top值, 这样模态框可以跟着鼠标走了 ⑥ 鼠标按下触发的事件源是 最上面一行,就是 id 为 title ⑦ 鼠标的坐标 减去 鼠标在盒子内的坐标, 才是模态框真正的位置。 ⑧ 鼠标按下,我们要得到鼠标在盒子的坐标。 ⑨ 鼠标移动,就让模态框的坐标 设置为 : 鼠标坐标 减去盒子坐标即可,注意移动事件写到按下事件里面。 ⑩ 鼠标松开,就停止拖拽,就是可以让鼠标移动事件解除
<style>
* {
margin: 0;
padding: 0;
}
.login {
width: 600px;
height: 400px;
background-color: #fff;
box-shadow: 0 0 3px #999;
border-radius: 10px;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: none;
}
.title {
width: 600px;
height: 40px;
background-color: #333;
text-align: center;
line-height: 40px;
color: #fff;
}
.close {
position: absolute;
right: 5px;
top: 5px;
font-size: 30px;
cursor: pointer;
color: #fff;
/* display: none; */
}
.mask {
background-color: rgba(0, 0, 0, 0.6);
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
display: none;
}
#link {
position: absolute;
left: 50%;
transform: translate(-50%, 0);
color: black;
z-index: 10;
}
</style>
<div class="mask"></div>
<a href="javascript:;" id="link">点击弹出登录框</a>
<div class="login">
<div class="title">登录</div>
<div class="close">×</div>
</div>
<script>
//1、获取元素
var login = document.querySelector('.login');
var mask = document.querySelector('.mask');
var close = document.querySelector('.close');
var link = document.querySelector('#link');
var title = document.querySelector('.title');
//2、点击弹出层这个链接link 让mask 和login显示出来
link.addEventListener('click', function () {
mask.style.display = 'block';
login.style.display = 'block';
});
//3、点击close 让mask 和login隐藏
close.addEventListener('click', function () {
mask.style.display = 'none';
login.style.display = 'none';
}); //4、开始拖拽
//(1)当我们鼠标按下,就获得鼠标在盒子内的坐标
title.addEventListener('mousedown', function (e) {
var x = e.pageX - login.offsetLeft;
var y = e.pageY - login.offsetTop;
console.log(x, y);
// (2)鼠标移动的时候,把鼠标在页面中的坐标,减去鼠标在盒子内的坐标就是模态框的left和top
document.addEventListener('mousemove', move)
function move(e) {
login.style.left = e.pageX - x + 'px';
login.style.top = e.pageY - y + 'px';
}
// (3)鼠标弹起的时候,就让鼠标移动事件移除
document.addEventListener('mouseup', function () {
document.removeEventListener('mousemove', move)
})
})
</script>
案例:仿京东放大镜
案例分析 ① 整个案例可以分为三个功能模块 ② 鼠标经过小图片盒子, 黄色的遮挡层 和 大图片盒子显示,离开隐藏2个盒子功能 ③ 黄色的遮挡层跟随鼠标功能。 ④ 移动黄色遮挡层,大图片跟随移动功能。
① 鼠标经过小图片盒子, 黄色的遮挡层 和 大图片盒子显示,离开隐藏2个盒子功能 ② 就是显示与隐藏
① 黄色的遮挡层跟随鼠标功能。 ② 把鼠标坐标给遮挡层不合适。因为遮挡层坐标以父盒子为准。 ③ 首先是获得鼠标在盒子的坐标。 ④ 之后把数值给遮挡层做为left 和top值。 ⑤ 此时用到鼠标移动事件,但是还是在小图片盒子内移动。 ⑥ 发现,遮挡层位置不对,需要再减去盒子自身高度和宽度的一半。 ⑦ 遮挡层不能超出小图片盒子范围。 ⑧ 如果小于零,就把坐标设置为0 ⑨ 如果大于遮挡层最大的移动距离,就把坐标设置为最大的移动距离 ⑩ 遮挡层的最大移动距离: 小图片盒子宽度 减去 遮挡层盒子宽度
移动黄色遮挡层,大图片跟随移动功能。
<div class="preview_wrap">
<div class="preview_img"> <img src="./images/1.jpg" alt="">
<div class="mask"></div>
<div class="big"> <img src="./images/big1.jpg" alt