Web Api
获取元素的方法
- document.getElementById()
- getElementsByClassName()
- getElementsByTagName()
- getElementsByName()
- querySelector()
- querySelectorAll()
注意事项
getElementById()
只能由document
调用,如果通过其他元素调用会报错,其他方法可由已经获取到的 dom 对象调用querySelector
和getElementById
如果获取不到元素会返回 null;getElementsByClassName
、getElementsByTagName
、getElementsByName
、querySelectorAll
如果没有获取到元素也会返回一个伪数组,只不过伪数组长度为 0
事件
focus
: 获得焦点blur
: 失去焦点click
: 单击dblclick
:双击mouseover/mouseout
: 进入/离开元素mouseenter/mouseleave
: 进入/离开元素mousedown
:按下mouseup
:抬起/释放mousemove
:移动keydown/keypress
:按下keyup
: 释放
属性操作
标签的自定义属性
我们之前讨论的属性,都是 HTML 规范中,标签本来就有的属性,对于标签自定义的一些属性,比较特殊
在 html 页面中,定义一个自定义属性
<div id="box" aa="bb"></div> |
在对应的 DOM 对象中是不存在的,在 DOM 对象中只会存在固定的那些属性
var box = document.getElementById('box') |
attribute 方法
attribute 系列方法用于设置标签的属性,不管是自定义的还是固有的属性
// 获取标签的属性 |
区别 :
// <div a="1" id="box"></div> |
tab 栏案例 (重点)
[案例:获取当前元素的索引]
// 方式1: |
【案例:tab 栏切换】
标签的内容属性
innerText 和 innerHTML
- 共同点 : 都是用来获取和设置标签的内容的
- 区别:
- innerHTML 能够识别标签,标签能够生效
- innerText 只识别文本,标签会被转义
var div = document.getElementById('div') |
浏览器兼容性:指网页在各种浏览器上的显示效果不一致。或者是一些属性和方法在低版本的浏览器中不支持
- innerText 是 IE 提出来的属性,因此低版本的火狐浏览器不支持这个属性。
- 火狐有一个 textContent 属性,效果跟 innerText 一样,但是 IE678 不支持这个属性
书写 innerText 的兼容性代码
function getInnerText(element) { |
行内样式操作(style 属性)
标签不仅可以通过 class 属性操作样式 (嵌套样式),还可以通过 style 属性操作样式 (行内样式)。
同样的 DOM 对象可以通过 className 操作样式 (嵌套样式),也可以通过 style 属性操作样 (行内样式)。
css : 嵌套样式 => js : 类名 div.className = ‘red’
css : 行内样式 => js : style 对象 div.style.color = ‘red’
样式属性
- style 属性是一个对象,里面存储了所有行内样式的键值对
- style 属性只能获取和设置行内样式,嵌套样式通过 style 获取不到
- 如果样式的名字带
-
,比如 background-color ,在 style 对象中使用 backgroundColor => (因为-
在 js 中不是一个合法的标识符) - style 设置的样式是行内样式,优先级要高于通过 className 设置的样式
<div style="color:red;background-color:blue;">哈哈</div> |
var div = document.querySelector('div') |
getComputedStyle 获取元素计算后的样式
语法:
window.getComputedStyle( 获取的元素, 伪类)
伪类 ==> ::after ::before,如果写上了伪类,表示要获取元素的伪类的样式,如果不需要获取的话,该参数写 null
返回值: 返回一个样式对象
var div = document.querySelector('div')
// 获取元素自身的
var ret = window.getComputedStyle(div, null).fontSize
var ret1 = window.getComputedStyle(div, null).backgroundColor
// 推荐:对于复合样式,需要获取什么样式,写具体的样式名,这样能更好的兼容更多浏览器
// 获取伪类的
var ret2 = window.getComputedStyle(div, '::after').width
关于 body 的样式操作
var bd = document.querySelector('body') |
【案例:开关灯案例】
【案例:随机背景颜色案例】
【案例:百度换肤】
关于 cssText (了解)
使用 cssText 可以设置 style 的属性值
<div style="width: 100px; height: 100px">哈哈哈</div> |
节点操作 (超级重要)
节点属性 (了解)
节点分类:
元素节点、文本节点、属性节点、注释节点
节点常用的属性
childNodes : 获取所有的子节点
nodeType: 节点类型:元素节点 = 1 属性-2(过时) 注释-8 文本-3
nodeType 链接-MDN
nodeName: 节点名称
nodeValue: 节点值
节点查找 (重点)
孩子节点
<ul> |
兄弟节点
nextSibling
: 下一个兄弟节点 (基本不常用)nextElementSibling
: 下一个兄弟元素(IE678 不兼容)previousSibling
: 上一个兄弟节点 (基本不常用)previousElementSibling
: 上一个兄弟元素 有兼容性问题 可以封装一个兼容性方法
<p>导航1</p> |
【案例 1:表单校验】
父亲节点
parentNode
: 父节点(没有兼容性问题)parentElement
: 父元素
div.parentNode // 获取父节点 |
添加节点 (重点)
appendChild()
// 作用:在子元素的最后添加一个元素 |
注意 : 如果 newChild 已经存在于 DOM 树中,则它会被从原始位置删除
insertBefore()
// 作用:在某个子元素之前添加一个元素 |
- 必须要父节点来调用,newChild 为需要添加的那个节点,refChild 为添加到哪一个节点的前面
- 没有
insertAfter()
// 将元素添加到最后 |
克隆节点 (重点)
// 语法:var newNode = 节点.cloneNode([isDeep]) |
- 克隆出来的节点跟原来的节点没有关系了,修改了也不会相互影响
- 如果克隆的节点带了 id,我们需要给 id 重新设置一个值,不让 id 冲突
var newNode = div.cloneNode(true) |
创建节点(3 种方式) (重点)
document.write(基本不用)
可以生成新的节点,但是不推荐使用。如果页面已经加载完成了,再用 document.write 写内容的话,会把之前的页面给覆盖掉
原理:页面从上往下加载的时候,会开启一个文档流,当页面加载完,文档流就会关闭。document.write 的本意就是在文档流上写入内容。如果页面没加载完成,文档流还是开着的,document.write 直接在这个文档流上写东西,如果页面加载完成了,还是用 document.write 写东西,会重新开启一个新的文档流,往新的文档流上写东西,旧的文档流就被新的文档流覆盖了。
window.onload = function() { |
innerHTML (偶尔用)
innerHTML 也可以创建节点
使用 innerHTML 创建节点时,如果原来有内容的话,会把原先的内容覆盖
慎用:很容易出现效率问题
div.innerHTML = '<h1>哈哈</h1>' |
createElement (常用)
// 语法:var element = document.createElement('tagName') |
删除节点 (重点)
// 语法:parent.removeChild(child) |
【案例 : 节点操作-删除节点】
1. 使用 children 和 TagName => 需要配合 i-- |
[案例 : 许愿墙案例]
功能1: 克隆10个tip, 并且随机分布 |
替换节点
// 语法: |
注意 : 如果 newChild 已经存在于 DOM 树中,则它会被从原始位置删除
节点操作综合案例
【动态生成表格】
BOM
BOM(Browser Object Model):浏览器对象模型,提供了一套操作浏览器功能的工具
重点 :定时器、 offset 系列
window
- window 对象是一个全局对象,也可以说是 JavaScript 中的顶级对象
- 所有定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法
- 像 document、alert()、console.log() 这些都是 window 的属性,其实 BOM 中基本所有的属性和方法都是 window 的
- window 对象下的属性和方法调用的时候可以省略 window
.onload(掌握)
window.onload 事件会在 窗体加载完成 后执行,通常我们称之为入口函数。
window.onload = function() { |
如果有图片加载,那么代码一定要写到 window.onload 里面,否则会出现图片没有加载完成,获取到的宽度和高度不对的情况。
浏览器会对页面的加载做优化,在加载图片的时候,图片的引入会延迟。
<img src="./01.png" alt=""> |
.open() 与 .close() (了解)
- window.open() 打开一个窗口
// 语法:window.open(url, [name], [features]) |
- window.close() 关闭窗口
newWin.close() // newWin 是刚刚创建的那个窗口 |
延时器与定时器 (重点)
setTimeout 延时器
可以在延迟一定时间后执行指定的代码
设置延时器
// 语法: setTimeOut(callback,time) |
清除延时器
// 语法 : clearTimeOut(timerId) |
setInterval 定时器
setInterval 方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间间隔。 (每隔一段时间执行一段代码)
定时器除非清除,否则会一直执行下去。
设置定时器
// 语法 :var timerId = setInterval(func,dealy) |
清除定时器
// 语法 : clearInterval(intervalId) |
案例
【短信验证码案例.html】
location 对象
location 对象也是 window 的一个属性
location 其实对应的就是浏览器中的地址栏
常用属性和方法
- location.href : 控制地址栏的地址,实现页面跳转
document.onclick = function() { |
[案例 : 注册成功,3 秒后跳转]
页面跳转:
location.href = 'url地址'
location.assign('url地址')
location.replace('url地址')
(不记录历史)
- location.reload() 让页面重新加载
document.onclick = function() { |
location 的其他值
http://www.bbb.com:8080/index.html?id=666&psd=123#xxx
- location.hash //哈希值 其实就是锚点 ==> #xxx
- location.host //服务器 服务器名+端口号 => www.bbb.com:8080
- location.hostname //服务器名 => www.bbb.com
- location.pathname //路径名 => index.html
- location.port //端口 => 8080
- location.protocol //协议 => http
- location.search //参数 => ?id=666&psd=123
其他对象
- history 对象表示页面的历史
// 随便打开一个网页 可以演示 |
- screen 对象
console.log(screen.width) // 屏幕的宽度 |
缓动动画
缓动动画初体验
动画公式 :
var step = (target - current) / 10 |
[案例演示 : ]
1. 三步走 |
缺点 : 打开控制台, 查看盒子的结构行内样式 left, 发现并没有跑到 400px, 只能跑到 396.4/395.5
原因 : offsetLeft 获取值的时候, 只会获取整数 , (对小数部分会四舍五入,整数有时候往上取整,有时候往下取整); 可以在获取的 offset 地方打印查看
缓动动画 - 移动 400 位置
动画公式 :
var step = (target - current) / 10 |
案例演示 注意点 :
1.查看位置 : left有时候为 395.5/ 396.4 |
缓动动画 - 回到 0 点位置
动画公式 :
var step = (target - current) / 10 |
案例演示注意点 :
1. 先把盒子 设置 left : 400px 位置; 回到0位置 |
缓动动画 - 封装函数
function animate(element, target) { |
[案例 : 筋斗云]
[案例:开机提示关闭]
事件对象
事件对象的概述
在触发某个事件的时候,都会产生一个事件对象 Event,这个对象中包含所有与事件相关的一些信息,包括触发事件的元素,事件的类型以及其他与事件相关的信息
鼠标事件触发时,事件对象中会包含鼠标的位置信息。
键盘事件触发时,事件对象中会包含按下的键相关的信息。
获取事件对象
现代浏览器获取 : (掌握)
// 给一个形参即可 |
低版本浏览器 (ie678): (了解)
btn.onclick = function() { |
兼容性 :
btn.onclick = function(e) { |
事件对象的常用属性
事件对象中有很多很多的属性,但是很多属性并不常用。我们经常用到的是鼠标位置信息和键盘码相关的信息
鼠标位置信息
clientX
与clientY
: 相对于浏览器可视区左上角的位置(不随滚动条滚动而改变)pageX
与pageY
:相对于网页内容(文档 document)左上角的位置screenX
与screenY
:相对于屏幕左上角的位置offsetX
与offsetY
:鼠标相对于事件源左上角的位置
document.onmousemove = function(e) { |
[案例 : 拖拽案例]
键盘码
// 键盘按下的那个键的键盘码 |
注册事件的两种方式
on + 事件名称
onclick、onmouseover 这种 on+事件名称的方式注册事件几乎所有的浏览器都支持
// 注册事件 |
on+事件名称注册事件的缺点:同一个元素同一类型的事件,只能注册一个,如果注册了多个,会出现覆盖问题
addEventListener
现代浏览器支持的注册事件的新方式,这种方式注册的事件不会出现覆盖问题
addEventListener 的语法
// type:事件的类型:click mouseover 字符串类型,不带 on |
removeEventListen 的语法
// type:事件的类型 |
低版本浏览器兼容问题: (了解)
IE678 不支持 addEventListener 与 removeEventListen 两个方法,但是支持 attachEvent 与 detachEvnet
attachEvent 的用法:
// type: 事件类型,需要加上on |
detachEvent 的用法:
detachEvent(type, fn) |
兼容性封装(了解)
// 添加事件 |
事件流
事件冒泡
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为冒泡
说白了就是:当我们触发了子元素的某个事件后,父元素对应的事件也会触发
on 创建的事件默认为冒泡,无法修改
[案例 : 弹窗案例]
阻止事件冒泡 e.stopPropagation()
box.onclick = function(e) { |
event.stopImmediatePropagation
阻止事件冒泡并且阻止相同事件的其他侦听器被调用
如果有多个相同类型事件的事件监听函数绑定到同一个元素,当该类型的事件触发时,它们会按照被添加的顺序执行。如果其中某个监听函数执行了 event.stopImmediatePropagation()
方法,则当前元素剩下的监听函数将不会被执行
阻止事件冒泡的兼容性封装
function stopPropagation(e) { |
事件捕获
事件冒泡是 ie 提出来的
路径 : 触发事件的目标元素(son) > you > father > body > document
事件捕获是火狐提出来的
路径 : document > body > father > you > 触发事件的目标元素 (son)
解析 : 事件的处理将从 DOM 层次的根开始,而不是从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递
// 当 addEventListener 第三个参数为 true 时,表示事件捕获 |
事件流的三个阶段
- 事件的捕获阶段
- 事件的目标阶段(触发自己的事件)
- 事件的冒泡阶段
事件有三个阶段 :
- 捕获事件和冒泡事件都存在的话,首先发生的是捕获阶段,然后是目标阶段,最后才是冒泡阶段
- addEventListener 第三个参数为是否捕获
- 如果为 true 时,表示该事件在捕获阶段发生
- 如果为 false 时,表示该事件在冒泡阶段发生
- 某一个事件只会执行一次
三大系列
offset 系列 (重要)
offset 系列用于用于获取元素自身的大小和位置,在 webapi 中有广泛应用
offset 系列主要有:offsetHeight、offsetWidth、offsetParent、offsetLeft、offsetTop
offsetHeight 与 offsetWidth
- 获取元素真实的高度和宽度 (内容大小 + border + padding)(关注盒子本身,不关注盒子内部内容)
- 获取到的是数值类型,方便计算
- offsetHeight 与 offsetWidth 是只读属性,不能设置
style.height 与 style.width
- 只能获取和设置行内样式
- 不包括内边距、边框和外边距
- 获取到的是字符串类型,需要转换
offsetParent
- 获取离当前元素最近的定位父元素(absolute、relative),如果没有,那就找 body
parentNode : 父节点(没有兼容性问题)
parentElement : 父元素
offsetLeft 与 offsetTop
- 获取元素自身与 offsetParent 真实的距离
- 获取到的是数值类型,方便计算
- 只读属性,只能获取,不能设置
style.left 与 style.top
- 只能获取和设置行内样式
- 获取到的是字符串,需要转换
scroll 系列
scroll 系列是用来获取盒子内容的大小和位置
scroll 系列主要有 : scrollWidth、scrollHeight、scrollLeft、scrollTop
scrollWidth 与 scrollHeight
- scrollWidth 与 scrollHeight 是盒子内容的宽度和高度。与盒子大小无关,仅仅与盒子的内容有关系(padding + 内容)
- 如果内容没有溢出,scrollHeight 就是盒子高度 (scrollWidth 同理) => 与 clientHeight、clientWidth 相同
- 如果内容超过盒子,scrollHieght 就是内容高度 (scrollWidth 同理)
scrollTop
- scrollTop 用于获取内容垂直滚动的像素数。如果没有滚动条,那么 scrollTop 值是 0
- 内容超过盒子,盒子设置 overflow: scroll 就可出现滚动条
- 此属性是可读写的
scrollLeft
- scrollLeft 用于获取内容水平滚动的像素数
- 此属性是可读写的
- 浏览器切忌这种出现水平滚动条,用户体验极差,避免
scrollX 与 scrollY
只读属性
scrollY:文档在垂直方向已滚动的像素值
pageYOffset 属性是 scrollY 属性的别名
为了跨浏览器兼容,请使用 window.pageYOffset 代替 window.scrollY
onscroll 事件
对于有滚动条的盒子,可以使用 onscroll 注册滚动事件,每滚动一像素,就会触发该事件
var div = doucment.getElementById('div') |
场景 : 获取页面被卷去的高度和宽度
通常来说,scroll 家族用的最多的地方就是用来获取页面 被卷去的高度,非常的常用
- 对于老式的浏览器,需要获取 html 或者 body 的 scrollTop
- 对于现在浏览器,使用 window.pageYOffset 进行获取
页面被卷去的高度和宽度的兼容性封装
// 给整个页面注册滚动事件 |
[案例 : 固定导航案例]
client 家族
clien t 家族用于获取盒子可视区的大小 (内容 + padding)
client 家族有 clientWidth、clientHeight、clientLeft、clientTop
clientWidth、clientHeight 可视区宽高
clientTop 与 clientLeft 完全没有用,他们就是 borderTop 与 borderLeft
onresize 事件:onresize 事件会在窗口被调整大小的时候发生。
window.onresize = function() { |
场景 : client 系列一般用来获取页面的可视区宽高
低版本浏览器 : 获取的 html 和 body
高版本的浏览器 : window.innerWidth (掌握)(只读属性)
// 因为求的是窗口大小所以用 window |