WebAPI编程
Web APIs
Web APIs 和 JS 基础关联性
JS 的组成:
JS 基础阶段以及 Web APIs 阶段:JS 基础学习 ECMAScript 基础语法为后面作铺垫, Web APIs 是 JS 的应用,大量使用 JS 基础语法做交互效果。
API 和 Web API
API:API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
简单理解: API 是给程序员提供的一种工具,以便能更轻松的实现想要完成的功能。
Web API:Web API 是浏览器提供的一套操作浏览器功能和页面元素的 API ( BOM 和 DOM )。
API 和 Web API 总结
- API 是为我们程序员提供的一个接口,帮助我们实现某种功能
- Web API 主要是针对于浏览器提供的接口,主要针对于浏览器做交互效果。
- Web API 一般都有输入和输出(函数的传参和返回值),Web API 很多都是方法(函数)
- 学习 Web API 可以结合前面学习内置对象方法的思路学习
DOM
DOM 简介
文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口。
W3C 已经定义了一系列的 DOM 接口,通过这些 DOM 接口可以改变网页的内容、结构和样式。
DOM 树:
- 文档:一个页面就是一个文档,DOM 中使用 document 表示
- 元素:页面中的所有标签都是元素,DOM 中使用 element 表示
- 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM 中使用 node 表示
- DOM 把以上内容都看做是对象
获取元素
DOM在我们实际开发中主要用来操作元素。获取页面中的元素可以使用以下几种方式:
- 根据 ID 获取
- 根据标签名获取
- 通过 HTML5 新增的方法获取
- 特殊元素获取
根据 ID 获取
使用 getElementById() 方法可以获取带有 ID 的元素对象。
document.getElementById('id');
使用 console.dir() 可以打印我们获取的元素对象,更好的查看对象里面的属性和方法。
根据标签名获取
使用 getElementsByTagName() 方法可以返回带有指定标签名的对象的集合。
document.getElementsByTagName('标签名');
注意:
- 因为得到的是一个对象的集合,所以我们想要操作里面的元素就需要遍历。
- 得到元素对象是动态的
- 如果获取不到元素,则返回为空的伪数组(因为获取不到对象)
可以获取某个元素(父元素)内部所有指定标签名的子元素:
element.getElementsByTagName('标签名');
注意:父元素必须是单个对象(必须指明是哪一个元素对象). 获取的时候不包括父元素自己。
通过 HTML5 新增的方法获取
- document.getElementsByClassName(‘类名’);// 根据类名返回元素对象集合
- document.querySelector(‘选择器’); // 根据指定选择器返回第一个元素对象
- document.querySelectorAll(‘选择器’); // 根据指定选择器返回
注意:
querySelector 和 querySelectorAll里面的选择器需要加符号,比如:document.querySelector(‘#nav’);
获取特殊元素(body,html)
获取body元素:
- doucumnet.body // 返回body元素对象
获取html元素:
- document.documentElement // 返回html元素对
事件基础
事件概述
JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为。简单理解: 触发— 响应机制。网页中的每个元素都可以产生某些可以触发 JavaScript 的事件,例如,我们可以在用户点击某按钮时产生一个事件,然后去执行某些操作。
事件三要素
- 事件源 (谁)
- 事件类型 (什么事件)
- 事件处理程序 (做啥)
执行事件的步骤
- 获取事件源
- 注册事件(绑定事件)
- 添加事件处理程序(采取函数赋值形式)
常见的鼠标事件
分析事件三要素
下拉菜单三要素
关闭广告三要素
操作元素
JavaScript 的 DOM 操作可以改变网页内容、结构和样式,我们可以利用 DOM 操作元素来改变元素里面的内容 、属性等。
改变元素内容
element.innerText
从起始位置到终止位置的内容, 但它去除 html 标签, 同时空格和换行也会去掉;
element.innerHTML
起始位置到终止位置的全部内容,包括 html 标签,同时保留空格和换行;
常用元素的属性操作
- innerText、innerHTML 改变元素内容
- src、href
- id、alt、title
表单元素的属性操作
利用 DOM 可以操作如下表单元素的属性:
type、value、checked、selected、disabled
样式属性操作
我们可以通过 JS 修改元素的大小、颜色、位置等样式。
- element.style 行内样式操作
- element.className 类名样式操作
注意:
JS 里面的样式采取驼峰命名法 比如 fontSize、 backgroundColor;JS 修改 style 样式操作,产生的是行内样式,CSS 权重比较高;如果样式修改较多,可以采取操作类名方式更改元素样式;class因为是个保留字,因此使用className来操作元素类名属性;className 会直接更改元素的类名,会覆盖原先的类名。
排他思想
如果有同一组元素,我们想要某一个元素实现某种样式, 需要用到循环的排他思想算法:
- 所有元素全部清除样式(干掉其他人)
- 给当前元素设置样式 (留下我自己)
- 注意顺序不能颠倒,首先干掉其他人,再设置自己
自定义属性的操作
获取属性值:
- element.属性 获取属性值。
- element.getAttribute(‘属性’);
区别:
element.属性获取内置属性值(元素本身自带的属性);element.getAttribute(‘属性’); 主要获得自定义的属性(标准)我们程序员自定义的属性。
设置属性值:
- element.属性 = ‘值’ 设置内置属性值。
- element.setAttribute(‘属性’, ‘值’);
区别:element.属性 设置内置属性值;element.setAttribute(‘属性’); 主要设置自定义的属性 (标准)。
移除属性:element.removeAttribute(‘属性’);
H5自定义属性
自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。自定义属性获取是通过getAttribute(‘属性’) 获取。但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。H5给我们新增了自定义属性。
设置H5自定义属性:H5规定自定义属性data-开头做为属性名并且赋值。
获取H5自定义属性:兼容性获取 element.getAttribute(‘data-index’);H5新增 element.dataset.index 或者 element.dataset[‘index’] ie 11才开始支持。
节点操作
获取元素通常使用两种方式: 利用 DOM 提供的方法获取元素和利用节点层级关系获取元素。
利用 DOM 提供的方法:
document.getElementById()
document.getElementsByTagName()
document.querySelector 等
逻辑性不强、繁琐
利用节点层级关系:
利用父子兄节点关系获取元素
逻辑性强, 但是兼容性稍差
节点概述
网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。
HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。
一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
元素节点 nodeType 为 1,属性节点 nodeType 为 2,文本节点 nodeType 为 3 (文本节点包含文字、空格、换行等)。我们在实际开发中,节点操作主要操作的是元素节点。
利用 DOM 树可以把节点划分为不同的层级关系,常见的是父子兄层级关系。
父级节点
node.parentNode
parentNode 属性可返回某节点的父节点,注意是最近的一个父节点。如果指定的节点没有父节点则返回 null。
子节点
- parentNode.childNodes(标准)
parentNode.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的集合。
注意:返回值里面包含了所有的子节点,包括元素节点,文本节点等。
如果只想要获得里面的元素节点,则需要专门处理。 所以我们一般不提倡使用childNodes。
- parentNode.children(非标准)
parentNode.children 是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返
回 。
虽然children 是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用。
- parentNode.firstChild
firstChild 返回第一个子节点,找不到则返回null。同样,也是包含所有的节点。
- parentNode.lastChild
lastChild 返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点。
- parentNode.firstElementChild
firstElementChild 返回第一个子元素节点,找不到则返回null。
- parentNode.lastElementChild
lastElementChild 返回最后一个子元素节点,找不到则返回null。
注意:5、6有兼容性问题,IE9 以上才支持。
实际开发中,firstChild 和 lastChild 包含其他节点,操作不方便,而 firstElementChild 和
lastElementChild 又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢?
解决方案:
- 如果想要第一个子元素节点,可以使用 parentNode.chilren[0]
- 如果想要最后一个子元素节点,可以使用 parentNode.chilren[parentNode.chilren.length - 1]
兄弟节点
- node.nextSibling
nextSibling 返回当前元素的下一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。
- node.previousSibling
previousSibling 返回当前元素上一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。
- node.nextElementSibling
nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回null。
- node.previousElementSibling
previousElementSibling 返回当前元素上一个兄弟节点,找不到则返回null。
注意:3、4有兼容性问题, IE9 以上才支持。
如何解决兼容性问题 ?自己封装一个兼容性的函数:
function getNextElementSibling(element) {
var el = element;
while (el = el.nextSibling) {
if (el.nodeType === 1) {
return el;
}
}
return null;
}
创建节点
document.createElement(‘tagName’)
document.createElement() 方法创建由 tagName 指定的 HTML 元素。因为这些元素原先不存在,
是根据我们的需求动态生成的,所以我们也称为动态创建元素节点。
添加节点
- node.appendChild(child)
node.appendChild() 方法将一个节点添加到指定父节点的子节点列表末尾。类似于 CSS 里面的
after 伪元素。
- node.insertBefore(child, 指定元素)
node.insertBefore() 方法将一个节点添加到父节点的指定子节点前面。类似于 CSS 里面的 before
伪元素。
删除节点
node.removeChild(child)
node.removeChild() 方法从 DOM 中删除一个子节点,返回删除的节点。
复制节点(克隆节点)
node.cloneNode()
node.cloneNode() 方法返回调用该方法的节点的一个副本。也称为克隆节点/拷贝节点。
注意:
- 如果括号参数为空或者为 false ,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点。
- 如果括号参数为 true ,则是深度拷贝,会复制节点本身以及里面所有的子节点。
三种动态创建元素区别
- document.write()
- element.innerHTML
- document.createElement()
区别
- document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
- innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘
- innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
- createElement() 创建多个元素效率稍低一点点,但是结构更清晰
总结:不同浏览器下,innerHTML 效率要比 creatElement 高。
DOM 重点核心
文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言
(HTML或者XML)的标准编程接口。W3C 已经定义了一系列的 DOM 接口,通过这些 DOM 接口可以改变网页的内容、结构和样式。
- 对于JavaScript,为了能够使JavaScript操作HTML,JavaScript就有了一套自己的dom编程接口。
- 对于HTML,dom使得html形成一棵dom树. 包含 文档、元素、节点。
我们获取过来的DOM元素是一个对象(object),所以称为文档对象模型。
关于dom操作,我们主要针对于元素的操作。主要有创建、增、删、改、查、属性操作、事件操作。
创建:
- document.write
- innerHTML
- createElement
增:
- appendChild
- insertBefore
删:
- removeChild
改:主要修改dom的元素属性,dom元素的内容、属性, 表单的值等。
- 修改元素属性: src、href、title等
- 修改普通元素内容: innerHTML 、innerText
- 修改表单元素: value、type、disabled等
- 修改元素样式: style、className
查:主要获取查询dom的元素
- DOM提供的API 方法: getElementById、getElementsByTagName 古老用法 不太推荐
- H5提供的新方法: querySelector、querySelectorAll 提倡
- 利用节点操作获取元素: 父(parentNode)、子(children)、兄(previousElementSibling、
nextElementSibling) 提倡
属性操作:主要针对于自定义属性。
- setAttribute:设置dom的属性值
- getAttribute:得到dom的属性值
- removeAttribute移除属性
事件操作:给元素注册事件, 采取 事件源.事件类型 = 事件处理程序。
事件高级
注册事件(绑定事件)
注册事件概述
给元素添加事件,称为注册事件或者绑定事件。注册事件有两种方式:传统方式和方法监听注册方式。
传统注册方式:利用 on 开头的事件 onclick ;特点: 注册事件的唯一性;同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数。
方法监听注册方式:w3c 标准 推荐方式;addEventListener() 它是一个方法;IE9 之前的 IE 不支持此方法,可使用 attachEvent() 代替;特点:同一个元素同一个事件可以注册多个监听器;按注册顺序依次执行。
addEventListener 事件监听方式
eventTarget.attachEvent(eventNameWithOn, callback)
eventTarget.attachEvent()方法将指定的监听器注册到 eventTarget(目标对象) 上,当该对象触
发指定的事件时,指定的回调函数就会被执行。
该方法接收两个参数:
eventNameWithOn:事件类型字符串,比如 onclick 、onmouseover ,这里要带 on。
callback: 事件处理函数,当目标触发事件时回调函数被调用。
注意:IE8 及早期版本支持。
删除事件(解绑事件)
删除事件的方式
传统注册方式:
eventTarget.onclick = null;
方法监听注册方式:
① eventTarget.removeEventListener(type, listener[, useCapture]);
② eventTarget.detachEvent(eventNameWithOn, callback);
DOM事件流
事件流描述的是从页面中接收事件的顺序。事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即 DOM 事件流。
DOM 事件流分为3个阶段:
- 捕获阶段
- 当前目标阶段
- 冒泡阶段
事件冒泡: IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点的过程。事件捕获: 网景最早提出,由 DOM 最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。
注意:
- JS 代码中只能执行捕获或者冒泡其中的一个阶段。
- onclick 和 attachEvent 只能得到冒泡阶段。
- addEventListener(type, listener[, useCapture])第三个参数如果是 true,表示在事件捕
获阶段调用事件处理程序;如果是 false(不写默认就是false),表示在事件冒泡阶段调用事件处理
程序。 - 实际开发中我们很少使用事件捕获,我们更关注事件冒泡。
- 有些事件是没有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave
事件对象
eventTarget.onclick = function(event) {}
eventTarget.addEventListener('click', function(event) {})
// 这个 event 就是事件对象,我们还喜欢的写成 e 或者 evt
event 对象代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态。简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象event,它有很多属性和方法。
eventTarget.onclick = function(event) {
// 这个 event 就是事件对象,我们还喜欢的写成 e 或者 evt
}
eventTarget.addEventListener('click', function(event) {
// 这个 event 就是事件对象,我们还喜欢的写成 e 或者 evt
})
这个 event 是个形参,系统帮我们设定为事件对象,不需要传递实参过去。当我们注册事件时, event 对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)。
事件对象本身的获取存在兼容问题:
- 标准浏览器中是浏览器给方法传递的参数,只需要定义形参 e 就可以获取到。
- 在 IE6~8 中,浏览器不会给方法传递参数,如果需要的话,需要到 window.event 中获取查找。
解决方法: e = e || window.event;
e.target 和 this 的区别: this 是事件绑定的元素, 这个函数的调用者(绑定这个事件的元素),e.target 是事件触发的元素。
事件对象的常见属性和方法:
阻止事件冒泡
事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点。
阻止事件冒泡:
标准写法:利用事件对象里面的 stopPropagation()方法;
e.stopPropagation()
非标准写法:IE 6-8 利用事件对象 cancelBubble 属性;
e.cancelBubble = true;
事件委托(代理、委派)
事件委托也称为事件代理, 在 jQuery 里面称为事件委派。
事件委托的原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
事件委托的作用:我们只操作了一次 DOM ,提高了程序的性能。
常用的鼠标事件
禁止鼠标右键菜单:
contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单。
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
})
禁止鼠标选中(selectstart 开始选中):
document.addEventListener('selectstart', function(e) {
e.preventDefault();
})
鼠标事件对象:
event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象
MouseEvent 和键盘事件对象 KeyboardEvent。
常用的键盘事件
事件除了使用鼠标触发,还可以使用键盘触发。
注意:
- 如果使用addEventListener 不需要加 on
- onkeypress 和前面2个的区别是,它不识别功能键,比如左右箭头,shift 等。
- 三个事件的执行顺序是: keydown – keypress — keyup
键盘事件对象:
注意: onkeydown 和 onkeyup 不区分字母大小写,onkeypress 区分字母大小写。
在我们实际开发中,我们更多的使用keydown和keyup, 它能识别所有的键(包括功能键);
Keypress 不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值。
BOM 浏览器对象模型
BOM 概述
BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是 window。
BOM 由一系列相关的对象构成,并且每个对象都提供了很多方法与属性。
BOM 缺乏标准,JavaScript 语法的标准化组织是 ECMA,DOM 的标准化组织是 W3C,BOM 最初是Netscape 浏览器标准的一部分。
DOM:
- 文档对象模型
- DOM 就是把「文档」当做一个「对象」来看待
- DOM 的顶级对象是 document
- DOM 主要是操作页面元素
- DOM 是 W3C 标准规范
BOM:
- 浏览器对象模型
- 把「浏览器」当做一个「对象」来看待
- BOM 的顶级对象是 window
- BOM 学习的是浏览器窗口交互的一些对象
- BOM 是浏览器厂商在各自浏览器上定义的,兼容性较差
BOM 的构成:BOM 比 DOM 更大,它包含 DOM。
window 对象是浏览器的顶级对象,它具有双重角色。
- 它是 JS 访问浏览器窗口的一个接口。
- 它是一个全局对象。定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法。
在调用的时候可以省略 window,前面学习的对话框都属于 window 对象方法,如 alert()、prompt() 等。
注意:window下的一个特殊属性 window.name。
window 对象的常见事件
窗口加载事件:
window.onload = function(){}
或者
window.addEventListener("load",function(){});
window.onload 是窗口 (页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS 文件等), 就调用的处理函数。
注意:
- 有了 window.onload 就可以把 JS 代码写到页面元素的上方,因为 onload 是等页面内容全部加载完毕,
再去执行处理函数。 - window.onload 传统注册事件方式 只能写一次,如果有多个,会以最后一个 window.onload 为准。
- 如果使用 addEventListener 则没有限制
document.addEventListener('DOMContentLoaded',function(){})
DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表,图片,flash等等。
Ie9以上才支持。
如果页面的图片很多的话, 从用户访问到onload触发可能需要较长的时间, 交互效果就不能实现,必然影响用户的体验,此时用 DOMContentLoaded 事件比较合适。
调整窗口大小事件:
window.onresize = function(){}
window.addEventListener("resize",function(){});
window.onresize 是调整窗口大小加载事件, 当触发时就调用的处理函数。
注意:
- 只要窗口大小发生像素变化,就会触发这个事件。
- 我们经常利用这个事件完成响应式布局。 window.innerWidth 当前屏幕的宽度
定时器
window 对象给我们提供了 2 个非常好用的方法-定时器:
- setTimeout()
- setInterval()
setTimeout() 定时器:
window.setTimeout(调用函数, [延迟的毫秒数]);
setTimeout() 方法用于设置一个定时器,该定时器在定时器到期后执行调用函数。
注意:
- window 可以省略。
- 这个调用函数可以直接写函数,或者写函数名或者采取字符串‘函数名()'三种形式。第三种不推荐
- 延迟的毫秒数省略默认是 0,如果写,必须是毫秒。
- 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符。
setTimeout() 这个调用函数我们也称为回调函数 callback。普通函数是按照代码顺序直接调用,而这个函数,需要等待时间,时间到了才去调用这个函数,因此称为回调函数。
简单理解: 回调,就是回头调用的意思。上一件事干完,再回头再调用这个函数。
以前我们讲的 element.onclick = function(){} 或者 element.addEventListener(“click”, fn); 里面的 函数也是回调函数。
停止 setTimeout() 定时器:
window.clearTimeout(timeoutID)
clearTimeout()方法取消了先前通过调用 setTimeout() 建立的定时器。
注意:
- window 可以省略。
- 里面的参数就是定时器的标识符 。
setInterval() 定时器:
window.setInterval(回调函数, [间隔的毫秒数]);
setInterval() 方法重复调用一个函数,每隔这个时间,就去调用一次回调函数。第一次执行也是间隔毫秒数之后执行,之后每隔毫秒数就执行一次。
停止 setInterval() 定时器:
window.clearInterval(intervalID);
clearInterval()方法取消了先前通过调用 setInterval()建立的定时器。
this
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,一般情况下this的最终指向的是那个调用它的对象。
- 全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window)
- 方法调用中谁调用this指向谁
- 构造函数中this指向构造函数的实例
JS 执行队列
JS 是单线程,JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是: 如果JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程。于是,JS 中出现了同步和异步。
同步:前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。
异步:你在做一件事情时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情。
他们的本质区别: 这条流水线上各个流程的执行顺序不同。
同步任务:同步任务都在主线程上执行,形成一个执行栈。
异步任务:JS 的异步是通过回调函数实现的。
一般而言,异步任务有以下三种类型:
1、普通事件,如 click、resize 等
2、资源加载,如 load、error 等
3、定时器,包括 setInterval、setTimeout 等
异步任务相关回调函数添加到任务队列中(任务队列也称为消息队列)。
JS 执行机制:
- 先执行执行栈中的同步任务。
- 异步任务(回调函数)放入任务队列中。
- 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环( event loop)。
location 对象
window 对象给我们提供了一个 location 属性用于获取或设置窗体的 URL,并且可以用于解析 URL 。 因为这个属性返回的是一个对象,所以我们将这个属性也称为 location 对象。
URL:
统一资源定位符 (Uniform Resource Locator, URL) 是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
URL 的一般语法格式为:
protocol://host[:port]/path/[?query]#fragment
http://www.itcast.cn/index.html?name=andy&age=18#link
location 对象的属性:
location 对象的方法:
navigator 对象
navigator 对象包含有关浏览器的信息,它有很多属性,我们最常用的是 userAgent,该属性可以返回由客户机发送服务器的 user-agent 头部的值。
下面前端代码可以判断用户那个终端打开页面,实现跳转
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))) {
window.location.href = ""; //手机
} else {
window.location.href = ""; //电脑
}
history 对象
window 对象给我们提供了一个 history 对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的 URL。
history 对象一般在实际开发中比较少用,但是会在一些 OA 办公系统中见到。
PC 端网页特效
元素偏移量 offset 系列
offset 翻译过来就是偏移量, 我们使用 offset 系列相关属性可以动态的得到该元素的位置(偏移)、大小等。
- 获得元素距离带有定位父元素的位置
- 获得元素自身的大小(宽度高度)
- 注意: 返回的数值都不带单位
offset 系列常用属性:
offset 与 style 区别:
offset:offset 可以得到任意样式表中的样式值;offset 系列获得的数值是没有单位的;offsetWidth 包含padding+border+width;offsetWidth 等属性是只读属性,只能获取不能赋值;所以,我们想要获取元素大小位置,用offset更合适。
style:style 只能得到行内样式表中的样式值;style.width 获得的是带有单位的字符串;style.width 获得不包含padding和border 的值;style.width 是可读写属性,可以获取也可以赋值;所以,我们想要给元素更改值,则需要用style改变。
元素可视区 client 系列
scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。
如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。滚动条在滚动时会触发 onscroll 事件。
需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常有如下几种写法:
- 声明了 DTD,使用 document.documentElement.scrollTop
- 未声明 DTD,使用 document.body.scrollTop
- 新方法 window.pageYOffset 和 window.pageXOffset,IE9 开始支持
mouseenter 和mouseover的区别
- 当鼠标移动到元素上时就会触发 mouseenter 事件
- 类似 mouseover,它们两者之间的差别是
- mouseover鼠标经过自身盒子会触发,经过子盒子还会触发。 mouseenter 只会经过自身盒子触发 之所以这样,就是因为mouseenter不会冒泡 跟mouseenter搭配 鼠标离开 mouseleave 同样不会冒泡
动画函数封装
动画实现原理:核心原理:通过定时器 setInterval() 不断移动盒子位置。
实现步骤:
- 获得盒子当前位置
- 让盒子在当前位置加上1个移动距离
- 利用定时器不断重复这个操作
- 加一个结束定时器的条件
- 注意此元素需要添加定位,才能使用element.style.left
动画函数简单封装:
注意函数需要传递2个参数,动画对象和移动到的距离。
动画函数给不同元素记录不同定时器:
如果多个元素都使用这个动画函数,每次都要var 声明定时器。我们可以给不同的元素使用不同的定时器(自己专门用自己的定时器)。核心原理:利用 JS 是一门动态语言,可以很方便的给当前对象添加属性。
缓动效果原理:
缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来。
思路:
- 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来。
- 核心算法: (目标值 - 现在的位置 ) / 10 做为每次移动的距离 步长
- 停止的条件是: 让当前盒子位置等于目标位置就停止定时器
- 注意步长值需要取整
动画函数多个目标值之间移动:
当我们点击按钮时候,判断步长是正值还是负值
- 如果是正值,则步长 往大了取整
- 如果是负值,则步长 向小了取整
动画函数添加回调函数:
回调函数原理:函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调。
回调函数写的位置:定时器结束的位置。
动画函数封装到单独JS文件里面:
因为以后经常使用这个动画函数,可以单独封装到一个JS文件里面,使用的时候引用这个JS文件即可。
- 单独新建一个JS文件。
- HTML文件引入 JS 文件。
节流阀
防止轮播图按钮连续点击造成播放过快。
节流阀目的:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发。
核心实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数。
开始设置一个变量 var flag = true;
If(flag) {flag = false; do something} 关闭水龙头
利用回调函数 动画执行完毕, flag = true 打开水龙头