1. 元素偏移量 offset 系列
1.1 offset 概述
offset
翻译过来就是偏移量, 我们使用 `offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。
获得元素距离带有定位父元素的位置;
获得元素自身的大小(宽度高度);
注意:返回的数值都不带单位。
1.2 offset 与 style 区别
offset
offset
可以得到任意样式表中的样式值;offset
系列获得的数值是没有单位的;offsetWidth
包含padding+border+width
;offsetWidth
等属性是只读属性,只能获取不能赋值;所以,我们想要获取元素大小位置,用
offset
更合适。
style
style
只能得到行内样式表中的样式值;style.width
获得的是带有单位的字符串;style.width
获得不包含padding
和border
的值;style.width
是可读写属性,可以获取也可以赋值;所以,我们想要给元素更改值,则需要用style改变;
因为平时我们都是给元素注册触摸事件,所以重点记住
targetTocuhes
。
1.3 案例:获取鼠标在盒子内的坐标
我们在盒子内点击,想要得到鼠标距离盒子左右的距离。
首先得到鼠标在页面中的坐标(
e.pageX
,e.pageY
)。其次得到盒子在页面中的距离 (
box.offsetLeft
,box.offsetTop
)。用鼠标距离页面的坐标减去盒子在页面中的距离,得到 鼠标在盒子内的坐标。
如果想要移动一下鼠标,就要获取最新的坐标,使用鼠标移动。
.box {
width: 300px;
height: 300px;
margin: 200px;
background-color: skyblue;
}
// 1. 首先获取到鼠标在页面中的坐标距离 body ,之后获取到盒子距离页面的距离 box 。 通过 body - box 可得到鼠标距离盒子的距离
let box = document.querySelector('.box');
box.addEventListener('mouseover', function (e) {
let pageX = e.pageX;
let pageY = e.pageY;
let offsetLeft = this.offsetLeft;
let offsetTop = this.offsetTop;
let x = (pageX - offsetLeft);
let y = (pageY - offsetTop);
this.innerHTML = 'x坐标 : ' + x + 'y坐标 : ' + y;
});
1.4 案例:模态框拖拽
- 【前端案例】15 - 案例:模态框拖拽 - 。
1.5 案例:图片放大器
3. 元素可视区 client 系列
2.1 client概述
-
client
翻译过来就是客户端,我们使用client
系列的相关属性来获取元素可视区的相关信息。通过client
系列的相关属性可以动态的得到该元素的边框大小、元素大小等。
2.2 淘宝 flexible.js 源码分析
立即执行函数
立即执行函数不需要调用立马能够执行。
普通函数:
function fn() {
console.log('我是函数');
}
fn();
- 立即执行函数:
// 2. 立即执行函数写法
(function (a, b, c) {
console.log(a + b + c);
// 在立即函数中定义的变量是局部变量,不会有冲突问题
})(1, 2, 3); // 第二个小括号可以看做是调用函数
// 如果有多个立即执行函数需要使用 分号分隔开
// 或者
(function () {
console.log('我是立即函数');
}())
- 立即执行函数的主要作用 : 创建一个独立的作用域。 避免了命名冲突问题。
下面三种情况都会刷新页面都会触发 load 事件。
a标签的超链接;
F5或者刷新按钮(强制刷新);
前进后退按钮。
但是 火狐中,有个特点,有个“往返缓存”,这个缓存中不仅保存着页面数据,还保存了 DOM
和JavaScript
的状态;实际上是将整个页面都保存在了内存里。所以此时后退按钮不能刷新页面。
使用 pageshow
事件解决上面的问题:,这个事件在页面显示时触发,无论页面是否来自缓存。在重新加载页面中,pageshow
会在 load
事件触发后触发;根据事件对象中的 persisted
来判断是否是缓存中的页面触发的 pageshow
事件。
注意这个事件给window添加。
3. 元素滚动 scroll 系列
3.1 scroll 概述
-
scroll
翻译过来就是滚动的,我们使用scroll
系列的相关属性可以动态的得到该元素的大小、滚动距离等。
3.2 页面被卷去的头部
- 如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。滚动条在滚动时会触发
onscroll
事件。
3.3 案例:仿淘宝固定右侧侧边栏
- 【前端案例】17 - 案例:仿淘宝固定右侧侧边栏 -
3.4 页面被卷去的头部兼容性解决方案
需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常有如下几种写法:
- 声明了
DTD
,使用document.documentElement.scrollTop
。DTD
指的是:文档定义类型即文档首部的。
- 未声明
DTD
,使用document.body.scrollTop
; - 新方法
window.pageYOffset
和window.pageXOffset
,IE9
开始支持。
function getScroll() {
return {
left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft||0,
top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
};
}
使用的时候 getScroll().left
4. 三大系列总结
他们主要用法:
-
offset
系列 经常用于获得元素位置offsetLeft offsetTop
;
2.client
经常用于获取元素大小 clientWidth clientHeight
;
scroll
经常用于获取滚动距离scrollTop scrollLeft
;注意页面滚动的距离通过
window.pageXOffset
获得。
5. mouseenter
和 mouseover
的区别
当鼠标移动到元素上时就会触发
mouseenter
事件;类似
mouseover
,它们两者之间的差别是;mouseover
鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter
只会经过自身盒子触发;之所以这样,就是因为
mouseenter
不会冒泡;跟
mouseenter
搭配鼠标离开mouseleave
同样不会冒泡。
.father {
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
background-color: skyblue;
}
.son {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 50px;
height: 50px;
background-color: deepskyblue;
}
let father = document.querySelector('.father');
/**
* 1. mouseenter : --> mouseleave
*
* 2. mouseover
*/
/*father.addEventListener('mouseover', function () {
console.log('mouseover');
});*/
father.addEventListener('mouseenter', function () {
console.log('mouseenter');
});
6. 动画函数封装
div {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background-color: skyblue;
}
span {
display: block;
position: absolute;
top: 150px;
left: 0;
width: 100px;
height: 100px;
background-color: deepskyblue;
}
let div = document.querySelector('div');
let span = document.querySelector('span');
let button = document.querySelector('button');
function animal(element, target, interval) {
/**
* element.timer 代替 let timer 可以节省 给不同的元素指定了不同的定时器 使用对象属性的方式存定时器
* @type {number}
*/
clearInterval(element.timer)
element.timer = setInterval(function () {
if (element.offsetLeft >= target) {
clearInterval(timer);
} else {
element.style.left = element.offsetLeft + 1 + 'px';
}
}, interval);
}
animal(div, 400, 20);
/**
* 当点击的次数越来越多的时候出现跑的很快的bug
*
* 解决方案就是让其只有一个定时器执行 ,先清以前的定时器只保留当前的一个定时器执行
*/
button.addEventListener('click', function () {
animal(span, 600, 5);
});
6.1 动画实现原理
核心原理:通过定时器
setInterval()
不断移动盒子位置。
实现步骤:
获得盒子当前位置;
让盒子在当前位置加上1个移动距离;
利用定时器不断重复这个操作;
加一个结束定时器的条件;
注意此元素需要添加定位,才能使用
element.style.left
。
6.2 动画函数给不同元素记录不同定时器
- 如果多个元素都使用这个动画函数,每次都要
let
声明定时器。我们可以给不同的元素使用不同的定时器(自己专门用自己的定时器)。
核心原理:利用
JS
是一门动态语言,可以很方便的给当前对象添加属性。