JavaScript——PC端网页特效

目录

一、元素偏移量offset系列

1. offset概述

2. 常见属性

3. offset与style区别

案例——鼠标在盒子内坐标

案例——拖动模态框

案例——京东放大镜

二、元素可视区client系列

flexible源码分析

立即执行函数

pageshow事件

三、元素滚动scroll系列

1. 页面被卷去头部

 案例——仿淘宝固定右侧侧边栏

 2. 页面被卷曲头部兼容性方案

四、三大系列总结

五、mouseenter和mouseover事件

六、动画函数封装

1. 动画实现原理

2. 动画函数的简单封装

3. 动画函数给不同元素记录不同定时器

4. 缓动效果动画

5. 动画函数在多个目标之间移动

6. 给动画函数添加回调参数

7. 动画函数封装到单独JS文件里面

案例——右侧盒子滑动

七、常见网页特效案例

案例——网页轮播图

1. 节流阀

短路运算简写callback函数

案例——返回顶部

案例——筋斗云移动


  JavaScript——PC端网页特效_第1张图片

一、元素偏移量offset系列

1. offset概述

offset翻译过来就是偏移量,我们使用offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。

  • 获取元素距离带有定位父元素的位置
  • 获得元素自身大小
  • 注意:返回的值都不带单位

2. 常见属性

JavaScript——PC端网页特效_第2张图片

	
	
	
		

3. offset与style区别

JavaScript——PC端网页特效_第3张图片

案例——鼠标在盒子内坐标

    
	
	
		

案例——拖动模态框

	
	
	
		
		

		
		

		

案例——京东放大镜

JavaScript——PC端网页特效_第4张图片

	
	
		
1

二、元素可视区client系列

通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。

JavaScript——PC端网页特效_第5张图片

flexible源码分析

(function flexible(window,document){
	// 获取html的根元素
	var docEl=document.documentElement;
	// dpr像素比
	var dpr=window.devicePixelRatio	|| 1;
	
	// 设置body的字体大小
	function setBodyFontSize(){
		// 如果页面有body元素,就设置body页面文字大小
		if(document.body){
			document.body.style.fontSize=(12*dpr)+'px';
		}else{
			// 如果页面中无body,则等页面主要DOM元素加载完毕再设置body字体大小
			document.addEventListener('DOMContentLoaded',setBodyFontSize);
		}
	}
	setBodyFontSize();
	
	//设置html元素文字大小
	function setRumUnit(){
		var rem=docEl.clientWidth/10;
		docEl.style.fontSize=rem+'px';
	}
	setRumUnit();
	
	// 当我们页面尺寸大小发生变化,要重新设置rem的大小
	window.addEventListener('resize',setRumUnit());
	//pageshow使我们重新加载页面触发的事件
	window.addEventListener('pageshow',function(e){
		// e.persisted返回true,就是说如果这个页面是从缓冲取过来的页面,也需要重新计算rem大小
		if(e.persisted){
			setRumUnit();
		}
	})
	
	// 有些移动端不支持0.5像素的写法
	if(dpr>=2){
		var fakeBody=document.createElement('body');
		var testElement=document.createElement('div');
		testElement.style.border='.5px solid transparent';
		fakeBody.appendChild(testElement);
		docEl.appendChild(fakeBody);
		if(testElement.offsetHeight===1){
			docEl.classList.add('hairlines')
		}
		docEl.removeChild('fakeBody')
	}
}(window,document))

立即执行函数

  1. 立即函数不需要调用,立马自己执行
  2. 也可以传递参数
  3. 立即执行函数最大的作用是:独立创建了一个作用域,里面所有变量都是局部变量,不会有命名冲突情况
//创建方法
//也可以传递参数

//独立创建了一个作用域,里面所有变量都是局部变量,不会有命名冲突情况

pageshow事件

JavaScript——PC端网页特效_第6张图片

三、元素滚动scroll系列

使用scroll系列的相关属性可以动态的得到该元素的大小、滚动距离等。

JavaScript——PC端网页特效_第7张图片JavaScript——PC端网页特效_第8张图片 

1. 页面被卷去头部

如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。滚动条在滚动时会触发onscroll事件

 案例——仿淘宝固定右侧侧边栏

 JavaScript——PC端网页特效_第9张图片 JavaScript——PC端网页特效_第10张图片JavaScript——PC端网页特效_第11张图片

    
	
		
返回顶部
头部区域
主体部分

 2. 页面被卷曲头部兼容性方案

JavaScript——PC端网页特效_第12张图片

  

四、三大系列总结

 JavaScript——PC端网页特效_第13张图片

 主要用法:

  1. offset 系列经常用于获取元素位置 offsetLeft offsetTop
  2. client 系列经常用于获取元素大小 clientWidth clientHeight
  3. scroll 经常用于获取滚动距离 scrollTop scrollLeft
  4. 注意页面的滚动距离通过  window.pageXoffset  获得

五、mouseenter和mouseover事件

  • 当鼠标移动到元素上会触发mouseenter和mouseover事件
  • 当mouseover鼠标经过自身盒子会触发,经过子盒子还会触发
  • mouseenter只会经过自身盒子才触发
  • 之所以这样,mouseenter不会冒泡
  • 跟mouseenter搭配 鼠标离开事件 mouseleave 同样不会冒泡

六、动画函数封装

1. 动画实现原理

核心原理:通过定时器setInterval()不断移动盒子位置

实现步骤:

  1. 获取当前盒子位置
  2. 让盒子在当前位置加上一个像素
  3. 利用定时器不断重复这个操作
  4. 加上结束定时器条件
  5. 注意!此元素要添加定位才行

常见网页特效案例

2. 动画函数的简单封装

注意需要传递2个参数,动画对象移动到的距离

//简单函数封装,obj目标对象,target目标位置
function animate(obj, target) {
	var timer = setInterval(function() {
		if (obj.offsetLeft >= target) {
			//停止动画,本质停止定时器
			clearInterval(timer);
		}
		obj.style.left = obj.offsetLeft + 1 + 'px';
	}, 30);
}

3. 动画函数给不同元素记录不同定时器

JavaScript——PC端网页特效_第14张图片

    
		
		

以上优化有bug:当我们不断点击按钮,这个元素会越来越快,应为开启太多定时器

function animate(obj, target) {
	//先清楚以前定时器,只保留当前的定时器
	clearInterval(obj.timer);
	obj.timer = setInterval(function() {
		if (obj.offsetLeft >= target) {
			//停止动画,本质停止定时器
			clearInterval(obj.timer);
		}
		obj.style.left = obj.offsetLeft + 2 + 'px';
	}, 30);
}

解决方案:先清除以前定时器,只保留当前的定时器

4. 缓动效果动画

缓动动画就是让元素运动有所变化。

思路:

  1. 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来
  2. 核心算法:(目标值-现在的位置)/ 10 ,作为每次移动的步长
  3. 停止条件:让当前盒子位置等于目标位置就停止定时器
  4. 注意步长值需要取整
function animate(obj, target) {
	clearInterval(obj.timer);
	obj.timer = setInterval(function() {
		//步长值写定时器里面
		var step=(target-obj.offsetLeft)/10;
		if (obj.offsetLeft >= target) {
			clearInterval(obj.timer);
		}
		//把每次加1改为慢慢变小,(目标值-现在的位置)/ 10 ,作为每次移动的步长
		obj.style.left = obj.offsetLeft + step + 'px';
	}, 15);
}

5. 动画函数在多个目标之间移动

可以让动画函数从800移动到500.

当我们点击按钮时,判断步长时正值还是负值

  1. 如果是正值,则步长往大了取整。
  2. 如果是负值,则步长向小了取整。



6. 给动画函数添加回调参数

回调函数原理:函数可以作为一个参数。将这个函数作为参数传递到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫回调

回调函数写的位置:定时器结束的位置。




7. 动画函数封装到单独JS文件里面

因为以后经常使用这个动画函数,可以单独封装到一个JS文件里面,使用的时候引用这个JS文件即可。

function animate(obj, target, callback) {
	// console.log(callback);//等价于 callback=function(){}调用的时候callback()
	clearInterval(obj.timer);
	obj.timer = setInterval(function() {
		//步长值写定时器里面
		// 把步长值改为整数,避免到不了固定位置
		// var step = Math.ceil((target - obj.offsetLeft) / 10);
		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();
			}
		}
		//把每次加1改为慢慢变小,(目标值-现在的位置)/ 10 ,作为每次移动的步长
		obj.style.left = obj.offsetLeft + step + 'px';
	}, 15);
}

案例——右侧盒子滑动

JavaScript——PC端网页特效_第15张图片






	
<-
问题反馈

七、常见网页特效案例

案例——网页轮播图

轮播图也称焦点图

JavaScript——PC端网页特效_第16张图片

 JavaScript——PC端网页特效_第17张图片

JavaScript——PC端网页特效_第18张图片

 JavaScript——PC端网页特效_第19张图片

 

 JavaScript——PC端网页特效_第20张图片

//js
window.addEventListener('load', function() {
	// 1.获取元素
	var arrow_l = document.querySelector('.arrow-l');
	var arrow_r = document.querySelector('.arrow-r');
	var focus = document.querySelector('.focus');
	var focusWidth = focus.offsetWidth;
	// 2.鼠标经过focus 就显示隐藏左右按钮
	focus.addEventListener('mouseenter', function() {
		arrow_l.style.display = 'block';
		arrow_r.style.display = 'block';
		clearInterval(timer);
		timer = null;
	})
	focus.addEventListener('mouseleave', function() {
		arrow_l.style.display = 'none';
		arrow_r.style.display = 'none';
		timer = setInterval(function() {
			// 手动调用事件
			arrow_r.click()
		}, 2000);
	})

	// 3.动态生成小圆圈 有几张图片,我就生成几个小圆圈
	var ul = focus.querySelector('ul');
	var ol = focus.querySelector('.circle');
	for (var i = 0; i < ul.children.length; i++) {
		// 创建一个小li
		var li = document.createElement('li');
		// 记录当前小圆圈索引号,通过自定义属性来做
		li.setAttribute('index', i);
		// 把小li插入到ol里面
		ol.appendChild(li);
		//4.小圆圈的排他思想,我们可以直接再生产小圆圈的同时直接绑定点击事件
		li.addEventListener('click', function() {
			for (var i = 0; i < ol.children.length; i++) {
				ol.children[i].className = '';
			}
			this.className = 'current';
			//5.点击小圆圈,移动图片 当然是ul
			//ul的移动距离就是小圆圈索引号乘以图片宽度 注意是负值
			// 当我们点击了某个小li,就拿到li的索引号
			var index = this.getAttribute('index');
			// 当我们点击了某个小li,就要把这个li的索引号给num
			num = index;
			//当我们点击了某个小li,就把li的索引号给circle1
			circle = index;
			animate(ul, -index * focusWidth);
		})
	}
	// 把ol里面第一个小li设置为current
	ol.children[0].className = 'current';
	// 6.克隆第一张图片放到ul最前面
	var first = ul.children[0].cloneNode(true);
	ul.appendChild(first);
	//7.右侧按钮点击事件
	var num = 0;
	var circle = 0; //控制小圆圈播放
	var flag = true; //节流阀
	arrow_r.addEventListener('click', function() {
		if (flag) {
			flag = false; //关闭节流阀
			// 如果走到最后,图片滚到第一张
			if (num == ul.children.length - 1) {
				ul.style.left = 0;
				num = 0;
			}
			num++;
			animate(ul, -num * focusWidth, function() {
				flag = true; //打开节流阀
			});
			// 8.点击右侧按钮,小圆圈跟随一起变化,可以再声明一个变量控制小圆圈的播放
			circle++;
			// 如果circle==4 说明走到了克隆的图片,我们就复原
			if (circle == ol.children.length) {
				circle = 0;
			}
			circleChange();
		}
	})

	// 9.左侧按钮做法
	arrow_l.addEventListener('click', function() {
		if (flag) {
			flag = false;
			// 如果第一张,图片滚到最后一张
			if (num == 0) {
				num = ul.children.length - 1;
				ul.style.left = -num * focusWidth + 'px';
			}
			num--;
			animate(ul, -num * focusWidth, function() {
				flag = true;
			});
			// 点击左侧按钮,小圆圈跟随一起变化,可以再声明一个变量控制小圆圈的播放
			circle--;
			// 如果circle<0 说明走到了克隆的图片,我们就复原
			// if (circle < 0 ) {
			// 	circle = ol.children.length-1;
			// }
			circle = circle < 0 ? ol.children.length - 1 : circle;
			circleChange();
		}

	});

	function circleChange() {
		// 先清除其余小圆圈的current类名
		for (var i = 0; i < ol.children.length; i++) {
			ol.children[i].className = '';
		}
		// 留下当前的小圆圈current类名
		ol.children[circle].className = 'current';
	}

	// 10。自动播放
	var timer = setInterval(function() {
		// 手动调用事件
		arrow_r.click()
	}, 2000);
})


//css
.focus {
    position: relative;
    width: 721px;
    height: 455px;
    background-color: purple;
    overflow: hidden;
}

.focus ul {
    position: absolute;
    top: 0;
    left: 0;
    width: 600%;
}

.focus ul li {
    float: left;
}

.arrow-l,
.arrow-r {
    display: none;
    position: absolute;
    top: 50%;
    margin-top: -20px;
    width: 24px;
    height: 40px;
    background: rgba(0, 0, 0, .3);
    text-align: center;
    line-height: 40px;
    color: #fff;
    font-family: 'icomoon';
    font-size: 18px;
    z-index: 2;
}

.arrow-r {
    right: 0;
}

.circle {
    position: absolute;
    bottom: 10px;
    left: 50px;
}

.circle li {
    float: left;
    width: 8px;
    height: 8px;
    /*background-color: #fff;*/
    border: 2px solid rgba(255, 255, 255, 0.5);
    margin: 0 3px;
    border-radius: 50%;
    /*鼠标经过显示小手*/
    cursor: pointer;
}

.current {
    background-color: #fff;
}

1. 节流阀

防止轮播图点击按钮播放过快。

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

核心实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数。

JavaScript——PC端网页特效_第21张图片

 

arrow_r.addEventListener('click', function() {
	if (flag) {
		flag = false; //关闭节流阀
		// 如果走到最后,图片滚到第一张
		if (num == ul.children.length - 1) {
			ul.style.left = 0;
			num = 0;
		}
		num++;
		animate(ul, -num * focusWidth, function() {
			flag = true; //打开节流阀
		});
		// 8.点击右侧按钮,小圆圈跟随一起变化,可以再声明一个变量控制小圆圈的播放
		circle++;
		// 如果circle==4 说明走到了克隆的图片,我们就复原
		if (circle == ol.children.length) {
			circle = 0;
		}
		circleChange();
	}
})

短路运算简写callback函数

// if (callback) {
//     // 调用函数
//     callback();
// }
callback && callback();

案例——返回顶部

滚动窗口至文档中特定位置

window.scroll(x,y)

JavaScript——PC端网页特效_第22张图片

	
	
		
返回顶部
头部区域
主体部分

 

案例——筋斗云移动

 

 JavaScript——PC端网页特效_第23张图片

 








 

你可能感兴趣的:(前端,#,JavaScript,javascript,前端,css,html)