本篇为 JavaScript 系列笔记第八篇,将陆续更新后续内容。参考:黑马程序员JavaScript核心教程,前端基础教程

系列笔记:

JavaScript(一)—— 初识JavaScript / 注释 / 输入输出语句 / 变量 / 数据类型

JavaScript(二)—— 运算符 / 流程控制 / 数组

JavaScript(三)—— 函数 / 作用域 / 预解析 / 对象

JavaScript(四)—— 内置对象 / 简单数据类型与复杂类型

JavaScript(五)—— Web APIs 简介 / JavaScript 必须掌握的 DOM 操作

JavaScript(六)—— DOM 事件高级

JavaScript(七)—— BOM 浏览器对象模型

文章预览

「一」元素偏移量 offset


offset 系列相关属性可以 动态的 得到该元素的位置(偏移)、大小等:

  1. 获得元素距离带有定位父元素的位置
  2. 获得元素自身的大小(宽度、高度)
  3. 返回的数值不带单位

offset 系列常用属性如下:

  • offsetTopoffsetLeft 属性

  1. 父亲有定位,则以 父亲 为准,返回 45
  2. 父亲无定位,则以 body 为准,返回 195
  • offsetWidthoffsetHeight 属性
  1. 计算数值时包含 paddingborderwidth
  2. 可以动态获取数值,比如浏览器缩小时,数值相应变化
  • offsetParent 属性

  1. 返回带有定位的父亲,否则返回 body
  2. 与节点操作中 parentNode 相比,parentNode 返回最近一级的父亲,无论父亲是否有定位
  • offset 与 style 区别

offset

  1. offset 可以得到任意样式表中的样式值
  2. offset 系列获得的数值是没有单位的
  3. offsetWidth 包含 padding、border、width
  4. offsetWidth 等属性是只读属性,只能获取不能赋值
  5. 只想获取元素大小位置,offset 更合适

style

  1. style 只能得到行内样式表中的样式值
  2. style.width 获得的是带有单位的字符串
  3. style.width 获得不包含 padding 和 border 的值
  4. style.width 是可读写属性,可以获取也可以赋值
  5. 要想给元素更改值,需要用 style

  • 案例:获取鼠标在盒子内的坐标
var box = document.querySelector('.box');
box.addEventListener('mousemove', function (e) {var x = e.pageX - this.offsetLeft;var y = e.pageY - this.offsetTop;this.innerHTML = 'x坐标是' + x + ' y坐标是' + y;})box.addEventListener('mouseout', function () {this.innerHTML = '';})
  • 案例:模态框拖拽

var login = document.querySelector('.login');
var mask = document.querySelector('.login-bg');
var link = document.querySelector('#link');
var closeBtn = document.querySelector('#closeBtn');
var title = document.querySelector('#title');
// 显示
link.addEventListener('click', function () {mask.style.display = 'block';login.style.display = 'block';
})
// 隐藏
closeBtn.addEventListener('click', function () {mask.style.display = 'none';login.style.display = 'none';
})
// 拖拽
title.addEventListener('mousedown', function (e) {var x = e.pageX - login.offsetLeft;var y = e.pageY - login.offsetTop; document.addEventListener('mousemove', move);function move(e) {login.style.left = e.pageX - x + 'px';login.style.top = e.pageY - y + 'px';}document.addEventListener('mouseup', function () {document.removeEventListener('mousemove', move);})
})
  1. 鼠标按下 mousedown,获取鼠标在盒子中坐标
  2. 鼠标移动 mousemove,求得模态框的 lefttop
  3. 鼠标弹起 mouseup,移除注册事件 removeEventListener
  • 案例:仿京动放大镜

部分 HTML 代码

<div class="preview_img"><img src="img/mac_small.jpg" alt="">   <--小图--><div class="mask"></div>               <--遮罩--><div class="preview_img_big">            <--大图--><img src="img/mac_big.jpg" alt="" class="big_img"></div>
</div>

部分 CSS 代码

.preview_img {position: relative;height: 450px;border: 1px solid #ccc;
}.mask {display: none;position: absolute;left: 0;top: 0;width: 300px;height: 300px;background: #FEDE4F;opacity: .5;        /* 不透明度 */border: 1px solid #ccc;cursor: move;       /* 鼠标样式为移动 */
}.preview_img_big {display: none;position: absolute;left: 450px;top: -1px;width: 540px;height: 540px;border: 1px solid #ccc;overflow: hidden;
}.big_img {position: absolute;top: 0;left: 0;
}

JS 代码

window.addEventListener('load', function () {var preview_img = document.querySelector('.preview_img');var mask = document.querySelector('.mask');var big = document.querySelector('.preview_img_big');preview_img.addEventListener('mouseover', function () {mask.style.display = 'block';big.style.display = 'block';})preview_img.addEventListener('mousemove', move);function move(e) {var x = e.pageX - this.offsetLeft;var y = e.pageY - this.offsetTop;// 减去遮罩盒子高度一半 var maskX = x - mask.offsetWidth / 2;var maskY = y - mask.offsetHeight / 2;// 最大移动距离(宽高相等)var maskMax = preview_img.offsetWidth - mask.offsetWidth;if (maskX <= 0) {maskX = 0;} else if (maskX >= maskMax) {maskX = maskMax;}if (maskY <= 0) {maskY = 0;} else if (maskY >= maskMax) {maskY = maskMax;}mask.style.left = maskX + 'px';mask.style.top = maskY + 'px';// 获得大图片var big_img = document.querySelector('.big_img');// 最大移动距离var bigMax = big_img.offsetWidth - big.offsetWidth;var bigX = maskX * bigMax / maskMax;var bigY = maskY * bigMax / maskMax;big_img.style.left = -bigX + 'px';big_img.style.top = -bigY + 'px';}preview_img.addEventListener('mouseout', function () {mask.style.display = 'none';big.style.display = 'none';})
})

注意:

  1. 若将 js 文件放在 html 上面,注意一定要先加载窗口 window.addEventListener('load', function(){}),否则注册事件绑定为空,出现报错
  2. 理解遮罩层和放大图片移动的算法

「二」元素可视区 client


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

  • client 系列和 offset 系列区别

「三」元素滚动 scroll


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

  • onscroll 事件

如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条,当滚动条向下滚动时,会触发 onscroll 事件

  • 案例:仿淘宝固定右侧侧边栏

部分 HTML 代码

JS 代码

var sliderbar = document.querySelector('.slider-bar');
var banner = document.querySelector('.banner');var bannerTop = banner.offsetTop;var sliderbarTop = sliderbar.offsetTop - bannerTop;var main = document.querySelector('.main');var goBack = document.querySelector('.goBack');var mainTop = main.offsetTop;document.addEventListener('scroll', function (e) {if (window.pageYOffset >= bannerTop) {sliderbar.style.position = 'fixed';sliderbar.style.top = sliderbarTop + 'px';} else {sliderbar.style.position = 'absolute';sliderbar.style.top = '300px';}if (window.pageYOffset >= mainTop) {goBack.style.display = 'block';} else {goBack.style.display = 'none';}})

注意:页面被卷去的头部,有兼容问题,通常有下面几种写法:

  1. 声明了 DTD(<!DOCTYPE html>),使用 document.documentElement.scrollTop
  2. 未声明 DTD,使用 document.body.scrollTop
  3. IE9 开始,新方法 window.pageYOffsetwindow.pageXOffset

「四」动画函数


  • 动画实现原理

通过定时器 setInterval() 不断移动盒子位置。实现步骤:

  1. 获得盒子当前位置
  2. 通过定时器不断重复移动单位距离(需要添加定位,使用 element.style.left )
  3. 添加结束定时条件

  • 动画函数的封装

可能一个页面中会多次调用动画过程,因此可以将其封装成函数。

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

function animate(obj, target) {var timer = setInterval(function () {if (obj.offsetLeft >= target) {clearInterval(timer);}obj.style.left = obj.offsetLeft + 2 + 'px';}, 10)
}
  • 动画函数给不同元素记录不同定时器

若每次调用都声明 var timer 变量,会造成占用大量内存以及重复命名歧义等问题。因此,这里利用给对象添加属性的方式进行赋值操作 obj.timer,实现了不同元素指定不同定时器

  1. 为避免持续点击导致开启多个定时器,应在函数调用开始时清除所有定时器
  2. 为避免停止后点击还会少量移动问题,在到达指定距离后,return 结束函数调用
  • 缓动效果原理

缓动动画就是让元素运动速度有所变化,最常见的是逐渐降速到停止,使得效果更加自然

算法: 步长 = (目标位置 - 当前位置)/ 10

 var step = (target - obj.offsetLeft) / 10;step = step > 0 ? Math.ceil(step) : Math.floor(step);


  1. 避免小数问题导致最后无法运动到指定 target, 这里利用了向上取整
  2. 此外,考虑到后退过程,向上取整也出现了问题。因此需要分类来讨论
  • 动画函数添加回调函数

回调函数原理:函数可以作为一个参数,作为传递到另一个函数中

function animate(obj, target, callback) {}   // callback 回调函数animate(span, 500, function () {});


  • 动画函数封装到单独 JS 文件中

以后会经常使用动画函数,因此可以将其单独封装到一个 JS 文件中,使用时直接引用 JS 文件即可

  • 案例:滑动盒子
    <div class="sliderbar"><span>←</span><div class="con">问题反馈</div></div><script>var sliderbar = document.querySelector('.sliderbar');var con = document.querySelector('.con');sliderbar.addEventListener('mouseenter', function () {animate(con, -160, function () {sliderbar.children[0].innerHTML = '→';});})sliderbar.addEventListener('mouseleave', function () {animate(con, 0, function () {sliderbar.children[0].innerHTML = '←';});})</script>
  1. mouseentermouseleavemouseovermouseout 用法一样,区别在于前者无法冒泡
  2. 注意要引用 animate.js

「五」常见网页特效案例


  • 案例:淘宝轮播图

JS 代码主要利用

  1. animate.js 代码
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) {clearInterval(obj.timer);callback && callback();}obj.style.left = obj.offsetLeft + step + 'px';}, 15);
}
  1. index.js 代码
window.addEventListener('load', function () {var arrow_l = document.querySelector('.arrow-l');var arrow_r = document.querySelector('.arrow-r');var focus = document.querySelector('.focus');var focusWidth = focus.offsetWidth;//  鼠标经过 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);})// 动态生成小圆圈var ul = focus.querySelector('ul');var ol = focus.querySelector('.circle');for (var i = 0; i < ul.children.length; i++) {var li = document.createElement('li');// 淘宝源码中 li 中又创建了 a,其实在这里不创建 a 也可以,本案例暂且依淘宝为准var a = document.createElement('a');// 记录索引a.setAttribute('index', i);ol.appendChild(li);li.appendChild(a);// 圆圈绑定事件li.addEventListener('focus', function () {this.blur();})a.addEventListener('click', function () {// 排他思想,被点击的圆圈设置 current 样式for (var i = 0; i < ol.children.length; i++) {ol.children[i].firstChild.className = '';}this.className = 'current';// 移动图片var index = this.getAttribute('index');animate(ul, - index * focusWidth);// 修改索引num = circle = index;})}ol.children[0].firstChild.className = 'current';// 克隆第一张图片放在 ul 最后,实现无缝滚动(不复制直接添加的话会多出一个小圆圈)var first = ul.children[0].cloneNode(true);ul.appendChild(first);// 点击右侧按钮, 图片滚动一张var num = 0;// circle 控制小圆圈的播放var circle = 0;// flag 节流阀, 防止连续点击造成过快播放var flag = true;// 右侧按钮arrow_r.addEventListener('click', function () {if (flag) {flag = false; // 关闭节流阀// 如果走到最后复制的一张图片,ul 快速复原if (num == ul.children.length - 1) {ul.style.left = 0;num = 0;}num++;animate(ul, -num * focusWidth, function () {flag = true; // 打开节流阀});circle++;// 最后一张时复原if (circle == ol.children.length) {circle = 0;}// 调用函数circleChange();}})// 左侧按钮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 = circle < 0 ? ol.children.length - 1 : circle;circleChange();}})// 圆圈变色function circleChange() {for (var i = 0; i < ol.children.length; i++) {ol.children[i].firstChild.className = '';}ol.children[circle].firstChild.className = 'current';}// 自动播放轮播图var timer = this.setInterval(function () {arrow_r.click();}, 2000);
})
  1. html 代码、css 代码由于篇幅问题不再给出

遇到的问题

  • 开始写轮播图效果时,遇到点击 li 后出现光标持续闪烁的问题,尝试了各种方法,都没有很好的解决

    如上图所示输入光标
  • 最后灵机一动,发现其实这个问题只需要给整个盒子设置 font-size: 0;,即可完美解决

  • 案例:动画返回页面顶部

在此前案例中,返回顶部使用的是锚点链接,在此处介绍一种新方式:

window.scroll(x, y)   // 滚动窗口至文档中的指定位置

本案例利用 window.scroll(x, y) 配合动画函数 animate 实现动画返回顶部效果

部分 JS 代码

goBack.addEventListener('click', function () {// 窗口进行滚动, 对象是 windowanimate(window, 0);// window.scroll(0, 0);
});// 动画函数
function animate(obj, target) {clearInterval(obj.timer);obj.timer = setInterval(function () {var step = (target - window.pageYOffset) / 10;step = step > 0 ? Math.ceil(step) : Math.floor(step);if (window.pageYOffset == target) {clearInterval(obj.timer);}window.scroll(0, window.pageYOffset + step);}, 15);
}

这里注意 animate 函数 将参数改为垂直相关,利用 window.pageYOffset


  • 案例:筋斗云导航
window.addEventListener('load', function () {var cloud = document.querySelector('.cloud');var c_nav = document.querySelector('.c-nav');var lis = c_nav.querySelectorAll('li');// 设置变量,记录起始位置var current = 0;for (var i = 0; i < lis.length; i++) {// 鼠标进入,当前 li 位置为目标值lis[i].addEventListener('mouseenter', function () {animate(cloud, this.offsetLeft);})// 鼠标离开,回到起始位置lis[i].addEventListener('mouseleave', function () {animate(cloud, current);})// 鼠标点击,当前位置设为目标值lis[i].addEventListener('click', function () {current = this.offsetLeft;})}
})

JavaScript(八)—— PC 端网页特效相关推荐

  1. 【重点案例】b站pink老师JavaScript的PC端网页特效 案例代码——网页轮播图

    目录 代码段: 1.index.js部分(全是重点) 2.animate.js部分(重点,是之前封装好的动画函数) 3.index.html部分(重点在标红区) 4.index.css部分(重点在标红 ...

  2. b站pink老师JavaScript的PC端网页特效 案例代码——仿京东放大镜效果

    目录 原理讲解: 代码段: 1. detail.html部分(重点在标红区) 2. detail.js部分(全部都是重点) 3. detail.css部分(重点在标红区) 4. base.css部分( ...

  3. b站pink老师JavaScript的PC端网页特效 案例代码——筋斗云案例

    目标效果: 1.最开始的时候cloud筋斗云处于最左边 2.当鼠标经过(mouseenter 不冒泡)对应li,cloud筋斗云就移到那个li(lis[i].offsetLeft获得li相对有定位的父 ...

  4. b站pink老师JavaScript的PC端网页特效 案例代码——仿淘宝固定侧边栏

    目标效果: 1.当页面滚动到banner区域的顶部碰到页面顶部时,右边的侧边栏sliderbar,由之前距离页面顶部300px的固定定位,变为    侧边栏sliderbar距离页面顶部的距离=页面滚 ...

  5. b站pink老师JavaScript的PC端网页特效 案例代码——仿淘宝返回顶部(带有动画的返回顶部)

    目标效果: 在之前写好的 的代码基础上 实现点击返回顶部字样,即可用缓动动画返回顶部[见代码段中4.和动画函数部分] 重点语法: 滚动窗口至文档中的特定位置 window.scroll(x,y) x, ...

  6. javaScript PC端网页特效

    PC端网页特效 1. 元素偏移量 offset 系列 1.1 offset 概述 1.2 offset 与 style 区别 2. 元素可视区 client 系列 2.1 立即执行函数 2.2 loa ...

  7. JavaScript—— PC 端网页特效

    目录 一.PC 端网页特效 1. 元素偏移量 offest 系列 1.1 offset 概述 1.2 offset 与 style 区别 案例:获取鼠标在盒子内的坐标 案例:模拟框拖拽 html cs ...

  8. 移动端、PC端 网页特效

    移动端网页特效 标题触屏事件 移动端浏览器兼容性较好,不需要考虑以前 JS 的兼容性问题,可以放心的使用原生 JS 书写效果,但是移动端也有自己独特的地方.比如触屏事件 touch(也称触摸事件),A ...

  9. 05【JS 高级】-【PC端网页特效】元素偏移量 offset 系列, 元素可视区 client 系列, 元素滚动 scroll 系列, 动画函数封装, 常见网页特效案例

    04[JS 高级]-[PC端网页特效] 学习内容: 元素偏移量 offset 系列, 元素可视区 client 系列, 元素滚动 scroll 系列, 动画函数封装, 常见网页特效案例 1. 元素偏移 ...

  10. JS PC端网页特效 (一)

    2022年7月27日 周三学习记录博客  学习进度:PC端网页特效(一).学习时长:6h. 目录 PC端网页特效 1.元素偏移量 offset 系列 1.1 offset 概述 1.2 offset ...

最新文章

  1. 一行代码搞定 Python 逐行内存消耗分析
  2. 如何彻底关闭windows update
  3. 32位crc校验码程序_CRC码计算及校验原理的最通俗诠释
  4. webpack 的基本使用—— 创建列表隔行变色项目||在项目中安装和配置 webpack
  5. oracle结束过程,oracle 结束被锁的包或存储过程
  6. UVA 536——Tree Recovery
  7. 华为p50预装鸿蒙系统,华为P50系列将至,内部测试预装鸿蒙系统,还有4款重磅新品将发布...
  8. gdb vscode 不进入断点_VScode配置MASM32运行环境(断点/运行/debug/配合emu8086(非DOSBox))...
  9. linux 函数自动补全,Shell脚本中实现自动补全功能
  10. Android实现传感器应用及位置服务
  11. 关于网页导出Excel
  12. 软件设计师中级考试经验总结
  13. NOD32杀毒软件如何更新及用户名列表
  14. 图片验证码的实现以及校验验证码
  15. 2020-10-04
  16. 什么是RF、IF信号
  17. CSS外边距合并和CSS清除浮动
  18. 【每日进步一点点】C语言刷题技巧及训练1
  19. 54家半导体芯片原厂涨价、调价及交期变动通知函!
  20. 人工智能(1)-样本空间、假设空间、版本空间

热门文章

  1. python画3d心形_有了这几个3D立体手工教程,幼儿园手工作业再也不用愁!
  2. EifficientDet论文笔记
  3. 完善区块链产业链 加速经济数字化转型
  4. SpringMVC的简要介绍和表单参数的接收和时间参数的转换
  5. api 文件夹index.js 集合写法
  6. 模板语法-插入文本//模板语法-插入标签//模板语法-双花括号//模板语法-向标签属性中插入数据
  7. 小汤学编程之JDBC(一)——JDBC概述和快速入门
  8. TypeScript完全解读(26课时)_14.ES6和Nodejs中的模块
  9. 求逆元的两种方法+求逆元的O(n)递推算法
  10. bzoj 1079: [SCOI2008]着色方案