PC端网页特效

1 offset

(1) 概述

offset翻译过来就是偏移量,我们使用offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。
获得元素距离带有定位父元素的位置。
获得元素自身的大小(宽度高度)。
//注意:返回的数值都不带单位。

(2) offset常用属性

元素对象.offsetParent:返回作为该元素带有定位的父级元素如果父级都没有定位则返回body。
元素对象.offsetTop:返回元素相对带有定位父元素上方的偏移。
//它以带有定位的父亲为准,如果么有父亲或者父亲没有定位,则以body为准。
元素对象.offsetLeft:返回元素相对带有定位父元素左边框的偏移。
元素对象.offsetWidth:返回自身包括padding、边框、内容区的宽度,返回数值不带单位。
元素对象.offsetHeight:返回自身包括padding、边框、内容区的高度,返回数值不带单位。、

(3) offset与style的区别

offset可以得到任意样式表中的样式值;style只能得到行内样式表中的样式值。
offset系列获得的数值是没有单位的;style.width获得的是带有单位的字符串。
offsetWidth包含padding+border+width;style.width获得不包含padding和border的值。
offsetWidth等属性是只读属性,只能获取不能赋值;style.width是可读写属性,可以获取也可以赋值。
所以,我们想要给元素更改值,则需要用style改变;我们想要获取元素大小位置,用offset更合适。
 

(4) 鼠标拖动元素案例

<1> 核心思路

<1.1> 在页面中拖拽的原理:鼠标按下并且移动,之后松开鼠标。
<1.2> 触发事件是鼠标按下mousedown,鼠标移动mousemove,鼠标松开mouseup
<1.3> 拖拽过程:鼠标移动过程中,获得最新的值赋值给盒子的lef和top值,这样盒子可以跟着鼠标走了。
<1.4> 鼠标的坐标减去鼠标在盒子内的坐标,才是盒子真正的位置。
<1.5> 鼠标按下,我们要得到鼠标在盒子的坐标。
<1.6> 鼠标移动,就让盒子的坐标设置为:鼠标坐标减去鼠标在盒子内坐标即可,注意移动事件写到按下事件里面。
<1.7> 鼠标松开,就停止拖,就是可以让鼠标移动事件解除。

<2> 代码实现

//当我们鼠标按下,就获得鼠标在盒子内的坐标。
div.addEventListener('mousedown',function(e){
	var x = e.pageX - div.offsetLeft;
	var y = e.pageY - div.offsetTop;
	//鼠标移动的时候,把鼠标在页面中的坐标减去鼠标在盒子内的坐标就时盒子的left值和top值。
	document.addEventListener('mousemove',move);
	function move(e){
		div.style.left = e.pageX - x + 'px';
		div.style.top = e.pageY - y + 'px';
	}
	//鼠标弹起,就让鼠标移动事件移除。
	document.addEventListener( 'mouseup',function(){
		document.removeEventListener('mousemove',move);
	});
});

 

2 client

(1) 概述

client翻译过来就是客户端,我们使用client系列的相关属性来获取元素可视区的相关信息。
通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。

(2) client常用属性

元素对象.clientTop:返回元素上边框的大小。
元素对象.clientLeft:返回元素左边框的大小。
元素对象.clientWidth:返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位。
元素对象.clientHeight:返回自身包括padding、内容区的高度,不含边框,返回数值不带单位。

(3) client与offset的区别

offsetWidth包含padding+border+width;clientWidth获得不包含border的值。

 

3 立即执行函数

(1) 概述

不需要调用,可以立即执行的函数。

(2) 语法格式

(function(形参,形参){})(实参,实参); 或者 (function(形参,形参){}(实参,实参));
//也可写函数名:(function 函数名(形参,形参){})(实参,实参); 或者 (function 函数名(形参,形参){}(实参,实参));
例1:
(function sum(a,b){
  console.log(a+b);
})(1,2);
例2:
(function sum(a,b){
  console.log(a+b);
}(1,2));

(3) 作用

立即执行函数最大的作用就是独立创建了一个作用域,里面所有的变量都是局部变量,不会有命名冲突的情况。

(4) 元素对象.click();

该语句被执行后,相当于自动点击该元素对象一次。
 

4 scroll

(1) 概述

scroll翻译过来就是滚动的,我们使用scroll系列的相关属性可以动态的得到该元素的大小、滚动距离等

(2) scroll常用属性

元素对象.scrollTop:返回被卷去的上侧距离,返回数值不带单位。
//当内容超出盒子高度,同时overflow设置为auto,当滚动条向下滑动时,scrollTop的值便是上面遮挡的内容部分。
元素对象.scrollleft:返回被卷去的左侧距离,返回数值不带单位。
元素对象.scrollWidth:返回自身实际的宽度,不含边框,返回数值不带单位。
元素对象.scrollHeight:返回自身实际的高度,包含内容的高度,不含边框,返回数值不带单位。

(3) 页面被卷去的头部

*<1> 页面被卷去的头部可以通过 window.pageYOffset获得;如果是被卷去的左侧 window.pagexoffset
//注意,元素被卷去的头部是element.scrollTop,如果是页面被卷去的头部则是window.pageYOffset
<2> 如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。滚动条在滚动时会触发onscroll事件。
div.addEventListener("scroll",function(){
  console.log(div.scrollTop);
})

(4) 页面被卷去的头部兼容性解决方案

<1> 需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常有如下几种写法:
声明了DTD,即<!DOCTYPE html>,使用 document.documentElement.scrollTop
未声明DTD,即<!DOCTYPE html>,使用 document.body.scrollTop
新方法 window.pageYOffset window.pageXOffset,IE9开始支持。
<2> 兼容性解决办法
function getScroll(){
	return{
		left:window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0,
		top:window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0,
	};
}
使用: getScroll().leftgetScroll().top

(5) scroll与client的区别

scrollwidthscrollHeight返回的宽度和高度包含内容的宽度和高度。

(6) 滚动窗口至文档中的特定位置

window.scroll(x,y);
//注意,里面的x和y不跟单位,直接写数字。
 

5 三大系列总结

offset可返回元素大小和元素在父元素(有定位)中的位置,常用于获得元素位置offsetLeftoffsetTop
client可返回元素边框的大小和元素大小,常用于获取元素大小clientwidthclientHeight
scroll可返回元素大小和被卷去部分的大小,常用于获取滚动距离scrollTopscrollLeft。注意页面滚动的距离通过 window.pageXOffset

 

6 mouseenter和mouseover的区别

当鼠标移动到元素上时就会触发mouseenter事件
类似mouseover,它们两者之间的差别是:mouseover鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter只会经过自身盒子触发。
之所以这样,就是因为mouseenter不会冒泡。
跟mouseenter搭配鼠标离开mouseleave同样不会冒泡。

 

7 动画函数封装

(1) 动画实现原理

<1> 核心原理

通过定时器setlntervalo不断移动盒子位置

<2> 实现步骤

<2.1> 获得盒子当前位置。
<2.2> 让盒子在当前位置加上1个移动距离。
<2.3> 利用定时器不断重复这个操作。
<2.4> 加一个结束定时器的条件。
<2.5> 注意此元素需要添加定位,才能使用 element.style.left
var div = document.querySelector('div');
var timer = setInterval(function(){
	if(div.offsetLeft >= 400){
	//若div与父盒子左侧相距400。
		clearInterval(timer);
		//则div不再移动,即停止计时器。
	}
	div.style.left=div.offsetLeft+1+"px";
	//不断为div左偏移赋值,使div与父元素左侧相距距离不断加1。
},30);

(2) 动画函数简单封装

注意函数需要传递2个参数,动画对象和移动到的距离。
function animate(obj,target){
	//当我们不断的为同一个对象添加动画,这个元素的速度会越来越快,因为开启了太多的定时器。
	//解决方案就是让我们元素只有一个定时器执行,先清除以前的定时器,只保留当前的一个定时器执行。
	clearInterval(obj.timer);
	obj.timer = setInterval(function(){
	//将计时器封装在对象中,给不同的元素指定了不同的计时器,避免了多个计时器有相同的名称。
		if(obj.offsetLeft >= target){
			//若obj与父盒子左侧相距target。
			clearInterval(obj.timer);
			//则obj不再移动,即停止计时器。
		}
		div.style.left = div.offsetLeft + 1 + "px";
		//不断为obj左偏移赋值,使obj与父元素左侧相距距离不断加1。
	},30);
}
var div = document.querySelector('div');
animate(div,200);

(3) 缓动效果原理

<1>概述

缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来

<2> 思路

<2.1> 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来。
<2.2> 核心算法:(目标值-现在的位置)/10 做为每次移动的距离步长。
//注意步长值需要取整,当我们点击按钮时候,判断步长是正值还是负值。
如果是正值,则步长往大取整。
如果是负值,则步长向小取整。
<2.3> 停止的条件是:让当前盒子位置等于目标位置就停止定时器。
function animate(obj,target,callback){
	//当我们不断的为同一个对象添加动画,这个元素的速度会越来越快,因为开启了太多的定时器。
	//解决方案就是让我们元素只有一个定时器执行,先清除以前的定时器,只保留当前的一个定时器执行。
	clearInterval(obj.timer);
	obj.timer = setInterval(function(){
	//将计时器封装在对象中,给不同的元素指定了不同的计时器,避免了多个计时器有相同的名称。
		var step = (target - obj.offsetLeft) / 10; //步长
		//将步长取整,如果是正值,则步长往大取整;如果是负值,则步长向小取整。
		step = step > 0 ? Math.ceil(step) : Math.floor(step);
		if(obj.offsetLeft = target){
			//若obj与父盒子左侧相距target。
			clearInterval(obj.timer);
			//则obj不再移动,即停止计时器。
			if(callback){
			//若回调函数存在,执行回调函数。
				callback();
			}
			//另一种写法:callback && callback();
		}
		div.style.left = div.offsetLeft + step + "px";
		//不断为obj左偏移赋值,使obj与父元素左侧相距距离不断加1。
	},30);
}
var div = document.querySelector('div');
animate(div,200,function(){
	alert("callback已执行");
});

(4) 筋斗云单例

<1> 需求

<1.1> 当鼠标经过时,筋斗云移动到鼠标经过位置;
<1.2> 当鼠标离开,就回到起始位置;
<1.3> 当鼠标点击就把当前位置作为起始位置。

<2> 代码实现

//这个current做为筋斗云的起始位置
var current = 0;
for(var i = 0; i < lis.length; i++){
//鼠标经过把当前小1i的位置做为目标值
lis[il.addEventListener('mouseenter',function(){
	//cloud代表筋斗云元素
	animate(cloud,this.offsetLeft);
});
//鼠标离开就回到起始的位置
lis[i].addEventListener('mouseleave',function(){
	animate(cloud,current);
});
//当我们鼠标点击,就把当前位置做为目标值
lis[i].addEventListener('click',function(){
	current = this.offsetLeft;
});
 

8 节流阀

(1) 目的

当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发。

(2) 核心实现思路

<1> 利用回调函数,添加一个变量来控制,锁住函数和解锁函数。
<2> 开始设置一个变量
var flag = true;
<3> 关闭水龙头 
if(flag){
  flag = false;
  do something;
}
<4> 打开水龙头
//在执行完毕时调用的回调函数中,打开水龙头。
flag=true;
posted @ 2023-06-02 11:17  10kcheung  阅读(34)  评论(0)    收藏  举报