【Web API】PC端网页特效

 
元素偏移量offset

使用offset可动态的得到元素的位置(偏移)大小

注:偏移是指相对于带有定位的父元素;大小是指自身整个盒子的宽高;返回值都不带单位

box.offsetTop			// 上偏移位置
box.offsetLeft			// 左偏移位置
box.offsetWidth			// 宽
box.offsetHeight		// 高
box.offsetParent		// 返回带有定位的父亲

offsetWidthstyle.width的区别(height同理)

  1. offset可以得到任意样式表中的样式值;style.width只能得到行内样式表中的样式值(内嵌式css不行!!!)
  2. offset返回的是没有单位的数字型;style.width返回的带有单位的字符串
  3. offsetWidth是整个盒子(width+padding+border);style.width得到的就是width
  4. offsetWidth只读,不能赋值修改;style.width可读可写
  5. 因此:offsetWidth适合获取元素的位置和大小;style.width适合对元素进行修改

 
元素可视区client

使用client可动态的得到元素的边框大小元素大小

box.clientTop				// 上边框的大小(很不常用)
box.clientLeft				// 左边框的大小
box.clientWidth				// 返回宽度(包括padding和自身width,不包括边框border)
box.clientHeight			// 返回宽度(包括padding和自身heigth,不包括边框border)

 
元素滚动scroll

使用scroll可以动态的得到元素的大小滚动距离

box.scrollTop				// 被卷去的上方距离
box.scrollLeft				// 被卷去的左侧距离
box.scrollWidth				// 返回宽度(包括padding,不包括border)
box.scrollHeight			// 返回高度(包括padding,不包括border)

// 与clientWidth和clientHeigth的区别是,返回的内容实际的宽高,包括超出的部分

// 注意区分———页面被卷去的头部是pageYOffset;盒子中被卷去的头部是scrollTop(同理宽度)

 
三个系列的总结

获取元素大小方面:offset获取的是包含border的;clientscroll不包含border的;都包含padding;scroll还包含超出的内容

主要用法offsetTop、offsetLeft用来获取位置偏移;offsetWidth、offsetHeight(clientWidth、clientHeight)用来获取元素大小;scrollTop、scrollLeft用来获取滚动距离;页面滚动距离用window.pageXOffset、window.pageYOffset;其他的几乎不用

上面的主要用法是重点 ! ! !

 
补充内容——立即执行函数

// 不需要调用,立即执行
// 写法:
(function() {})()			// 其实这样最容易理解(其实就是声明后立即传入了参数>_<)
(function() {}())			// 当然这样也可以

(function(a, b) {
    console.log(a + b);
})(2, 3);						// 输出5
(function(a, b) {
    console.log(a + b);
}(2, 3));						// 输出5

// ☀ 主要作用:每个立即执行函数都创建了一个独立的作用域,这避免了命名冲突的问题

 
补充内容——mouseover和mouseenter的区别

mouseover经过自身盒子会触发,经过子盒子也会触发;mouseenter只有经过自身盒子会触发

mouseover经过自身盒子的触发,实际上子盒子冒泡的结果;

也就是说,mouseover冒泡mouseenter不冒泡mouseleave也不冒泡

 
动画函数封装

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

// 简单动画函数的封装:参数有 目标对象obj,目标位置target
function anime(obj, target) {
    clearInterval(obj.timer); 					// 清除以前的定时器,防止元素有多个定时器(timer越来越多,元素无限加速...)
    obj.timer = setInterval(function() { 		// 给不同的对象指向了不同的定时器(节约了资源,避免了命名歧义)
        if (obj.offsetLeft >= target) {
            clearInterval(obj.timer);
        } else {
            obj.style.left = obj.offsetLeft + 1 + 'px';
        }
    }, 30);
}

// 优化:渐慢(通过修改步长实现) + 可返回(通过步长的负值实现反向)
function anime(obj, target) {
    clearInterval(obj.timer); 
    obj.timer = setInterval(function() { 
        var step = (target - obj.offsetLeft) / 10; 					// 通过设置可变步长,巧妙实现了渐慢的效果
        step = step > 0 ? Math.ceil(step) : Math.floor(step); 		// 避免了取到0后无法到达指定位置的bug(重难点)
        if (obj.offsetLeft == target) {
            clearInterval(obj.timer);
        } else {
            obj.style.left = obj.offsetLeft + step + 'px';
        }
    }, 30);
}

// 再添加功能:添加回调函数
// 其实很简单,这样声明动画函数,然后传入一个函数实参(匿名函数or函数名)就行了:
function anime(obj, target, callback){
	if(callback){						// 别忘啦,JS允许传入任意数量的实参,也就是说它自带重载(我们可以使用回调函数)
		callback();						// 通常这句话写在clearInteval(timer)的后面———在动画结束时调用这个效果
	}
	// 一种更优雅的写法
	callback && callback();
}

上面封装的那个动画函数虽说没有css丝滑,但绝对比你想象中的经典且强大

在后面的PC端网页特效案例会经常用到且效果极佳

 
 
 

 
----------------------------------------------------------分割线----------------------------------------------------------------
 
PC端网页特效案例
 

获取鼠标点击位置
在这里插入图片描述

var box = document.querySelector('.box');
box.addEventListener('click', function(e) {
	// 巧妙使用了一个减法(本身不难,但需要想到 ! ! !)
	var dx = e.pageX - this.offsetLeft;	
	var dy = e.pageY - this.offsetTop;
})

拖动盒子
在这里插入图片描述

// 核心思路:分为三步:鼠标按下--鼠标移动--鼠标弹起
// 除了鼠标按下绑定在box上,其他两个事件都绑定在document上 !

var box = document.querySelector('.box');
box.addEventListener('mousedown', function(e) {
    var dx = e.pageX - box.offsetLeft; 							// 鼠标按下,获得鼠标相对于盒子的位置(这个位置在拖动时是不变量)
    var dy = e.pageY - box.offsetTop;
    // 鼠标移动和鼠标弹起的事件,一定要位于鼠标按下内!!!
    document.addEventListener('mousemove', move); 				// 鼠标移动,通过计算(鼠标咋页面的位置-鼠标相对盒子的位置)给盒子的left和top赋值
    document.addEventListener('mouseup', function() { 			// 鼠标弹起,移除鼠标移动事件
            document.removeEventListener('mousemove', move);
        })
        
    function move(e) { 		// 鼠标移动时,对盒子位置的计算
        box.style.left = e.pageX - dx + 'px';
        box.style.top = e.pageY - dy + 'px';
    }
})

淘宝侧边栏案例

// 需求是:本来侧边栏是随主体而滚动的,到了某处时固定

// 关键点是获得页面上方被卷曲的值,当该值达到某个数值是,将绝对定位(absolute)改为固定定位(fixed)
// 再复习一下什么是绝对定位:不是说一直固定在页面某处(那是固定定位),也会随着页面滚动而滚动,不要曲解“绝对”二字

var bar = document.querySelector('.bar');
document.addEventListener('scroll', function() { 	// 滚动事件时document的滚动,事件源是document
    if (window.pageYOffset >= 300) {				// 页面被卷去的头部是pageYOffset;盒子中被卷去的头部是scrollTop;注意区分
        bar.style.position = 'fixed';
    } else {
        bar.style.position = 'absolute';
    }
})

// 其实还有点小bug,改为固定定位的同时还要给固定定位设置fixed,这可以利用offsetTop经过简单的计算实现

导航栏特效(选中区域的滑动与固定)
在这里插入图片描述

// html和css很简单,ul>li*6并且有一个绝对定位的.cloud;它们属于.box大盒子

// 核心思路:
// .box相对定位后,使用offsetLeft作为cloud移动的目标位置
// 上面封装的anime位移动画函数派上了大用场

window.addEventListener('load', function() {
    var box = document.querySelector('.box');
    var cloud = document.querySelector('.cloud');
    var lists = document.querySelectorAll('li');
    var current = 0; 		// current作为起始位置
    for (var i = 0; i < lists.length; i++) {
        lists[i].addEventListener('mouseenter', function() {
            anime(cloud, this.offsetLeft);				 // 鼠标经过就移动cloud
        })
        lists[i].addEventListener('mouseleave', function() {
            anime(cloud, current); 						// 鼠标离开,cloud回到起始位置
        })
        lists[i].addEventListener('click', function() {
            current = this.offsetLeft; 					// 鼠标点击,cloud起始位置更新为此处
        })
    }
})

 
☀ Loli & JS

♫ Suki

猜你喜欢

转载自blog.csdn.net/m0_46202073/article/details/106669154
今日推荐