元素偏移量offset系列
-
offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。
1.可以获得元素距离带有定位父元素等位置。
2.可以获得元素自身的大小(宽度和高度)。
注意:返回的数值都不带单位。
- offset系列常用属性:
offset系列属性 | 说明 |
---|---|
element.offsetParent | 返回作为该元素带有定位的父级元素 如果父级都没有定位则返回body |
element.offsetTop | 返回元素相对带有定位父元素上方的偏移 如果没有父级元素或者父级元素没有定位,则以body为准 |
element.offsetLeft | 返回元素相对带有定位父元素左边框的偏移 如果没有父级元素或者父级元素没有定位,则以body为准 |
element.offsetWidth | 返回自身包括padding、边框、内容区的宽度,返回数值不带单位 |
element.offsetHeight | 返回自身包括padding、边框、内容区的高度,返回数值不带单位 |
注意:
offsetParent和parentNode的区别:
1.offsetParent只返回带有定位的父级元素,如果没有,则返回body。
2.parentNode返回的是最近一级的父级元素,不管父级元素也没有定位。
- offset和style的区别:
offset | style |
---|---|
offset可以得到任意样式表中的样式值 | style只能得到行内样式表中的样式值 |
offset系列获得的数值是没有单位的 | style获得的是带有单位的字符串 |
offsetWidth包含padding+border+width | style.width获得不包含padding和border的值 |
offsetWidth等属性是只读属性,只能获取不能赋值 | style.width等属性是可读属性,可以获取也可以赋值 |
获取元素大小位置,用offset更合适 | 更改元素的值,用style更合适 |
元素可视区client系列
- client系列的相关属性可以获取元素可视区的相关信息,简单来收,通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。
client系列属性 | 说明 |
---|---|
element.clientTop | 返回元素上边框的大小 |
element.clientLeft | 返回元素左边框的大小 |
element.clientWidth | 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位 |
element.clientHeight | 返回自身包括padding、内容区的高度,不含边框,返回数值不带单位 |
元素滚动scroll系列
- scroll系列的相关属性可以动态的得到该元素的大小、滚动距离等。
scroll系列 | 说明 |
---|---|
element.scrollTop | 返回被卷去的上侧距离,返回数值不带单位(包含上边框大小) |
element.scrollLeft | 返回被卷去的左侧距离,返回数值不带单位(包含左边框大小) |
element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |
element.scrollHeight | 返回自身实际的高度,不含边框,返回数值不带单位 |
-
scrollWidth和clientWidth最大的区别就是:如果盒子内容溢出或出现滚动条,则scrollWidth是指盒子内容的宽度;而clientWidth还是可视区的宽度。如果没有内容没有益处,则它们两个是相同的。(scrollHeoght和clientHeight同理)
-
拓展:
1.页面被卷去的头部,可以通过window.pageYOffset获得;而页面被卷去的左侧,则可以通过window.pageXOffset获得。注意:元素被卷去的头部,使用的是element.scrollTop。
2.页面被卷去的头部是有兼容性问题的,因此被卷去的头部通常有如下几种写法:
(1)声明了DTD(即< !DOCTYPE html >),使用document.documentElement.scrollTop
(2)未声明DTD(即< !DOCTYPE html >),使用document.body.scrollTop
(3)新方法window.pageYOffset和window.pageXOffset,IE0以后才支持
function getScroll(){ return { left: window.pageXOffset || document.docuemntElement.scrollLeft || document.body.scrollLeft || 0, top: window.pageYOffset || document.documntElement.scrollTop || document.body.scrollTop || 0 }; } //使用的时候,采取以下格式: getScroll().left
动画函数封装
1.动画实现原理
-
核心原理:通过定时器setInterval()不断移动盒子位置。
-
实现步骤如下:
1.获得盒子当前位置。
2.让盒子在当前位置加上1个移动距离。
3.利用定时器不断重复这个操作。
4.加一个结束定时器的条件。
5.注意此元素需要添加定位,才能使用element.style.left。
2.动画函数简单封装
- 动画函数封装需要传递2个参数,分别是动画对象和移动到的距离。
function animate(obj, target){
var timer = setInterval(function(){
if(obj.offsetLeft >= target){
clearInterval(timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
},25);
}
- 如果多个元素都使用这个动画函数,每次都要把var声明定时器,并且都会在内存中开辟空间,导致浪费内存。
- 如果多个元素都使用这个动画函数,而timer这个变量名都一样,可能会造成歧义。
//优化结果1:
function animate(obj, target){ //obj这个传过来的元素是一个对象
obj.timer = setInterval(function(){
if(obj.offsetLeft >= target){
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
},25);
}
- 如果给一个加了动画函数的元素绑定一个按钮,只有点击这个按钮,元素才会运动起来。当我们不断点击这个按钮,这个元素的速度会越来越快。(因为开启了太多的定时器)
//优化结果2:
function animate(obj, target){ //obj这个传过来的元素是一个对象
clearInterval(obj.timer);
obj.timer = setInterval(function(){
if(obj.offsetLeft >= target){
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
},25);
}
-
缓动效果原理:缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来。
步骤:
1.让盒子每次移动的距离慢慢变小,速度就会慢慢落下来。
2.核心算法:”(目标值 - 现在的位置) / 10 ”作为每次移动的距离步长。
3.停止的条件是:让当前盒子位置等于目标位置就停止定时器。
-
缓动动画基本代码实现:
function animate(obj, target){ //obj这个传过来的元素是一个对象
clearInterval(obj.timer);
obj.timer = setInterval(function(){
var step = Math.ceil((target - obj.offsetLeft) / 10);
//计算结果是正数,需要通过Math.ceil()方法,使移动距离向上取整,才能使元素移动的结果是整数,
//而不是小数。(比如,想让元素移动到500px,如果不加这个方法,那么最后会移动到496.4px就停下来了)
if(obj.offsetLeft == target){
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step + 'px';
},15);
}
//匀速动画就是盒子当前的位置+固定值(10)
//缓动动画就是盒子当前的位置+变化的值(目标值 - 现在的位置) / 10
- 缓动动画在多个目标住之间移动:
function animate(obj, target){ //obj这个传过来的元素是一个对象
clearInterval(obj.timer);
obj.timer = setInterval(function(){
//var step = Math.ceil((target - obj.offsetLeft) / 10);
//计算结果是正数,需要通过Math.ceil()方法,使移动距离向上取整,才能使元素移动的结果是整数,
//而不是小数。(比如,想让元素移动到500px,如果不加这个方法,那么最后会移动到496.4px就停下来了)
//计算结果是负数,则往下取整。
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if(obj.offsetLeft == target){
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step + 'px';
},15);
}
-
动画函数添加回调函数:
回调函数原理:函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调。
function animate(obj, target,callback){ //obj这个传过来的元素是一个对象
clearInterval(obj.timer);
obj.timer = setInterval(function(){
//var step = Math.ceil((target - obj.offsetLeft) / 10);
//计算结果是正数,需要通过Math.ceil()方法,使移动距离向上取整,才能使元素移动的结果是整数,
//而不是小数。(比如,想让元素移动到500px,如果不加这个方法,那么最后会移动到496.4px就停下来了)
//计算结果是负数,则往下取整。
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if(obj.offsetLeft == target){
clearInterval(obj.timer);
//回调函数写到定时器里面
if(callback){
//调用函数
callback();
}
//或者可以写成:callback && callback(); ——短路运算
}
obj.style.left = obj.offsetLeft + step + 'px';
},15);
}
-
动画函数的使用:一般都是把这个动画函数单独封装到一个JS文件中,使用的时候引用这个文件即可。
-
节流阀的目的:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发。
核心思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数。
开始设置一个变量var flag = true; if(flag){ flag = false; //关闭水龙头 do something } 利用回调函数,在动画执行完毕后,通过flag = true 打开水龙头
课外点
- mouseenter和mouseover的区别:mouseover鼠标经过自身盒子会触发,经过子盒子也会触发;而mouseenter只有经过自身盒子才会触发。(原因是:mouseenter和mouseleave不会冒泡)
微信公众号也会定期更新,觉得文章写得还可以的,可以加个关注!点个赞!谢谢!