JavaScript进阶之BOM技术(五)

JavaScript进阶之BOM技术(五)
Ramsayi目录总览
BOM 概述
- BOM = Browser Object Model 👉 浏览器对象模型
- 它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是 window
- BOM 由一系列相关的对象构成,并且每个对象都提供了很多方法与属性
- BOM 缺乏标准,JavaScript 语法的标准化组织是 ECMA, DOM 的标准化组织是 W3C, BOM 最初是 Netscape 浏览器标准的一部分
| DOM | BOM |
|---|---|
| 文档对象模型 | 浏览器对象模型 |
| DOM 就是把 文档 当作一个对象来看待 | 把 浏览器当作一个对象来看待 |
| DOM 的顶级对象是 document | BOM 的顶级对象是 window |
| DOM 主要学习的是操作页面元素 | BOM 学习的是浏览器窗口交互的一些对象 |
| DOM 是 W3C 标准规范 | BOM 是浏览器厂商在各自浏览器上定义的,兼容性较差 |
BOM 的构成
- BOM 比 DOM 更大。它包含 DOM。
- window 对象是浏览器的顶级对象,它具有双重角色
- 它是 JS 访问浏览器窗口的一个接口
- 它是一个全局对象。定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法
- 在调用的时候可以省略 window,前面学习的对话框都属于 window 对象方法,如
alert()、prompt()等。 - 注意:window 下的一个特殊属性 window.name
1 | // 定义在全局作用域中的变量会变成window对象的属性 |
window 对象的常见事件
窗口加载事件
window.onload是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像,脚本文件,CSS 文件等),就调用的处理函数。
1 | window.onload = function () {} |
注意:
- 有了
window.onload就可以把 JS 代码写到页面元素的上方 - 因为
onload是等页面内容全部加载完毕,再去执行处理函数 window.onload传统注册事件方式,只能写一次- 如果有多个,会以最后一个
window.onload为准 - 如果使用 addEventListener 则没有限制
1 | document.addEventListener('DOMContentLoaded', function () {}) |
接收两个参数:
- DOMCountentLoaded 事件触发时,仅当 DOM 加载完成,不包括样式表,图片,flash 等等
- 如果页面的图片很多的话, 从用户访问到 onload 触发可能需要较长的时间
- 交互效果就不能实现,必然影响用户的体验,此时用
DOMContentLoaded事件比较合适。
区别
load等页面内容全部加载完毕,包括页面 dom 元素,图片,flash,css 等DOMContentLoaded是 DOM 加载完毕,不包含图片 flash css 等就可以执行,加载速度比 load 更快一些
1 | <script> |
调整窗口大小事件
window.onresize 是调整窗口大小加载事件,当触发时就调用的处理函数
1 | window.onresize = function () {} |
- 只要窗口大小发生像素变化,就会触发这个事件
- 我们经常利用这个事件完成响应式布局。
window.innerWidth当前屏幕的宽度
1 | <body> |
定时器
window 对象给我们提供了两个定时器
setTimeout()setInterval()
setTimeout()定时器
setTimeout()方法用于设置一个定时器,该定时器在定时器到期后执行调用函数。
1 | window.setTimeout(调用函数, [延迟的毫秒数]) |
注意:
window可以省略- 这个调用函数
- 可以直接写函数
- 或者写函数名
- 或者采取字符串 ‘函数名()’ (不推荐)
- 延迟的毫秒数省略默认是 0,如果写,必须是毫秒
- 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符
setTimeout()这个调用函数我们也称为回调函数 callback- 普通函数是按照代码顺序直接调用,而这个函数,需要等待事件,事件到了才会去调用这个函数,因此称为回调函数。
1 | <body> |
clearTimeout()停止定时器
clearTimeout()方法取消了先前通过调用setTimeout()建立的定时器
1 | window.clearTimeout(timeoutID) |
注意:
window可以省略- 里面的参数就是定时器的标识符
1 | <body> |
setInterval()定时器
setInterval()方法重复调用一个函数,每隔这个时间,就去调用一次回调函数
1 | window.setInterval(回调函数, [间隔的毫秒数]) |
window可以省略- 这个回调函数:
- 可以直接写函数
- 或者写函数名
- 或者采取字符 ‘函数名()’
- 第一次执行也是间隔毫秒数之后执行,之后每隔毫秒数就执行一次
1 | <body> |
clearInterval()停止定时器
clearInterval ( )方法取消了先前通过调用setInterval()建立的定时器
注意:
window可以省略- 里面的参数就是定时器的标识符
1 | <body> |
this 指向
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁
现阶段,我们先了解一下几个 this 指向
- 全局作用域或者普通函数中
this指向全局对象window(注意定时器里面的 this 指向 window) - 方法调用中谁调用
this指向谁 - 构造函数中
this指向构造函数实例
1 | <body> |
JS 执行机制
JS 是单线程
- JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为 Javascript 这门脚本语言诞生的使命所致——JavaScript 是为处理页面中用户的交互,以及操作 DOM 而诞生的。比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。
- 单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
一个问题
以下代码执行的结果是什么?
1 | console.log(1) |
那么以下代码执行的结果又是什么?
1 | console.log(1) |
同步和异步
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程
于是,JS 中出现了同步和异步。
同步:
- 前一个任务结束后再执行后一个任务
异步:
- 在做这件事的同时,你还可以去处理其他事情
同步任务
- 同步任务都在主线程上执行,形成一个 执行栈
异步任务
- JS 中的异步是通过回调函数实现的
- 异步任务有以下三种类型
- 普通事件,如
click,resize等 - 资源加载,如
load,error等 - 定时器,包括
setInterval,setTimeout等
- 普通事件,如
- 异步任务相关回调函数添加到任务队列中
- 先执行执行栈中的同步任务
- 异步任务(回调函数)放入任务队列中
- 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行
此时再来看我们刚才的问题:
1 | console.log(1) |
- 执行的结果和顺序为 1、2、3
1 | console.log(1) |
- 执行的结果和顺序为 1、2、3
1 | // 3. 第三个问题 |
同步任务放在执行栈中执行,异步任务由异步进程处理放到任务队列中,执行栈中的任务执行完毕会去任务队列中查看是否有异步任务执行,由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环( event loop)。
location 对象
- window 对象给我们提供了一个
location属性用于获取或者设置窗体的 url,并且可以解析 url。因为这个属性返回的是一个对象,所以我们将这个属性也称为 location 对象。
url
==统一资源定位符(uniform resouce locator)==是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
url 的一般语法格式为:
1 | protocol://host[:port]/path/[?query]#fragment |
| 组成 | 说明 |
|---|---|
| protocol | 通信协议 常用的 http,ftp,maito 等 |
| host | 主机(域名) www.itheima.com |
| port | 端口号,可选 |
| path | 路径 由零或多个'/'符号隔开的字符串 |
| query | 参数 以键值对的形式,通过&符号分隔开来 |
| fragment | 片段 #后面内容 常见于链接 锚点 |
location 对象属性
| location 对象属性 | 返回值 |
|---|---|
| location.href | 获取或者设置整个 URL |
| location.host | 返回主机(域名)www.baidu.com |
| location.port | 返回端口号,如果未写返回空字符串 |
| location.pathname | 返回路径 |
| location.search | 返回参数 |
| location.hash | 返回片段 #后面内容常见于链接 锚点 |
重点记住: href和search
需求:5s 之后跳转页面
1 | <body> |
location 对象方法
| location 对象方法 | 返回值 |
|---|---|
| location.assign() | 跟 href 一样,可以跳转页面(也称为重定向页面) |
| location.replace() | 替换当前页面,因为不记录历史,所以不能后退页面 |
| location.reload() | 重新加载页面,相当于刷新按钮或者 f5 ,如果参数为 true 强制刷新 ctrl+f5 |
1 | <body> |
获取 URL 参数
我们简单写一个登录框,点击登录跳转到 index.html
1 | <body> |
接下来我们写 index.html
1 | <body> |
这样我们就能获取到路径上的 URL 参数
navigator 对象
- navigator 对象包含有关浏览器的信息,它有很多属性
- 我们常用的是
userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值
下面前端代码可以判断用户是用哪个终端打开页面的,如果是用 PC 打开的,我们就跳转到 PC 端的页面,如果是用手机打开的,就跳转到手机端页面
1 | if (navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) { |
history 对象
- window 对象给我们提供了一个 history 对象,与浏览器历史记录进行交互
- 该对象包含用户(在浏览器窗口中)访问过的 URL。
| history 对象方法 | 作用 |
|---|---|
| back() | 可以后退功能 |
| forward() | 前进功能 |
| go(参数) | 前进后退功能,参数如果是 1 前进 1 个页面 如果是 -1 后退 1 个页面 |
1 | <body> |
PC 端网页特效
元素偏移量 offset 系列
offset 概述
offset 翻译过来就是偏移量,我们使用 offset 系列相关属性可以动态的得到该元素的位置(偏移)、大小等。
获得元素距离带有定位父元素的位置
获得元素自身的大小(宽度高度)
注意:返回的数值都不带单位
offset 系列常用属性:
| offset 系列属性 | 作用 |
|---|---|
| element.offsetParent | 返回作为该元素带有定位的父级元素 如果父级都没有定位则返回 body |
| element.offsetTop | 返回元素相对带有定位父元素上方的偏移 |
| element.offsetLeft | 返回元素相对带有定位父元素左边框的偏移 |
| element.offsetWidth | 返回自身包括 padding 、 边框、内容区的宽度,返回数值不带单位 |
| element.offsetHeight | 返回自身包括 padding、边框、内容区的高度,返回数值不带单位 |
element.offsetParent返回带有定位的父元素
element.parentNode返回最近一级的父元素
offset 和 style 区别
元素可视区 client 系列
client 翻译过来就是客户端,我们使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client 系列的相关属性可以动态的得到该元素的边框大小、元素大小等。
| client 系列属性 | 作用 |
|---|---|
| element.clientTop | 返回元素上边框的大小 |
| element.clientLeft | 返回元素左边框的大小 |
| element.clientWidth | 返回自身包括 padding、 内容区的宽度,不含边框,返回数值不带单位 |
| element.clientHeight | 返回自身包括 padding、 内容区的高度,不含边框,返回数值不带单位 |
立即执行函数
(function() {})() 或者 (function() {}())
主要作用:创建了一个独立的作用域。避免了命名冲突问题。
1 | ;(function (a, b) { |
1 | ;(function (a, b) { |
元素滚动 scroll 系列
scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。
| scroll 系列属性 | 作用 |
|---|---|
| element.scrollTop | 返回被卷去的上侧距离,返回数值不带单位 |
| element.scrollLeft | 返回被卷去的左侧距离,返回数值不带单位 |
| element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |
| element.scrollHeight | 返回自身实际的高度,不含边框,返回数值不带单位 |
scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。
页面被卷去的头部
如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。滚动条在滚动时会触发 onscroll 事件。
页面被卷去的头部:可以通过window.pageYOffset获得如果是被卷去的左侧 window.pageXOffset
三大系列总结:
| 三大系列大小对比 | 作用 |
|---|---|
| element.offsetWidth | 返回自身包括 padding 、边框、内容区的宽度,返回数值不带单位 |
| element.clientWidth | 返回自身包括 padding 、内容区的宽度,不含边框,返回数值不带单位 |
| element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |
他们主要用法 ∶
- offset 系列经常用于获得元素位置 offsetLeft offsetTop
- client 经常用于获取元素大小 clientWidth clientHeight
- scroll 经常用于获取滚动距离 scrollTop scrolllLeft
- 注意页面滚动的距离通过 window. pagexoffset 获得
mouseenter 和 mouseover 的区别
mouseenter 鼠标事件
当鼠标移动到元素上时就会触发 mouseenter 事件
类似 mouseover,它们两者之间的差别是
mouseover 鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter 只会经过自身盒子触发
之所以这样,就是因为 mouseenter 不会冒泡
跟 mouseenter 搭配 鼠标离开 mouseleave 同样不会冒泡
动画函数封装
动画实现原理
核心原理 ∶ 通过定时器setInterval()不断移动盒子位置。
实现步骤︰ 1.获得盒子当前位置 2.让盒子在当前位置加上 1 个移动距离 3.利用定时器不断重复这个操作 4.加一个结束定时器的条件 5.注意此元素需要添加定位,才能使用element.style.left
动画函数简单封装
注意函数需要传递 2 个参数,动画对象和移动到的距离。
动画函数给不同元素记录不同定时器
如果多个元素都使用这个动画函数,每次都要 var 声明定时器。我们可以给不同的元素使用不同的定时器(自己专门用自己的定时器)。
核心原理:利用 Js 是一门动态语言,可以很方便的给当前对象添加属性。
缓动效果原理
缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来
思路: 1.让盒子每次移动的距离慢慢变小,速度就会慢慢落下来。 2.核心算法 ∶(目标值-现在的位置)/ 10 做为每次移动的距离步长 3.停止的条件是:让当前盒子位置等于目标位置就停止定时器 4.注意步长值需要取整
动画函数多个目标值之间移动
可以让动画函数从 800 移动到 500。
当我们点击按钮时候,判断步长是正值还是负值 1.如果是正值,则步长往大了取整 2.如果是负值,则步长向小了取整
动画函数添加回调函数
回调函数原理 ∶ 函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调。
回调函数写的位置 ∶ 定时器结束的位置。
动画函数封装到单独 JS 文件里面
因为以后经常使用这个动画函数,可以单独封装到一个 s 文件里面,使用的时候引用这个 s 文件即可。
1.单独新建一个 s 文件.
常见网页特效案例
PC 端轮播图
移动端网页特效
触屏事件
触屏事件概述
移动端浏览器兼容性较好,我们不需要考虑以前 JS 的兼容性问题,可以放心的使用原生 JS 书写效果,但是移动端也有自己独特的地方。比如触屏事件 touch (也称触摸事件),Android 和 IOS 都有。
touch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。
常见的触屏事件如下:
| 触屏 touch 事件 | 说明 |
|---|---|
| touchstart | 手指触摸到一个 DOM 元素时触发 |
| touchmove | 手指在一个 DOM 元素上滑动时触发 |
| touchend | 手指从一个 DOM 元素上移开时触发 |
触摸事件对象(TouchEvent)
TouchEvent 是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等
touchstart、touchmove、touchend 三个事件都会各自有事件对象。触摸事件对象重点我们看三个常见对象列表:
| 触摸列表 | 说明 |
|---|---|
| touches | 正在触摸屏幕的所有手指的一个列表 |
| targetTouches | 正在触摸当前 DOM 元素上的手指的一个列表 |
| changedTouches | 手指状态发生了改变的列表,从无到有,从有到无变化 |
因为平时我们都是给元素注册触摸事件,所以重点记住 targetTocuhes
移动端拖动元素
1.touchstart、touchmove、touchend 可以实现拖动元素 2.但是拖动元素需要当前手指的坐标值我们可以使用targetTouches[0]里面的 pageX 和 pageY 3.移动端拖动的原理:手指移动中,计算出手指移动的距离。然后用盒子原来的位置+手指移动的距离 4.手指移动的距离:手指滑动中的位置减去手指刚开始触摸的位置
拖动元素三步曲 ∶
(1)触摸元素 touchstart:获取手指初始坐标,同时获得盒子原来的位置
(2)移动手指 touchmove :计算手指的滑动距离,并且移动盒子
(3)离开手指 touchend:
注意:手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动e.preventDefault0;
移动端常见特效
移动端轮播图
click 延时解决方案
移动端 click 事件会有 300ms 的延时,原因是移动端屏幕双击会缩放(double tap to zoom)页面。
解决方案:
1.禁用缩放。浏览器禁用默认的双击缩放行为并且去掉 300ms 的点击延迟
1 | <meta name="viewport" content="user-scalable=no" /> |
2.利用 touch 事件自己封装这个事件解决 300ms 延迟。
原理就是︰ 1.当我们手指触摸屏幕,记录当前触摸时间 2.当我们手指离开屏幕,用离开的时间减去触摸的时间 3.如果时间小于 150ms,并且没有滑动过屏幕,那么我们就定义为点击
3.使用插件。fastclick 插件解决 300ms 延迟。
移动端常用开发插件
什么是插件
移动端要求的是快速开发,所以我们经常会借助于一些插件来帮我完成操作,那么什么是插件呢?
JS 插件是 js 文件,它遵循一定规范编写,方便程序展示效果,拥有特定功能且方便调用。如轮播图和瀑布流插件。
特点 ∶ 它一般是为了解决某个问题而专门存在,其功能单一,并且比较小。
我们以前写的 animate.js 也算一个最简单的插件
fastclick 插件解决 300ms 延迟。使用延时
GitHub 官网地址: https://github.com/ftlabs/fastclick
插件的使用
引入 js 插件文件。
Swiper 插件的使用
中文官网地址: https://www.swiper.com.cn/
1.引入插件相关文件 2.按照规定语法使用
其他移动端常见插件
superslide : http://www.superslide2.com/
iscroll : https://github.com/cubiq/iscroll
插件的使用总结
- 确认插件实现的功能
- 去官网查看使用说明
- 下载插件
- 打开 demo 实例文件,查看需要引入的相关文件,并且引入
- 复制 demo 实例文件中的结构 html,样式 css 以及 js 代码
练习-移动端视频插件 zy.media.js
H5 给我们提供了 video 标签,但是浏览器的支持情况不同。
不同的视频格式文件,我们可以通过 source 解决。
但是外观样式,还有暂停,播放,全屏等功能我们只能自己写代码解决。
这个时候我们可以使用插件方式来制作。
移动端常用开发框架
前端常用的框架有 Bootstrap、Vue、Angular、React 等。既能开发 PC 端,也能开发移动端
前端常用的移动端插件有 swiper、superslide、iscroll 等。
Bootstrap
Bootstrap 是一个简洁、直观、强悍的前端开发框架,它让 web 开发更迅速、简单。它能开发 PC 端,也能开发移动端
Bootstrap JS 插件使用步骤:
- 引入相关 js 文件
- 复制 HTML 结构
- 修改对应样式
- 修改相应 S 参数
10、本地存储
本地存储特性
1、数据存储在用户浏览器中
2、设置、读取方便、甚至页面刷新不丢失数据
3、容量较大,sessionStorage 约 5M、localStorage 约 20M
4、只能存储字符串,可以将对象JSON.stringify()编码后存储
window.sessionStorage
1、生命周期为关闭浏览器窗口
2、在同一个窗口(页面)下数据可以共享
3、以键值对的形式存储使用
存储数据
sessionStorage.setltem(key, value)
获取数据
sessionStorage.getItem(key)
删除数据
sessionStorage.removeItem(key)
删除所有数据
sessionStorage.clear()
window.localStorage
1、生命周期永久生效,除非手动删除否则关闭页面也会存在
2、可以多窗口(页面)共享(同一浏览器可以共享)
3.以键值对的形式存储使用
存储数据
localStorage.setItem(key, value)
获取数据
localStorage.getItem(key)
删除数据
localStorage.removeItem(key)
删除所有数据
localStorage.clear()















