offset client scroll 三大系列
文章目录
元素偏移量offset系列
offset概述
offset翻译过来就是偏移量,我们使用offset系列相关属性可以动态得到元素的位置(偏移)、大小等
- 获取元素距离带有定位父元素的位置
- 获取元素自身的大小(宽度和高度)
- 注意:返回的数值都不带单位
offset系列常用属性:
offset系列属性 | 作用 |
---|---|
element.offsetParent | 返回作为该元素带有定位的父元素,如果父级都没有定位则返回body |
element.offsetTop | 返回元素相对带有定位父元素上面的偏移 |
element.offsetLeft | 返回元素相对带有父元素左边框的偏移 |
element.offsetWidth | 返回自身包括padding、边框、内容区的宽度,返回数值不带单位 |
element.offsetHeight | 返回自身包括padding、边框、内容区的高度,返回数值不带单位 |
offset与style区别
offset可以获取任意样式表中的样式值,style只能得到行内样式表的样式值
offset系列获得的数值是没有单位的,style.width获得到的是带有单位的字符串
offsetWidth包含padding+border+width,style.width获得不包含padding和boder值
offWidth等属性是只读属性,只能获取不能赋值,style.width是可读写属性,可以获取也可以赋值
所以获取元素大小位置,使用offset;更改值,则使用style
【案例】获取鼠标子在盒子内的坐标
【案例分析】
- 我们在盒子内想要得到鼠标距离盒子左右的距离
- 首先得到鼠标在页面的坐标,e.pageX,e.pageY
- 其次得到盒子在页面中的距离,box.offsetLeft,box.offsetTop
- 鼠标的坐标减去盒子在页面中的距离
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>获取鼠标在盒子内的坐标</title>
<style type="text/css">
.box{
width: 200px;
height: 200px;
margin: 50px;
background-color: pink;
}
</style>
</head>
<body>
<div class="box"></div>
<script type="text/javascript">
var box = document.querySelector('.box');
box.addEventListener('mousemove', function(e){
let mouseLeft = e.pageX;
let mouseTop = e.pageY;
let boxLeft = this.offsetLeft;
let boxTop = this.offsetTop;
let x = mouseLeft - boxLeft;
let y = mouseTop - boxTop;
console.log(x + ',' + y);
});
</script>
</body>
</html>
【案例】模态框拖拽
弹出框,我们也称为模态框
- 点击弹出层,会弹出模态框,并且显示灰色半透明的遮挡层
- 点击关闭按钮,可以关闭模态框,并且同时关闭灰色半透明的遮挡层
- 鼠标放到模态框在上面一行,可以按住鼠标拖拽模态框在页面中移动
- 鼠标放松,可以停止拖动模态框
页面拖拽的事件是:鼠标按下mousedown,鼠标移动mousemove,鼠标松开mouseup
拖拽过程:鼠标移动过程中,鼠标获得最新的left、right值并赋值给模态框
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>模态框</title>
<style type="text/css">
.login-header {
width: 200px;
height: 200px;
margin: 0px auto;
}
#link{
text-decoration: none;
color: black;
font-size: 50px;
}
.loging-box {
background-color: #DCD7D7;
width: 500px;
height: 200px;
margin: 10px auto;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
padding: 8px;
border-radius: 5%;
display: none;
}
p {
font-size: 20px;
}
#title {
float: left;
}
#close {
float: right;
}
#close a{
text-decoration: none;
color: black;
}
.header {
height: 20px;
cursor: pointer;
}
#input-box {
margin-top: 47px;
margin-left: 107px;
}
.login-input{
margin-bottom: 10px;
font-size: 20px;
}
.login-input input {
width: 180px;
height: 25px;
}
.loging-box button{
width: 150px;
height: 30px;
display: block;
margin: 20px auto;
}
</style>
</head>
<body>
<div class="login-header"> <a id="link" href="javascript:;">点击登录</a> </div>
<!-- 登录页面框 -->
<div class="loging-box">
<p id="title">用户登录界面</p> <p id="close"><a href="javascript:;">关闭</a></p>
<div class="header"></div>
<div id="input-box">
<div class="login-input">
<label>用户名:</label>
<input type="text" placeholder="请输入用户名">
</div>
<div class="login-input">
<label>密    码: </label>
<input type="password" placeholder="请输入密码">
</div>
</div>
<button>登录</button>
</div>
<script type="text/javascript">
var link = document.querySelector('#link');
var logingBox = document.querySelector('.loging-box');
var close = document.querySelector('#close');
// 弹出登录界面
link.addEventListener('click', function(){
logingBox.style.display = 'block';
link.style.display = 'none';
document.body.style.backgroundColor = '#9C9C9C';
})
// 关闭登陆界面的效果
close.addEventListener('click', function(){
logingBox.style.display = 'none';
link.style.display = 'block';
document.body.style.backgroundColor = '#FFFFFF';
})
// 拖拽效果,只在.header下拖动才有效
// 1.鼠标按下
var header = document.querySelector('.header');
header.addEventListener('mousedown',function(e){
// 得到鼠标在登录框中的坐标
var x = e.pageX - logingBox.offsetLeft;
var y = e.pageY - logingBox.offsetTop;
function move (e) {
// 登录框的坐标是按照框的左上角决定的,所以要减去框内坐标
logingBox.style.left = e.pageX - x + 'px';
logingBox.style.top = e.pageY - y + 'px';
}
// 2.实现鼠标拖动效果
document.addEventListener('mousemove', move);
// 3.当鼠标放开后,清除事件
document.addEventListener('mouseup', function(){
document.removeEventListener('mousemove', move);
})
})
</script>
</body>
</html>
【案例】仿京东放大镜
【案例分析】
- 案例可以分为三个功能模块
- 鼠标经过小图片盒子,黄色的遮挡层和大图片盒子显示,离开小图片盒子,黄色的遮挡层和大图片盒子隐藏
- 黄色的遮挡层跟随鼠标的功能
- 把鼠标坐标给遮挡层并不合适,因为遮挡层坐标以符盒子为准
- 首先要获得鼠标在盒子的坐标
- 之后把数值给遮挡层作为left和top
- 此时用到鼠标移动事件,但是还是在小图盒子内移动
- 移动黄色遮挡层,大图片跟随移动功能
<!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;
}
.box {
position: relative;
width: 400px;
height: 400px;
margin: 50px 0 0 100px;
border: 1px solid #000000;
cursor: move;
}
.box img {
width: 100%;
height: 100%;
}
.mask {
display: none;
position: absolute;
width: 300px;
height: 300px;
top: 0px;
left: 0px;
border: 1px solid #ccc;
background: yellow;
opacity: .5;
}
.big {
display: block;
position: absolute;
width: 600px;
height: 600px;
top: -1px;
left: 411px;
border: 1px solid #000000;
overflow: hidden;
}
.big img {
position: absolute;
width: 800px;
height: 800px;
left: 0px;
top: 0px;
}
</style>
</head>
<body>
<div class="box">
<img src="https://img12.360buyimg.com/n1/s450x450_jfs/t1/59022/28/10293/141808/5d78088fEf6e7862d/68836f52ffaaad96.jpg" alt="原图">
<div class="mask"></div>
<div class="big">
<img src="https://img12.360buyimg.com/n1/s450x450_jfs/t1/59022/28/10293/141808/5d78088fEf6e7862d/68836f52ffaaad96.jpg" alt="放大图" class="bigImg">
</div>
</div>
<script type="text/javascript">
window.addEventListener('load', function() {
var box = document.querySelector('.box');
var mask = document.querySelector('.mask');
var big = document.querySelector('.big');
// 鼠标进入事件
box.addEventListener('mouseover', function(e) {
mask.style.display = 'block';
big.style.display = 'block';
});
// 鼠标移出事件
box.addEventListener('mouseout', function() {
mask.style.display = 'none';
big.style.display = 'none';
});
// 鼠标移动事件
box.addEventListener('mousemove', function(e) {
// 确认mask 的位置
var x = e.pageX - this.offsetLeft - mask.offsetWidth / 2;
var y = e.pageY - this.offsetTop - mask.offsetHeight / 2;
// 最大偏移值,即大盒子-放大镜层
var maskMax = box.offsetWidth - mask.offsetWidth;
// 超出偏移量,强制修改
if (x <= 0) x = 0;
if (x >= maskMax) x = maskMax;
if (y <= 0) y = 0;
if (y >= maskMax) y = maskMax;
// 修改放大镜层的位置
mask.style.left = x + 'px';
mask.style.top = y + 'px';
// 计算大图的最大距离
var bigImg = document.querySelector('.bigImg');
var bigMax = bigImg.offsetWidth - big.offsetWidth;
// 两最大距离的商,即放大的倍数
var boom = bigMax / maskMax;
var bigX = x * boom;
var bigY = y * boom;
// 修改大图在盒子中的定位
bigImg.style.left = -bigX + 'px';
bigImg.style.top = -bigY + 'px';
});
});
</script>
</body>
</html>
元素可视区client系列
client翻译过来就是客户端,我们使用client系列的相关属性来获得元素可视区的相关的信息。通过client系列的相关的属性可以动态的得到该元素的边框大小、元素的大小等
client系类属性 | 作用 |
---|---|
element.clientTop | 返回元素上边框的大小 |
element.clientLeft | 返回元素左边框的大小 |
element.clientWidth | 返回自身包括padding、内容框的宽度、不含边框,返回数值不带单位 |
element.clientHeight | 返回自身包括padding、内容框的高度、不含边框,返回数值不带单位 |
立即执行函数
不用调用,立马能够自己执行的函数
如果有多个立即执行函数,那么就需要用;
隔开
立即执行函数的作用:独立创建一个作用域,里面所有的变量都是局部变量,不会有命名冲突的
写法:
(function(){})()
或者
(function(){}())
在第一个小括号内为形参,第二个小括号为实参
(function(a,b){
console.log(a + b);
})(1,2)
元素滚动scroll系列
scroll翻译过来就是滚动的,我们使用scroll系列的相关属性可以动态地获得元素地大小、滚动距离等
scroll系列属性 | 作用 |
---|---|
element.scrollTop | 返回被卷去的上侧距离,返回数值不带单位 |
element.scrollLeft | 返回被卷去的左侧距离,返回数值不带单位 |
element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |
element.scrollHeight | 返回自身实际的高度,不含边框,返回数值不带单位 |
当元素超出盒子的时候打印得到的所有元素的高度和宽度,我们可以给自己加滚动条
overflow:auto;
scroll滚动事件当我们滚动条发生变化的时候会触动
div.addEventListener('scroll', function(){
})
【案例】仿淘宝固定侧边栏
【案例分析】
实现效果:
- 原先侧边栏是绝对定位
- 当页面滚动到一定位置,侧边栏改为固定定位
- 页面继续滚动,会让“返回顶部”显示出来
代码需求:
- 需要用到页面滚动事件scroll因为是页面滚动,所以事件源是document
- 滚动到某个位置,判断页面被卷去的上版部分值
- 页面被卷去的头部:可以通过window.pageYOffset获得
- 注意,元素被卷去的头部是element.scrollTop,如果是页面被卷去的头部则是window.pageYOffset
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>仿淘宝固定侧边栏</title>
<style type="text/css">
* {
margin: 0px;
padding: 0px;
}
div {
width: 500px;
margin: 10px auto;
text-align: center;
}
.header {
height:200px;
background-color: pink;
}
.banner {
height: 100px;
background-color: yellow;
}
.body {
height: 900px;
background-color: blue;
position: relative;
}
.end {
height: 200px;
background-color: red;
}
#slider {
background-color: #897F7F;
width: 100px;
margin: 0px;
position: absolute;
left: 520px;
top: 0px;
}
#slider li {
list-style-type:none;
}
</style>
</head>
<body>
<div class="header">
header
</div>
<div class="banner">
banner
</div>
<div class="body">
body
<div id="slider">
<ul>
<li>品质好货</li>
<li>猜你喜欢</li>
<li id="hide" style="display: none"><a href="#">顶部^</a></li>
<li>反馈</li>
</ul>
</div>
</div>
<div class="end">
end
</div>
<script type="text/javascript">
var divs = document.querySelectorAll('div');
var slider = document.querySelector('#slider');
var body = document.querySelector('.body');
var hideli = document.querySelector('#hide');
//使文字在各个元素中居中
for(i=0;i<divs.length;i++){
//此处注意,不要使用divs[i].style.height
divs[i].style.lineHeight = divs[i].clientHeight + 'px';
}
slider.style.lineHeight = '50px';
var releft = slider.style.left;
document.addEventListener('scroll',function(){
var y = window.pageYOffset;
if(y > body.offsetTop){
slider.style.position = 'fixed';
slider.style.left = (body.offsetLeft + body.offsetWidth + 20) + 'px';
hideli.style.display = 'block';
}else if (y >= 0) {
slider.style.position = 'absolute';
slider.style.left = releft;
hideli.style.display = 'none';
}
})
</script>
</body>
</html>
offset和client和scroll的主要用法
- offset:经常用来获得元素的位置
- client:获取元素的大小
- scroll:经常用于获取滚动条距离
- 页面的滚动距离通过window.pageXoffset来获取