WEB API浅学习
什么是API?
- API是一种应用程序编程接口 给前端人员提供的一种工具 以便能完成一些网页效果和功能
- WEB API是浏览器提供的操作浏览器功能和页面元素的API(BOM和DOM)
- API的接口很多都是方法(也就是函数)
什么是DOM
- DOM:文档对象模型(Document Object Model)是一些编程接口,通过DOM接口可以改变网页的内容、结构和样式
什么是DOM树?
- 一个页面就是一个文档 document
- 页面中的标签就是元素 element
- 网页的内容就是节点 node
获取元素的几种方式: ID 标签名 新增方法 特殊元素
getElementByID(id)
获取带有ID的元素集合(ID区分大小写的字符串)
- 它的返回值是element object
console.dir(object);
打印对象的所有属性和属性值
getElementsByTagName('element')
返回带有指定标签名的对象的集合
- 所有的集合都以伪数组的形式存储,如果没找到返回空的伪数组
伪数组概念:
一个对象有了length属性,这个对象就可以成为伪数组,说到底,还是伪数组,只是看起来像数组,有数组的length,也有0123等属性的对象,不能调用数组的内置方法。,伪数组是Object(对象),而真实的数组是Array
元素.getElementsByTagName(标签名')
获取某个父元素内所有指定标签名的子元素,必须指明是哪一个元素对象,获取的时候不包括父元素自身
DEMO:
ul.getElementsByTagName('ul');
console.log(ul[0].getElementsByTagName('li'));
这样必然是很麻烦的,大量的开发场景中不考虑兼容性的话极少用到这个方法,故有了H5新增的方法
H5新增方法:
根据类名返回元素集合
getElementsByClassName('类名');
根据指定选择器返回第一个元素对象(常用)
querySelector('选择器')
根据指定选择器返回元素集合
querySelectorAll('选择器')
DEMO:
let firstbox = document.querySelector('.box');
let firstNav = document.querySelector('#nav');
let firstLi = document.querySelector('li');
let allBox = document.querySelectorAll('div');
...
- 获取特殊元素
拿body
let body = document.body
拿html
let html = document.documentElement
事件基础
事件三要素:
事件源、事件类型、事件处理程序
- 事件源:被触发对象(哪个按钮/选择器名)
- 事件类型:如何触发,什么事件(鼠标点过/鼠标经过…)
- 事件处理程序:通过函数达到想要的效果
执行事件的步骤:
- 获取事件源
- 注册事件/绑定事件
- 添加事件处理程序
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击 |
onmouseover | 鼠标经过 |
onmouseout | 鼠标离开 |
onmousedown | 鼠标按下 |
onmouseup | 鼠标弹起 |
onchange | 状态改变 |
操作元素:
截取从起点到终点的内容,但它剥去html相关的标签、空格,换行
元素.innerText
截取从起点到终点的内容,但它保留html相关的标签、空格,换行
元素.innerHTML
注意点:
- inner只针对普通盒子,不能对表单进行操作
- this指向的是事件函数的调用者
对元素的行内样式进行操作,需要注意的是权重比较高
元素.style.行内样式属性
修改元素的类名
元素.className.类名
新增类名(而不是修改)
元素.classList.add()
删除类名
元素.classList.remove()
- 值得注意的是,这些属性操作采用的都是驼峰命名法
DEMO:
替换盒子的颜色(行内权重比较高)
let box = document.querySelector('div');
box.style.backgroundColor = 'blue';
获取元素的属性值或是自定义属性
元素.getAttribute('属性')
相似:元素.属性 >>> element.type
DEMO:
<div></div>
let box = document.querySelector('div');
box.style.color = 'red';
区别在哪里:
- 元素.属性获取的是内置属性,无法获取自定义属性
- 元素.属性 = ‘值’ 是直接设置内置属性
使用setAttrobite (‘属性’,‘值’)设置属性值或者样式
元素.setAttribute('属性','值')
修改Class样式
元素.setAttribute('class','样式名')
移出属性
元素.removeAttribute('属性或者样式')
H5规定data-属性
这样的属性名都视为自定义属性
如果说getAttribute是兼容性比较好的CSS属性
H5新增了一些好用的自定义属性的方法:
获取元素的自定义属性的集合
元素.dataset
取到精确的单个自定义属性
元素.dataset.index
//或
元素.dataset['index']
- 值得注意的是,这三种不同的取自定义方法只能取到以
data-
开头的且不能以数字开头命名
一些测试Tesk:
- DOMStringMap专门被用来展示自定义元素的接口
div.setAttribute('data', 1);
console.log(div.dataset);
//结果返回空的DOMStringMap{}
div.setAttribute('data-', 1);
console.log(div.dataset);
//结果返回DOMStringMap{"":'1'}
"":"1"
//只写横杠不写自定义名,返回没有名字的值
div.setAttribute('data-list-name', 2);
console.log(div.dataset.listName);
//如果自定义变量中有多个横杠,采用驼峰命名法
学习节点获取元素:
优势在哪?
- 逻辑性强,兼容性较差
- 利用关系获取节点
父子节点
nodeType 类型节点
nodeName 名称节点
nodeValue 值节点
实际开发中元素节点操作应用多
拿到离元素最近的父节点,找不到返回Null
元素.parentNod
拿到子节点的集合,包含文本节点
父节点.childNodes
拿到元素子节点的集合 (常用)
父节点.cheldren
//extre
firstElementchild lastElementchild
firstchild lastchild
//获取第一个/最后一个子节点,IE9以下不支持
//又长又不方便
兄弟节点(开发较少用,会用最后两个就行)
返回元素的下一个兄弟节点 包含文本节点
node.nextSibling //node即是节点的意思
返回元素的上一个兄弟节点 包含文本节点
node.previousSibling
返回元素的下一个兄弟元素节点(低IE不兼容)
node.nextElementSibling
返回元素的上一个兄弟元素节点(低IE不兼容)
node.previousElementSibling
动态创建元素节点:
document.createElement('tag')
从后往前添加节点:
node.appendChild(child)
从前往后添加节点:
node.insertBefore(child, 指定元素)
DEMO:
<ul>
<li>哈哈</li>
</ul>
<script>
let lis = document.createElement('li');
let uls = document.querySelector('ul');
ul.appendChild(lis); //附加在哈哈的后面
ul.insertBefore(lis, ul.children[0]) //附加在哈哈的前面
</script>
添加节点到元素的前面
node.insertBefore(child,指定元素)
删除节点
node.removeChild(child)
复制节点,如果括号参数为空或者false,那判定为浅拷贝,只会复制标签;若括号内参数为true,判定为深拷贝,会复制内容
拷贝和被拷贝的数据会同步
node.cloneNode()
三种创建元素方式:
ducoment.write();
文档流执行完后会导致页面流重绘innerHTML;
拼接多个元素(标签);若直接拼接,速度慢;若采用其字符数组形式拼接,速度快createElement();
创建多个元素(标签),速度中上,结构比较清晰
小补充:使用trim
取出字符串的头尾空格
DOM复习:
1.一般我们都是通过DOM接口改变网页的内容、结构,样式等
2.对于HTML,DOM使得HTML形成一颗DOM数,包含文档、元素,节点
3.通过DOM获取过来的是object,故叫文档对象模型
事件高级
- 学习注册事件的第二种方法(方法监听注册)
老方法具有唯一性,最后注册的处理函数会覆盖前面的注册的函数
使用addEventListener()
实现同一个元素同一个事件可以注册多个监听
事件标签.addEventListener('事件类型',处理函数,[useCapture可选参数])
useCapture:参数为true,视为捕获处理;省略或者为false,视为冒泡处理
值得注意的是:onblur
/focus
/mouseenter
/mouseleave
这些事件没有冒泡
- 解绑事件(删除事件):
- 事件标签.事件类型 = null;
- 事件标签.removeaddEventListener(事件类型,处理函数地址/arguments.callee)
- 事件传播的过程被称为DOM事件流
分为三个阶段:1.捕获 2.当前目标 3.冒泡
事件对象:写在小括号内作为形参,事件对象可以自己命名
addEventListener('click',function(e){})
常用事件对象:
返回触发事件的元素 对比:this返回的是绑定事件的元素
e.target
阻止默认事件(也就是你侦听绑定的事件)
e.prevemtDefault
阻止默认行为
return false
阻止冒泡
e.stopPropagation
事件委托:
与普通事件区别:不是每个子节点单独设置事件监听器,贰而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
白话:给父节点添加侦听器,利用事件冒泡影响每一个子节点
另外,所有的事件委托都不需要加On
常用鼠标事件:
控制应何时显示上下文菜单
contextmenu
开始选中
selectstart
返回距离浏览器窗口x轴的距离
e.clickX
//e.clickY
返回鼠标相当于文档的x距离
e.pageX
//e.pageY
鼠标在元素上移动
mouseove
常用键盘事件:
键盘被松开时触发 默认识别的是大写
onkeyup
键盘被按下时触发
onkeydown
键盘被按下时触发,区分大小写,但不区分功能键
onkeypress
- 值得注意的是keydown和keypress在哇哦恩本狂中,是先触发,再落字的(这就会导致第二次事件才会有处理)
返回按键的ASCII码值(回车键是13)
keycode
BOM学习
浏览器顶级对象:window
- 是JS访问浏览器的接口
- window下声明的全局对象会变成window对象的属性和方法
- 研究浏览器中每一个窗口(window)
学习事件:
DOM加载事件,会等待浏览器窗口的元素都加载完毕才会执行
onload
窗口加载事件 会等待DOM加载完毕,但不包括图、flash、css加载就可以立即执行,有点是速度快
onDOMcontentloaded
获取屏幕的尺寸
resize
//window.innerWidth / innerHeight
学习方法:
延时器
setTimeout(回调函数,延迟的毫秒数)
计时器
setInterval(回到函数,延迟的毫秒数)
清除延时器
clearTimeout
清除定时器
clearInterval
- 异步和同步:
JS的异步通过回调函数实现
异步任务都会放在消息队列中等待执行
异步任务比同步后执行
常见异步行为:
setTimeout
setInterval
时间到了就执行
事件
事件触发了就执行
ajax onreadystatechange
数据返回了执行
–
BOM:location对象
location对象属性 | 返回值 |
---|---|
location.href | 获取或者设置整个URL |
location.host | 返回域名或主机 |
location.port | 返回端口号,没有为空字符串 |
location.pathname | 返回路径 |
location.search | 返回参数 |
location.hash | 返回片段 #后面内容 常见于链接 锚点 |
BOM:location对象方法扩展
location对象方法 | 返回值 |
---|---|
location.assign() | 重定向页面 |
location.replace() | 替换当前页面,无法后退 |
location.reload() | 重新加载页面,括号内跟true强制刷新 |
元素定位方法
offset偏移量,动态获取元素距离带有定位的父元素的位置,或者获取元素自身的大小取值均不带单位
offset系列属性 | 作用 |
---|---|
element.offsetParent | 返回作为该元素带有定位的父级元素,如果都没有定位返回body |
element.offsetTop | 返回元素相对带有定位父元素上方的偏移 |
element.offsetLeft | 返回元素相对带有定位父元素左边框的偏移 |
element.offsetWidth | 返回自身包括padding、边框、内容区的宽度,返回数值不带单位 |
element.offsetHeight | 返回自身包括padding、边框、内容区的高度,返回数值不带单位 |
offset与style的区别
offset
- 可以得到任意样式表中的样式值
- 获得的数值没有单位
- offsetWidth包含padding+border+width
- offsetWidth等属性是只读属性,只能获取不能赋值
- 想要获取元素大小位置,用offset更合适
style
- 只能得到行内样式表中的样式值
- style.width获得的是带有单位的字符串
- style.width获得不包含padding和border的值
- style.width是可读属性,可以获取也可以赋值
- 所以,我们想要给元素更改值,则需要用style改变
offset只读,style可读写
offsetX
/ offsetY
获取鼠标到元素(事件源)的X/Y轴距离
client系列属性 | 作用 |
---|---|
element.clientTop | 返回元素上边框的大小 |
element.clientLeft | 返回元素左边框的大小 |
element.clientWidth | 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位 |
element.clientHeight | 返回自身包括padding、内容区的高度,不含边框,返回数值不带单位 |
scroll系列属性 | 作用 |
---|---|
element.scrollTop | 返回被卷去的上侧距离,返回数值不带单位 |
element.scrollLeft | 返回被卷去的左侧距离,返回数值不带单位 |
element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |
element.scrollHeight | 返回自身实际的高度,不含边框,返回数值不带单位 |
一些拓展:
window.pageYOffset
window.pageXOffset
返回页面被卷去的X / Y轴
document.addEventLestener('scroll', fun)
页面滚动事件
pageshow
页面重新加载事件
mouseenter
鼠标事件,鼠标经过设置的盒子才会触发
mouseover
鼠标事件,鼠标经过以冒泡形式生效
相似的冒泡和经过搭配还有mouseout / mouseleave
change 表单改变值并失去焦点 / input 表单改变值
事件等
移动端事件
触屏touch事件 | 说明 |
---|---|
touchstart | 手指触摸到一个DOM元素时触发 |
touchmove | 手指在DOM元素上滑动时触发 |
touchend | 手指从一个DOM元素上移开时触发 |
触摸列表 | 说明 |
---|---|
touches | 正在触摸屏幕的所有手指的一个列表 |
targetTouches | 正在触摸当前DOM元素上的手指的一个列表 |
changedTouches | 手指状态发生了改变的列表,从无到有,从有到无变化 |
移动端click点击时会有三百毫秒的延迟,有一些解决方案可以参考(because移动端屏幕双击会缩放):
禁用双击缩放
<meta name="viewport" content="user-scaleble=no">
利用touch事件封装解决
本地存储
本地存储特性
1、数据存储在用户浏览器中
2、设置、读取方便、甚至页面刷新不丢失数据
3、容量较大,sessionStorage约5M、localStorage约20M
4、只能存储字符串,可以将对象JSON.stringify()编码后存储
-
sessionStorage是如何存储数据的 有何特性?
生命周期为关闭浏览器
同一个页面下数据可以共享
以键值对的形式存储
值必须是字符串 -
localStorage与sessionStorage有何不同?
生命周期永远存在
同一域名下数据可以共享
增删查改方法:
存储
(session / localStorage).Storage.setItem('键Key',值Value)
拿
(session / localStorage).Storage.getItem('键Key')
删除
(session / localStorage).Storage.removeItem('键Key')
清空
(session / localStorage).Storage.clear()