> 文章列表 > web前端-JS(DOM、BOM)

web前端-JS(DOM、BOM)

web前端-JS(DOM、BOM)

web前端-JS(DOM、BOM)

  • 1. DOM- 操作元素
    • 1.1 获取元素
    • 1.2 事件基础
    • 1.3 操作元素
      • 1.3.1 改变元素的内容
      • 1.3.2 常见元素的属性操作
      • 1.3.3 表单元素的属性操作
      • 1.3.4 样式属性的操作
        • 1.3.4.1 示例:当鼠标点击二维码关闭按钮的时候,则关闭整个二维码。
        • 1.3.4.2 示例: 循环精灵图背景
        • 1.3.4.3 示例:隐藏和显示文本框内容
        • 1.3.4.4 密码框验证信息案例
        • 1.3.4.5 示例: 百度换肤
      • 1.3.5 操作元素总结
      • 1.3.6 自定义属性
        • 1.3.6.1 自定义属性点的操作
        • 1.3.6.2 案例: tab切换按钮
        • 1.3.6.3 H5自定义属性
    • 1.4 节点操作
      • 1.4.1 节点概述
      • 1.4.2 父子节点
      • 1.4.3 兄弟节点
      • 1.4.4 创建和添加节点
      • 1.4.5 删除节点
      • 1.4.6 赋值节点(克隆节点)
      • 1.4.7三种动态创建元素区别
  • 2. DOM- 事件高级
    • 2.1 注册事件
    • 2.2 删除事件
    • 2.3 DOM事件流
    • 2.4 事件对象
      • 2.4.1 事件对象基础
      • 2.4.2 target和this的区别
      • 2.4.3 阻止默认行为
    • 2.5 阻止事件冒泡
    • 2.6 事件委托
    • 2.7 常用的鼠标事件
    • 2.8常用的键盘事件
  • 3. BOM 浏览器对象
    • 3.1 BOM的概述
      • 3.1.1 BOM的基础介绍
      • 3.1.2 BOM的基本构成
    • 3.2 window对象常见事件
      • 3.2.1 窗口加载事件- onload
      • 3.2.2 窗口加载事件-DOMContentLoaded
      • 3.2.3 调整窗口大小的事件-onresize
    • 3.3 定时器
      • 3.3.1 setTimeout()定时器
      • 3.3.2 setInterval()定时器
    • 3.4 this指向问题
    • 3.5 JS中的同步和异步
      • 3.5.1 同步和异步的概念
      • 3.5.2 JS执行机制
      • 3.5.3 事假循环
    • 3.6 location属性
      • 3.6.1 lcoation属性介绍
      • 3.6.2 案例: 获取URL中的参数
    • 3.7 navigator对象
    • 3.8 history对象
  • 4.PC端网页特效
    • 4.1 元素偏移量offset系列
      • 4.1.1 offset的基础属性
      • 4.1.2 offset和style的区别
    • 4.2 元素的可视区client系列
      • 4.2.1 淘宝的flexible.js的源码分析
    • 4.3 元素滚动scroll系列
      • 4.3.1 scroll属性
      • 4.3.2 仿淘宝固定右侧边栏 案例
      • 4.3.3 三大系列的总结
    • 4.4 mouseover和mouseenter的区别
    • 4.5 动画函数封装
      • 4.5.1 简单动画实现原理
      • 4.5.2 缓动动画的原理
      • 4.5.3 缓慢动画添加回调函数
      • 4.5.4 仿京东移动案例
      • 4.5.5 移动端网页特效导读
        • 4.5.5.1 触屏事件
        • 4.5.5.2 触摸事件对象
        • 4.5.5.3 移动端拖动元素
        • 4.5.5.4 移动端常见特效
        • 4.5.5 移动端常用开发插件
        • 4.5.5.6 移动端常用开发框架
    • 4.6 本地存储
      • 4.6.1 Window.sessionStorage
      • 4.6.2 window.locaStorage

web前端-JS(DOM、BOM)

1. DOM- 操作元素

  • DOM:文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可以扩展标记语言(HTML或则XML)的标准编程接口,W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式
  • DOM树:
    web前端-JS(DOM、BOM)
  • 文档:第一个页面就是一个文档,DOM中使用document来表示
  • 元素:页面中的所有标签都是元素,DOM中使用element来表示
  • 节点:网页中的所有内容都是节点(标签、文本、属性、注释等),DOM中使用node来表示
  • 注意:DOM把以上内容都看做是对象

1.1 获取元素

DOM在我们实际开发中主要用来操作元素,那么我们如何获取页面中的元素?我们有如下几种方式获取:根据ID获取、根据标签名获取、通过HTML5新增的方法获取、特殊元素获取

  • getElementById():更具ID获取元素对象
    web前端-JS(DOM、BOM)
  • element.getElementByTagName():返回带有指定标签名的对象的集合需要注意的是返回的一个对象的集合,如果需要操作里面的元素,需要便利,并且该方法得到的元素是动态的
    web前端-JS(DOM、BOM)

注意:该方法获取页面中的元素都是以伪数组的方式返回([])如果没有该标签的元素, 那么返回是一个空的伪数组; 父元素必须是单个对象(必须指明是哪一个元素对象)获取的时候不包括父元素自己;

  • 通过HTML5新增的方法获取
    • document.getElementsByClassName('类名'):更具类名返回元素的对象集合
    • document.querySelector('选择器'):根据指定选择器来发挥第一个元素对象,注意:选择器需带表示,如: .div、#nav
    • document.querySelectorAll('选择器'):根据指定选择器返回所有的元素对象
      web前端-JS(DOM、BOM)
  • 获取特殊元素:
    • document.body:获取body元素
    • document.doucmentElement:获取html对象
      web前端-JS(DOM、BOM)

1.2 事件基础

事件由三部分组成,事件源、事件类型、事件处理程序,我们也称为事件的三要素。
web前端-JS(DOM、BOM)
常见的鼠标事件:
web前端-JS(DOM、BOM)

1.3 操作元素

JavaScript的DOM操作可以改变网页内容、结构和样,我们可以利用DOM操作元素来改变元素里面的内容、属性等。

1.3.1 改变元素的内容

  • element.innerText:从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉
  • element.innerHTML:起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
    web前端-JS(DOM、BOM)
    由上我们可以知道innerText会把元素里面的内容全部替换掉, 包括里面的子元素。上面div中的p元素在点击按钮之后,全部被产生的内容替换掉了,注意: innerText不识别html标签,非标准, 去除空格和换行

web前端-JS(DOM、BOM)
对于innerHTML属性,也会替换标签内所有内容,但是会保留空格和换行,并且能够识别html的标签

**注意:**两个属性都是可读写的, 可以获取元素里面的内容
web前端-JS(DOM、BOM)

1.3.2 常见元素的属性操作

  • src、href
  • id、alt、title
  • 修改src属性,达到修改背景图片的效果
    web前端-JS(DOM、BOM)

1.3.3 表单元素的属性操作

利用DOM可以操作如下表单元素的属性:type、value、checked、selected、disabled

web前端-JS(DOM、BOM)

  • 密码框的隐藏显示
    web前端-JS(DOM、BOM)

1.3.4 样式属性的操作

我们可以通过JS修改元素的大小、颜色、位置等样式。

  • element.style :行内样式操作
  • element.className:类名样式操作
  • 注意:
    • 如果样式修改较多,可以采用操作类名的方式更改元素样式
    • class因为是个保留字,因此使用className来操作元素类名属性
    • className 会直接更改元素的类名, 会覆盖原先的类名

通过style来修改元素样式
web前端-JS(DOM、BOM)

通过className修改元素样式
web前端-JS(DOM、BOM)

1.3.4.1 示例:当鼠标点击二维码关闭按钮的时候,则关闭整个二维码。

web前端-JS(DOM、BOM)
web前端-JS(DOM、BOM)

1.3.4.2 示例: 循环精灵图背景

web前端-JS(DOM、BOM)

1.3.4.3 示例:隐藏和显示文本框内容

web前端-JS(DOM、BOM)

1.3.4.4 密码框验证信息案例

web前端-JS(DOM、BOM)

web前端-JS(DOM、BOM)

web前端-JS(DOM、BOM)

web前端-JS(DOM、BOM)

1.3.4.5 示例: 百度换肤

web前端-JS(DOM、BOM)
web前端-JS(DOM、BOM)

1.3.5 操作元素总结

操作元素是DOM的核心内容:
web前端-JS(DOM、BOM)

1.3.6 自定义属性

1.3.6.1 自定义属性点的操作

  • 获取属性值:
    • element.属性:获取属性值(获取内置属性值,(元素本省自带属性)
    • element.getAttribute('属性')主要获取自定义的属性(标准)我们程序员自定义的属性
  • 设置属性值:
    • element.属性 = ’值‘:设置内置属性的值
    • element.setAttribute('属性','值'),主要是设置自定义属性的值(标准)
  • 移出自定义属性:element.removeAttribute('属性')

web前端-JS(DOM、BOM)

1.3.6.2 案例: tab切换按钮

当鼠标点击秀英的选项卡(tab),下面的内容会跟随内容的变化
web前端-JS(DOM、BOM)

web前端-JS(DOM、BOM)

1.3.6.3 H5自定义属性

自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中
自定义属性获取是通过getAttribute('属性')获取。但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。H5给我们新增了自定义属性:

  • 设置H5自定义属性:H5规定自定义属性data-开头作为属性名并且赋值。
    • 例如<div class="box" data-index="1"></div> , 或则使用JS设置element.setAttribute('data-index',2);
    • 兼容性获取element.getAttribute(data-index);
    • H5新增element.dataset.index或则element.dataset['index'],但是此种方式 ie11才开始支持
      web前端-JS(DOM、BOM)

1.4 节点操作

1.4.1 节点概述

获取元素通常使用两种方式:
web前端-JS(DOM、BOM)
这两种方式都可以获取元素节点,我们后面都会使用,但是节点操作更简单

一般地至少拥有nodeType(节点类型)、nodeName(节点名称)、nodeValue(结点值)这三个基本属性

  • 元素节点的nodeType为1
  • 属性节点nodeType为2
  • 文本节点nodeType为3(文本节点包含文字、空格、换行等
  • 我们在实际开发中,节点操作主要操作的是元素节点

利用DOM树可以吧节点互粉为不同的层级关系,常见的是父子兄层级关系
web前端-JS(DOM、BOM)

1.4.2 父子节点

利用DOM树可以吧节点互粉为不同的层级关系,常见的是父子兄层级关系

  • 父级节点node.parentNode
    • parentNode :属性可返回某节点的父节点,注意是最近的一个父节点
    • 如果指定的结点没有父节点,则返回null
      web前端-JS(DOM、BOM)
  • 子节点:parentNode.childNodes(标准)
    • parentNode.childNodes:返回包含指定结点的子节点的集合,该集合为即时更新的集合
    • 注意:返回值里面包含了所有的子节点,包含元素节点、文本节点等,如果只想要获取里面的元素节点,则需要专门处理,所以我们一般不提倡使用childNodes
      web前端-JS(DOM、BOM)
    • parentNode.children(非标准):是一个只读属性,返回所有的子元素结点,它返回子元素结点。其余结点不返回(这个是我们需要重点掌握的),虽然children是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用
      web前端-JS(DOM、BOM)
  • 结点层级:
    • parentNode.firstChild:返回第一子节点,找不到则返回null,同样也包含所有的结点(不管是元素节点、文本节点都能识别)
    • parentNode.lastChild:返回最后一个子节点,找不到则返回null,同样,也包含所有的结点
    • parentNode.firstElementChild:返回第一个子元素结点,找不到则返回null注意:IE9以上才支持
    • parentNode.lastElementChild:返回最后一个子元素结点,找不到则返回null注意:IE9以上才支持

在实际的开发中,firstChildlastChild包含其它结点,操作不方便,而firstElementChildlastElementChild又有兼容性问题,那么我们如何获取第一个子元素结点或则最后一个子元素结点?

解决方案:如果想要第一个子元素结点,可以使用parentNode.children[0],最后一个结点则可以表示为:parentNode.children[parentNode.children.length-1]
web前端-JS(DOM、BOM)

案例: 下拉菜单
web前端-JS(DOM、BOM)
web前端-JS(DOM、BOM)

1.4.3 兄弟节点

  • node.nextSibling:返回当前元素的下一个兄弟结点,找不到则返回null同样,也包含所有的结点
  • node.previousSibling:返回当前元素上一个兄弟结点,找不到则返回null,同样,也是包含所有的结点
  • node.nextElementSibling:返回当前元素的下一个兄弟元素节点,找不到则返回null(IE9以上才支持
  • node.previousElementSibling:返回当前元素的上一个兄弟元素节点,找不到则返回nullIE9以上才支持

如果解决兼容性问题?可以自己封装一个兼容性函数。
web前端-JS(DOM、BOM)

1.4.4 创建和添加节点

  • document.createElement(‘tagName’):方法创建有tagName指定的HTML元素,因为这些元素原先不存在,是根据我们需求动态生成的,所以我们也称为动态创建元素节点
  • node.appendChild(child):将一个结点添加到置顶父节点的子节点列表末尾。类似于CSS里面的after伪元素
  • insertBefore(child, target):将一个结点添加到某个结点之前
    web前端-JS(DOM、BOM)
    案例 :简单版发布留言案例
    web前端-JS(DOM、BOM)
    web前端-JS(DOM、BOM)

1.4.5 删除节点

  • node.removeChild(child):方法从DOM中删除一个子节点,返回删除的结点
    web前端-JS(DOM、BOM)

案例: 删除留言案例
web前端-JS(DOM、BOM)

1.4.6 赋值节点(克隆节点)

  • node.cloneNode():返回调用该方法的结点的一个副本,也称为克隆结点/拷贝结点
  • 注意:
    • 如果括号参数为空或者为false,则是浅拷贝,即只是克隆赋值结点本身,不克隆里面的子节点
    • 如果括号内的参数为true,则是深度拷贝,会赋值结点本身以及里面所有的子节点

web前端-JS(DOM、BOM)

案例:动态生成表格
web前端-JS(DOM、BOM)
web前端-JS(DOM、BOM)

1.4.7三种动态创建元素区别

  • document.write():是直接将内容写入页面的内容流,但是文档流执行完毕时,则它会导致页面全部重绘
  • element.innerHTML:是讲内容写入某个DOM结点,不会导致页面全部重绘,并且如果是创建多个元素效率更高(不要拼接字符串,才去数组形式拼接)结构稍微复杂
  • createElement():创建多个元素效率稍低一点点,但是结构清晰
  • 总结:不同浏览器下,innerHTML效率要比createElement高

web前端-JS(DOM、BOM)
但是由我测试发现其实差别不是很大,时间几乎是相同的。可能由于课程的时间和本人学习的时间不一致,其中有一些更新。讲课中的时间差距还是蛮大的,但是现在测试发现没有什么差别。

2. DOM- 事件高级

2.1 注册事件

给元素添加事件,称为注册事件或则绑定事件。,注册事件的方式有两种,传统方式和方法监听注册方式
web前端-JS(DOM、BOM)
web前端-JS(DOM、BOM)
注意:传统的注册方式是没有兼容性问题的,但是事件监听的方式,同一个元素,同一个事件可以添加多个监听器

  • eventTarget.addEventListener():将指定的监听器注册到eventTargert(目标对象上)当该对象触发指定时间时,就回执行事件处理函数。(IE9才支持)该方法接收三个参数:
    • type :时间类型字符串,比如click,mouseover。注意这里不要带on
    • listener:事件处理函数,事件发生时,调用该监听函数
    • useCapture:可选参数,是一个布尔值,默认是false,学完DOM事件流后,在进一步学习
      web前端-JS(DOM、BOM)
  • IE9之前是使用eventTarget.attachEvent(eventNameWithOn, callback),该方法是将指定的监听器注册到eventTarget(目标对象上),当该对象触发指定的事件时,指定的回调函数就会被执行.该方法接收两个参数:
    • eventNameWithOn :事件类型字符串,比如onclik、onmouserover,这里要带on
    • callback:事件处理函数,当目标触发事件时回调函数被调用

注册事件兼容性解决方案:(兼容处理的原则,首先照顾大多数浏览器,在处理特殊浏览器

web前端-JS(DOM、BOM)

2.2 删除事件

  • 删除事件的方式:
    • 删除传统注册事件方式: eventTarget.onClick= null
    • 删除方法监听注册方式:eventTarget.removeEventListener(type,listener,[useCapture])eventTarget.detachEvent(eventNameWithOn,calbback)
      web前端-JS(DOM、BOM)

删除事件兼容性解决方案:
web前端-JS(DOM、BOM)

2.3 DOM事件流

  • 事件流:描述的是从页面中接收事件的顺序。事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程DOM事件流

比如我们给一个div注册了点击事件:
web前端-JS(DOM、BOM)

  • 事件冒泡:IE最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层结点的过程

  • 事件捕获:网景最早提出,由DOM最顶层结点开始,然后逐级像下传播到最具体的元素接收过程
    web前端-JS(DOM、BOM)

  • 注意:

    • JS代码中能够执行捕获或则冒泡其中的一个阶段。
    • onclick和attachEvent只能得到冒泡阶段。
    • addEventListener(type,listener,[useCapture])第三个参数如果是true,表示在事件捕获阶段调用时间处理程序;如果是false(不写默认就是false),表示在事件冒泡阶段调用事件处理程序
    • 实际开始中我们很少使用事件捕获,我们更关注事件冒泡
    • 有些事件是没有冒泡的,比如onblur、onfocus、onmouseover、onmouseleave
    • 事件冒泡有时候会带来麻烦,有些又会帮助很巧的做某些事件。后面会进一步学习

捕获阶段: 当我点击son(紫色盒子div)时, 控制台会输出如下打印信息,捕获路径:document->html->body->father->son, document和father也有监听对应的点击事件,所以也会触发
web前端-JS(DOM、BOM)

冒泡阶段:当我的监听方法,没有设置第三个参数时, 表示默认是在冒泡阶段。当我们点击son(紫色div)时,我们可以发现打印结果和上面的捕获阶段的打印结果刚好是相关的。冒泡的顺序:son->father->body->html->document
web前端-JS(DOM、BOM)

2.4 事件对象

2.4.1 事件对象基础

web前端-JS(DOM、BOM)
官方解释:event对象代表事件的状态,比如键盘按键的状态,鼠标的位置、鼠标按钮的状态。
简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象event,它有很多属性和方法

web前端-JS(DOM、BOM)
这个event是个形参,系统帮我们设定为事件对象,不需要传递实参过去。
当我们注册事件时,event对象就会被系统自动创建,并以此传递给事件监听器(事件处理函数)

但是事件对象本身的获取存在兼容性问题:

  1. 在标准浏览器中是浏览器给方法传递的参数,只需要定义形参e就可以获取到。
  2. 在IE6~8中,浏览器不会给方法传递参数,如果需要的话,需要到window.event中获取查找。
  3. 解决:e = e || window.event;

web前端-JS(DOM、BOM)

  • 事件对象是我们事件的一系列先关数据的集合,跟事件相关的,比如鼠标点击里面包含了鼠标的先关信息,鼠标坐标啊,如果是键盘事件里面就包含的键盘事件的信息,比如判断用户按下了哪个键
  • 这个事件对象我们是可以自己命名的,,比如event、e
  • 事件对象的获取也是有兼容性问题的IE678通过window.event

2.4.2 target和this的区别

事件对象的常见属性和方法:
web前端-JS(DOM、BOM)

  • event.target:返回的是触发事件的对象(元素),也就是点击了哪个对象就返回哪个对象
  • this返回的是绑定事件的对象(元素),哪个元素绑定了该事件,就返回哪个元素。
    web前端-JS(DOM、BOM)
    关于兼容性的问题:
    web前端-JS(DOM、BOM)

2.4.3 阻止默认行为

web前端-JS(DOM、BOM)

2.5 阻止事件冒泡

  • 事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到DOM的最顶层结点
  • 事件冒泡的背身的特性,会带来的坏处,也会带来好处,需要我们灵活掌握。
  • 组织冒泡事件的两种方式:
    • 标准写法:利用事件对象里面的stopPropagation()方法
      *非标准写法:IE678利用事件对象的cancelBubble属性

web前端-JS(DOM、BOM)
阻止事件冒泡的的兼容性解决方案:
web前端-JS(DOM、BOM)

2.6 事件委托

  • 事件委托:事件委托也称为事件代理,在jQuery里面被称为事件委派。
  • 事件委托的原理不是每个子节点单独设置事件监听器,而是事件监听器设置在父节点上,然后利用冒泡员那里影响设置每个子节点。 上面案例:给ul注册点击事件,然后利用事件对象的target来找到当前点击的li,因为点击li,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器。
  • 事件委托的作用:我们只操作了一次DOM,提高了程序的性能。
    web前端-JS(DOM、BOM)

2.7 常用的鼠标事件

  • 常用的鼠标事件:
    web前端-JS(DOM、BOM)
  • 进制鼠标右键菜单:contextmenu主要是控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
  • 禁止鼠标选中(selectstart 开始选中)
    web前端-JS(DOM、BOM)
    鼠标事件对象: event对象代表事件的状态,跟事件相关的一系列信息的集合,现在阶段我们主要是用鼠标事件对象MouseEvent和键盘事件对象KeyboardEvent
    web前端-JS(DOM、BOM)
    web前端-JS(DOM、BOM)

2.8常用的键盘事件

事件除了使用鼠标触发,还可以使用键盘触发。
web前端-JS(DOM、BOM)

  • 注意:
    • 如果使用addEventListenter不需要加on
    • onkeypress和前面两个的区别的是,它不识别功能键,比如箭头、shift等
    • 三个事件的执行顺序:keyboard---keypress---keyup
      web前端-JS(DOM、BOM)

键盘事件属性如下:
web前端-JS(DOM、BOM)

  • keyCode:返回该按键的ASCII值
  • key: 返回该按键的内容
  • 注意:onkeydown和onkeyup不区分字母的大小写,onkeypress区分字母的大小写。在我们实际的开发中,我们更过的使用onkeydown和onkeyup,它能识别所有的按键(包括功能键), 而onkeypress不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值
    web前端-JS(DOM、BOM)

案例:模拟京东搜索框(当键盘按下s键的时候,搜索框获得焦点)
web前端-JS(DOM、BOM)

案例:模拟京东快递单号查询案例
要求: 当我们在文本框输入内容时,文本框上面自动显示大号字体的内容
web前端-JS(DOM、BOM)

3. BOM 浏览器对象

3.1 BOM的概述

3.1.1 BOM的基础介绍

BOM(Browser Object Model)即浏览器对象,它提供了独立于内容而与浏览器窗口进行交互对象,其核心对象是window

BOM是由一系列的对象构成,并且每个对象都提供了很多方法与属性。

BOM缺乏标准,JavaScript语法的标准化组织是ECMA,DOM的标准化组织是W3C,BOM最初是Netscape浏览器标准的一部分
web前端-JS(DOM、BOM)

3.1.2 BOM的基本构成

web前端-JS(DOM、BOM)

window对象是浏览器的顶级对象,它具有双重角色

  1. 它是JS访问浏览器窗口的一个接口
  2. 它是一个全局对象,定义在全局作用域中的变量,函数都会变成widnow对象的属性和方法。

在调用的时候可以省略windown,前面学习的对话框都属于window对象方法,如alert(),prompt()等
注意:window下的一个特殊属性window.name

3.2 window对象常见事件

3.2.1 窗口加载事件- onload

web前端-JS(DOM、BOM)
window.onload是窗口(页面)加载事件,当文档内容完全家在完成会触发该事件(包括图像、脚本文件、CSS文件等)

  • 注意:
    • 有了window.onload就可以把JS代码写到页面元素上,因为onload是等页面内容全部加载完毕,在去执行处理函数
    • window.onload传统注册时间方式只能写一次,如果有多规格,会以最后一个window.onlaod为准
    • 如果使用addEventListener则没有限制

web前端-JS(DOM、BOM)
注意:onload函数不会收JS代码位置的影响, 当页面加载完成时, 就会回调这个方法。

3.2.2 窗口加载事件-DOMContentLoaded

web前端-JS(DOM、BOM)
DOMContentLoaded事件被触发时,仅当DOM加载完成时,不包括样式表,图片,flash等等
IE9以上才支持

如果页面的图片很多的话,从用户访问到onlaod触发可能小较长的时间,交互效果不能实现,必然影响用户的体验,此时用DOMContentLoaded事件比价合适。

web前端-JS(DOM、BOM)

3.2.3 调整窗口大小的事件-onresize

web前端-JS(DOM、BOM)
window.onresize:是调整窗口大小加载事件,当触发时就调用的处理函数

  • 注意:
    • 只要窗口大小发生像素变化,就回触发这个事件。
    • 我们经常利用这个事件完成响应式布局。window.innerWidth当前屏幕的宽度
      web前端-JS(DOM、BOM)

3.3 定时器

window对象给我们提供了2个非常好用的方法-定时器setTimeout()setInterval()

3.3.1 setTimeout()定时器

window.setTimer(调用函数,[延迟的毫秒数]):该方法用于设置一个定时器,该定时器在定时器到期后执行调用函数,该定时器是单词执行的。第二个参数如果不传,默认是0 毫秒

web前端-JS(DOM、BOM)
如果页面中有很多个定时器,我们也可以给定时器加标识符(名字)

  • 注意:
    • window可以省略
    • 这个调用函数可以直接写函数,或则写函数名或则采用字符串函数名()三种形式,第三种不推荐
    • 延迟的毫秒数省略默认为0,如果写,必须是毫秒数
    • 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符。
  • window.clearTimeout(timeoutID):取消了先前通过调用setTimeout()建立的定时器,window也是可以省略的

web前端-JS(DOM、BOM)

3.3.2 setInterval()定时器

  • window.setInterval(回调函数,[间隔的毫秒数]):重复调用一个函数,每隔这个时间,就去调用一次回调函数。该定时器会重复回调。
    web前端-JS(DOM、BOM)

  • window.clearInterval(intervalID):取消了先前通过调用setInterval()建立的定时器。
    web前端-JS(DOM、BOM)

3.4 this指向问题

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底是指向谁,一般情况下this的最终指向的是那个调用它的对象

web前端-JS(DOM、BOM)

3.5 JS中的同步和异步

3.5.1 同步和异步的概念

JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事情。这是因为JavaScript这门脚本语言诞生的使用所致–JavaScript是为处理页面中用户的交互,以及操作DOM而诞生的。比如我们对谋而DOM元素进行添加和删除操作,不能同时进行,应该进行添加,之后在删除。

单线程意味着,所有的任务都需要排队,前一个任务结束,才回执行后一个任务。这样所导致的问题是:如果JS的执行时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

以下代码的执行结果是什么?
web前端-JS(DOM、BOM)

为了解决这个问题 ,利用多核CPU的计算能力,HTML5提出Web Worker标准, 允许JavaScript脚本常见多个线程,于是,JS中出现了同步异步

  • 同步:前一个任务结束后在执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。
  • 异步:同事做多件事件。

看下面代码的执行结果:
web前端-JS(DOM、BOM)

3.5.2 JS执行机制

  • 同步任务:同步任务在主线程上执行,形成一个执行栈
  • 异步任务:JS的异步是通过回调函数实现的,一般而言,异步任务有一下三种类型
    • 普通事件,如click、resize
    • 资源加载:如load、error
    • 定时器,包括setInterval、setTimeout

异步任务相关回调函数添加到任务队列中(任务队列也称消息队列)
web前端-JS(DOM、BOM)

web前端-JS(DOM、BOM)

  • 先执行执行栈中的同步任务
  • 异步任务(回调函数)放入任务队列中。
  • 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行
    web前端-JS(DOM、BOM)

3.5.3 事假循环

web前端-JS(DOM、BOM)
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环(event loop)

3.6 location属性

3.6.1 lcoation属性介绍

window对象给我们提供了一个location属性用于获取或设置窗体的URL,并且可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象

  • URL: 统一资源定位符(Uniform Resource Locator, URL)是互联网上标准资源的地址,互联网上的每个文件都有一个唯一的URL,它包含的信息支出文件的位置以及浏览器应该怎么处理它。
    URL的一般语法格式为:
    web前端-JS(DOM、BOM)
    web前端-JS(DOM、BOM)

  • location对象的属性:
    web前端-JS(DOM、BOM)
    注意:这里比较重要的是search、href
    web前端-JS(DOM、BOM)

如何使用JS来实现页面的跳转:
web前端-JS(DOM、BOM)

3.6.2 案例: 获取URL中的参数

  • 案例:获取URL中的参数
    web前端-JS(DOM、BOM)

web前端-JS(DOM、BOM)

  • location对象的方法:
    web前端-JS(DOM、BOM)
    web前端-JS(DOM、BOM)
    web前端-JS(DOM、BOM)

3.7 navigator对象

navigator对象包含有关浏览器的信息,它有很多属性,我们最常用的就是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值

下面前端代码可以判断用户是由哪个终端打开页面,实现跳转
web前端-JS(DOM、BOM)

手机视图中navigator信息:
web前端-JS(DOM、BOM)

pc端navigator信息:
web前端-JS(DOM、BOM)

3.8 history对象

window对象给我们提供了一个history对象,与浏览器历史记录进行交互,该对象包含用户(在浏览器窗口中)
web前端-JS(DOM、BOM)
web前端-JS(DOM、BOM)

web前端-JS(DOM、BOM)

4.PC端网页特效

4.1 元素偏移量offset系列

4.1.1 offset的基础属性

  • offset翻译过来就是偏移量,我们使用offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。
    • 获得元素距离带有定位父元素的位置
    • 获得元素自身的大小(宽度高度)
    • 注意:返回的数据都不带单位

offset的常用属性:
web前端-JS(DOM、BOM)

  • 没有定位父元素的情况:
    web前端-JS(DOM、BOM)

  • 有定位父元素的情况:
    web前端-JS(DOM、BOM)

4.1.2 offset和style的区别

web前端-JS(DOM、BOM)

案例: 获取鼠标在盒子内的坐标
web前端-JS(DOM、BOM)

案例:模态框拖拽
web前端-JS(DOM、BOM)
案例分析如下:
web前端-JS(DOM、BOM)
web前端-JS(DOM、BOM)

案例:仿进洞放大镜效果

4.2 元素的可视区client系列

client翻译过来就是客户度,我们使用client系列相关属性来获取元素可视区域的相关消息。通过client系列的相关属性可以动态的得到该元素的边框大小,元素大小等。

  • element.clientTop:返回元素上边距的大小
  • element.clientLeft:返回元素左边距的大小
  • element.clientWidth:返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位
  • element.clientHeight:返回自身包括padding、内容区的高度,不含边框,返回数值不带单位

web前端-JS(DOM、BOM)

4.2.1 淘宝的flexible.js的源码分析

  • 立即执行函数:(function(){})() 或则 (function(){}())
// 立即执行函数也可以传递参数
(function (a , b){console(a+b);
})(1, 2)

立即执行函数最大的作用是独立创建了一个作用域里面所有的变量都是 局部变量,不会有命名冲突的情况

淘宝的flexible.js分析之核心原理

(function flexible(window, document) {// 获取的html 的根元素var docEl = document.documentElement// dpr 物理像素比var dpr = window.devicePixelRatio || 1// adjust body font size  设置我们body 的字体大小function setBodyFontSize() {// 如果页面中有body 这个元素 就设置body的字体大小if (document.body) {document.body.style.fontSize = (12 * dpr) + 'px'} else {// 如果页面中没有body 这个元素,则等着 我们页面主要的DOM元素加载完毕再去设置body// 的字体大小document.addEventListener('DOMContentLoaded', setBodyFontSize)}}setBodyFontSize();// set 1rem = viewWidth / 10    设置我们html 元素的文字大小function setRemUnit() {var rem = docEl.clientWidth / 10docEl.style.fontSize = rem + 'px'}setRemUnit()// reset rem unit on page resize  当我们页面尺寸大小发生变化的时候,要重新设置下rem 的大小window.addEventListener('resize', setRemUnit)// pageshow 是我们重新加载页面触发的事件window.addEventListener('pageshow', function(e) {// e.persisted 返回的是true 就是说如果这个页面是从缓存取过来的页面,也需要从新计算一下rem 的大小if (e.persisted) {setRemUnit()}})// detect 0.5px supports  有些移动端的浏览器不支持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))

关于flexible.js文件中使用pageshow事件,而不使用load事件?
下面三种情况都会刷新页面触发load事件 :a标签的超链接、F5或则刷新按钮(强制刷新)、前进后退按钮
但是在火狐浏览器中,有个特点,有个往返缓存,这个缓存中不仅保存着页面的数据,还保存着DOMJavaScript的状态;实际上是将整个页面都保存在内存中。所以此时后退按钮是不能刷新页面,也就不能触发load事件。

此时可以使用pageshow事件来触发,这个事件在页面显示时触发,无论页面是否来自缓存。在重新接在页面中,pageshow会在load事件触发后触发,根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件,注意这个事件是给window添加

4.3 元素滚动scroll系列

4.3.1 scroll属性

web前端-JS(DOM、BOM)

scrollHeight:是指真正内容的高度, clientHeight: 指的是盒子的高度

web前端-JS(DOM、BOM)

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

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

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

案例分析

  1. 需要用到页面滚动事件scroll因为是页面滚动,所以事件源是document
  2. 滚动到某个位置,就是判断页面被卷去的上部值
  3. 页面被卷去的头部,可以通过window.pageYOffset获得如果是被卷去的左侧widnow.pageXOffset
    注意:元素被卷去的头部是element.scrollTop,如果是页面被卷去的头部则是window.pageYOffset
    web前端-JS(DOM、BOM)

页面被卷去的头部兼容性解决方案:
需要注意的是页面被卷去的头部,是有兼容性问题的,因此被卷去的头部通常有如下几种写法:

  1. 声明了DTD,使用document.documentElement.scrollTTop
  2. 未声明DTD使用document.body.scrollTop
  3. 新方法:window.pageTOffsetwindow.pageXOffset,IE9开始支持
    web前端-JS(DOM、BOM)

4.3.3 三大系列的总结

web前端-JS(DOM、BOM)

主要使用方法:

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

4.4 mouseover和mouseenter的区别

  • 当鼠标移动到元素上时会触发mouseenter事件
  • 类似mouseover他们两者之间的差别是,mouseover鼠标经过自身盒子会触发,经过子盒子还会触发,而mouseenter只会经过自身盒子触发。之所以这样,就是因为mouseenter不会冒泡,和mouseleave(鼠标离开)一样不会冒泡。但是mouseover是会冒泡的
    web前端-JS(DOM、BOM)

4.5 动画函数封装

4.5.1 简单动画实现原理

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

  • 实现步骤:
    • 获取盒子的当前位置
    • 让盒子在当前位置加上1个移动距离
    • 利用定时器不断重复这个操作
    • 加上一个结束定时器的条件
    • 注意次元素需要添加定位,才能使用element.style.left

注意:必须加上定位,才可以实现,如果没有定位是无法实现动画的

一个简单像右平移的动画:
web前端-JS(DOM、BOM)

但是我们发现,如果我们给多个元素添加动画的时候, 那个需要创建多个定时器,而且每个定时的名称都是一样。 这里管理起来不是很方便。

而且我们使用var来声明变量,每次都会开辟一个空间,但是如果我们给每个元素对象添加一个属性(定时器)赋值的话,是不会开辟新的空间,只是做为一个对象的属性, 而且也解决创建多个相同的定时器的问题。
web前端-JS(DOM、BOM)

但是我们上面代码还有一个小小的问题,有些时候,并不是界面已显示的时候就开始动画, 比如我们添加一个按钮,点击按钮才出发动画,但是当按钮点击之后,标签的速度越来越快。原因:因为生成了很多个定时, 所以当生成一个新的定时器时,需要先取消掉原来的定时器,只保留当前的一个定时器
web前端-JS(DOM、BOM)

4.5.2 缓动动画的原理

缓慢动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来。
思路:

  1. 让盒子每次移动的距离慢慢变小,速度就会慢慢的落下来
  2. 核心算法:(目标值-现在的位置)/ 10作为每次移动的距离步长
  3. 停止的条件是:让当前盒子位置等于目标值就停止定时器
    web前端-JS(DOM、BOM)

注意:动画在多个值之间移动时,如果计算出来的步长是正职,则步长向上取整,否则向下取整

4.5.3 缓慢动画添加回调函数

就是把函数当做一个参数传递进去, 当我们的动画完成时,然后回调函数
web前端-JS(DOM、BOM)

4.5.4 仿京东移动案例

鼠标移动到元素上时
web前端-JS(DOM、BOM)
鼠标离开元素时
web前端-JS(DOM、BOM)
web前端-JS(DOM、BOM)

4.5.5 移动端网页特效导读

4.5.5.1 触屏事件

触屏事件:移动端浏览器兼容性好,我们不需要考虑以前JS的兼容性,可以放心的使用原生JS书写效果,但是移动端也有自己独特的地方,比如触屏事件(touch)(也称触摸事件,Android和IOS都有)。

touch对象代表一个触摸点,触摸点可能是一根手指,也可能是一根触摸笔,触屏事件可响应用户手指(或触控笔)对屏幕或者触控版操作。
web前端-JS(DOM、BOM)
web前端-JS(DOM、BOM)

4.5.5.2 触摸事件对象

TouchEvent是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化事件,这类事件用户描述一个或多个缺点,使开发者可以检测缺点的移动,触点的增加和缺少,等等touchstart、touchmove、touchend三个事件都会各自有事件对象。
触摸事件对象重点我们看三个常见对象列表:
web前端-JS(DOM、BOM)
web前端-JS(DOM、BOM)

4.5.5.3 移动端拖动元素

  1. touchstart、touchmove、touchend可以实现拖动元素
  2. 但是拖动元素需要当前手指的坐标值我们可以使用targetTouches[0]里面的pageXh和pageY
  3. 移动端拖动的原理: 手指移动中,计算出手指移动的距离,然后用盒子原来的位置 + 手指移动的距离
  4. 手指移动的距离: 手指滑动中的位置减去,手指刚开始触摸的位置
  5. 拖动元素三部曲:
    • 触摸元素touchstart:获取手指初始坐标,同时获取盒子原来的位置
    • 移动手指touchmove: 计算手指的滑动距离,并且移动盒子
    • 离开手指touchend:

注意:手指移动也会触发滚动屏幕事件,所以这里需要组织默认的屏幕滚动e.preventDefault()

4.5.5.4 移动端常见特效

  • classList: 属性是HTML5新增的一个属性,返回元素的类名,但是IE10以上版本支持。该属性用于在元素中添加、移出及切换CSS类。有以下方法

web前端-JS(DOM、BOM)

  • classList属性是HTML5新增的一个属性,返回元素的类名,但是IE10以上的版本支持。该属性用于在元素中添加,移除及切换CSS类。
    web前端-JS(DOM、BOM)

  • click延时解决方案:移动端click事件会有300ms的延时,原因是移动端双击缩放(double tap to zoom)页面。

  • 解决方案:

    • 禁用缩放,浏览器禁用默认缩放的双击行为并且去掉300ms的电机延迟。
      web前端-JS(DOM、BOM)
    • 利用Touch事件自己封装这个事件解决300ms延迟。其原理是:当我们手指触摸屏幕时,记录当前的触摸时间,当我们手指离开屏幕时,用离开屏幕的时间减去触摸的时间,如果时间小于150ms,并且没有滑动过屏幕,那么我们就定义为点击。
 //2. 第二种方法我们自己封装定义function tap(obj, callback) {var isMove = false;var startTime = 0; //记录触摸时候的时间变量åobj.addEventListener('touchstart', function() {// 获取手指的触摸时候的时间startTime = Date.now();});obj.addEventListener('touchmove', function (){isMove = true;});obj.addEventListener('touchend', function() {if (!isMove && Date.now() - startTime <= 150) {// 是点击事件,可以回调if (callback != null) {callback();}}// 重置变量isMove = false;startTime = 0;})}
  • 第三种方案是使用插件,fasclick插件解决300ms延迟

4.5.5 移动端常用开发插件

移动端要求是快速开发,所以我们进场会借助于一些插件来帮助我完成操作,那么什么是插件呢?
JS插件是js文件,它遵循一定的规范编写,方便程序展示效果,拥有特定的功能且方便调用,如轮播图和瀑布流插件。

特点:它一般是为了解决某个问题而专门存在的,其功能单一,并且比较小。

fastclick插件解决300ms延时web前端-JS(DOM、BOM)

  • Swiper插件的使用:swiper中官网地址
  • 轮播图其他插件:supersilder、iscroll

那么如果使用插件?

  1. 确认插件实现的功能
  2. 去官网查看使用说明
  3. 下载插件
  4. 打开demo实例文件,产看需要引入相关文件,并且引入
  5. 复制demo实例文件中的结果html,样式css以及js代码

4.5.5.6 移动端常用开发框架

框架,顾名思义就是一套架构,它会基于自身的特点向用户提供一套较为完整的解决方案,框架的控制权在框架本身,使用者要按照框架所规定的某种规范进行开发。

前端常用的框架有Bootstrap、Vue、Angular、Reat等既能开发PC端,也能开发移动端

4.6 本地存储

本地储存的特性:

  1. 数据存储在用户浏览器中
  2. 设置、读取方便、甚至页面刷新不丢失数据
  3. 容量较大,sessionStorage约5M、locaStorage约20M
  4. 只能存储字符串,可以讲对象转换成JSON.stringy()编码后存储

4.6.1 Window.sessionStorage

  • 生命周期为关闭浏览器窗口
  • 在同一个窗口(页面)下数据可以共享
  • 以键值对的形式存储使用
    web前端-JS(DOM、BOM)

4.6.2 window.locaStorage

  • 生命周期永久生效,除非手动删除否则关闭页面也会存在
  • 可以多窗口(页面)共享(同一浏览器中)
  • 以键值对的形式存储使用

web前端-JS(DOM、BOM)