元素偏移量offset
使用offset系列相关属性可以动态得到该元素的位置(偏移)、大小等
可以获取元素距离带有定位的父元素的位置,也可以获取元素自身的大小(宽度、高度),注意,返回的数值不带单位
如果父元素没有定位或者没有父元素,则以body为准
常用于获取元素位置
offset与style的区别
所以,获取元素大小时,使用offset更合适,想要改变元素大小时,使用style更合适
实例:一个可以用鼠标拖动的模拟框
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div{
width: 100px;
height: 100px;
background-color:#DB7093;
position: absolute;
}
</style>
</head>
<body>
<div></div>
<script>
var d=document.querySelector('div');
var x,x1;
var y,y1;
function move(e){
// x,y是鼠标位置
x=e.clientX;
y=e.clientY;
d.style.top=y-y1+'px';
d.style.left=x-x1+'px';
}
d.onmousedown=function(en){
// 计算原来鼠标距离盒子边缘的距离
x1=en.clientX-d.offsetLeft;
y1=en.clientY-d.offsetTop;
document.addEventListener('mousemove',move)
document.onmouseup=function(){
document.removeEventListener('mousemove',move)
}
}
</script>
</body>
</html>
元素可视区client系列
使用client系列相关属性来获取元素可视区的相关信息,可以动态获取元素的边框大小、元素大小等
常用于获取元素大小
立即执行函数
立即执行函数是不需要调用,立马能自己执行的函数
写法:(function(){})() 或(function(){}()),第二个小括号可以看做是调用函数,里面可以写参数
创建了一个独立作用域,避免了命名冲突
元素滚动scroll系列
scroll系列相关属性可以动态获得元素的大小、滚动距离等
注意,元素被卷去使用scrollTop,但页面被卷去使用window.pageYOffset(IE9)
scroll系列 常用于获取滚动距离
mouseenter与mouseover的区别
鼠标移到元素上时会触发mouseenter事件和mouseover事件,两个的区别是当鼠标经过父盒子之后再经过子盒子时,会触发mouseover,不会触发mouseenter事件
动画函数封装
核心原理:通过setInterval()函数不断移动盒子位置
过程:获取盒子当前位置,让盒子在当前位置上加一个一段距离,利用定时器不断重复该操作,增加定时器结束条件
缓动效果
缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来
缓动动画公式:每次移动的步长=(目标值-现在的位置)/10,注意,需要将步长向上取整。
回调函数
原理:函数可以作为一个参数,将这个函数作为参数传递到另一个函数里面,当那个函数执行之后再执行传进去的这个函数,这就是回调
回调函数可以写在定时器结束里面
实例:轮播图
window.addEventListener('load',function(){
var ll=document.querySelector('.ll');
var lr=document.querySelector('.lr');
var lunbo=document.querySelector('.lunbo');
var yb=document.querySelector('.yb');
var ybli=yb.children;
var lb=document.querySelector('.lb');
var timer=setInterval(function(){
// 手动调用
lr.click();
},3000)
lunbo.addEventListener('mouseenter',function(){
ll.style.display='block';
lr.style.display='block';
clearInterval(timer);
})
lunbo.addEventListener('mouseleave',function(){
ll.style.display='none';
lr.style.display='none';
timer=setInterval(function(){
// 手动调用
lr.click();
},4000)
})
for(var i=0;i<ybli.length;i++){
ybli[i].onmouseenter=function(){
for(var j=0;j<ybli.length;j++){
ybli[j].className='';
}
this.className='current';
var n=this.id;
var target=-(n*1+1)*400;
move(lb,target)
}
}
lr.addEventListener('click',function(){
var n=(-lb.offsetLeft)/400;
n=n+1;
if(n<5){
var target=-n*400
move(lb,target)
}else{
lb.style.left='0px';
n=(-lb.offsetLeft)/400;
n=n+1
var target=-n*400
move(lb,target)
}
for(var j=0;j<ybli.length;j++){
ybli[j].className='';
}
ybli[n-1].className='current';
});
ll.addEventListener('click',function(){
var n=(-lb.offsetLeft)/400;
n=n-1;
if(n>=0){
var target=-n*400
move(lb,target)
}else{
lb.style.left='-1600px';
n=(-lb.offsetLeft)/400;
n=n-1
var target=-n*400
move(lb,target)
}
for(var j=0;j<ybli.length;j++){
ybli[j].className='';
}
if(n-1==-1){
n=4;
}
ybli[n-1].className='current';
});
// 移动函数
function move(obj,target,func){
if(obj.offsetLeft == target){
if(func){
func();
}
return 0;
}
if(obj.offsetLeft < target){
var d=1;
}else{
var d=0;
}
clearInterval(obj.time);
obj.time=setInterval(function(){
if(d==0){
if(obj.offsetLeft <= target){
clearInterval(obj.time);
if(func){
func();
}
return 0;
}
obj.style.left=obj.offsetLeft-10+'px';
}else{
if(obj.offsetLeft >= target){
clearInterval(obj.time);
if(func){
func();
}
return 0;
}
obj.style.left=obj.offsetLeft+10+'px';
}
},1)
}
})
节流阀
目的:当上一个函数动画执行完毕之后再执行下一个函数动画,让事件无法连续触发
方法:利用回调函数,设置一个变量。来锁住和执行函数