JSwebAPI
WebApis
web APIs和JS基础关联性
- JS基础阶段及web APIs阶段
- JS基础阶段
- ECMAScript标准规定的基本语法
- web APIs阶段
- W3C标准
- DOM和BOM
- JS基础阶段
- API
应用程序编程接口 - web API
是浏览器提供的一套操作浏览器功能和页面元素的API(DOM和BOM)
一般都有输入和输出(函数的传参和返回值),主要为方法(函数)
DOM
- 概念:
- DOM 树
获取元素
根据ID获取
getElementById()方法获取带有ID的元素对象
ES6规定,可以直接使用元素id,来做元素对象,不需要在获取
- <script>标签要写在页面标签之后
- console.dir 在控制台中显示指定JavaScript对象的属性和方法,并通过类似文件树样式的交互列表显示
<body>
<div id="time">2020-11-16</div>
<script>
//1.因为文档页面从上往下加载,所以先有页面标签
//2.参数 id是大小写敏感的字符串
//3.返回的是一个元素对象
//4.console.dir在控制台中可以显示获取的timer对象的属性和方法
var timer=document.getElementById('time');
console.dir(timer);
</script>
</body>
根据标签名获取
.getElementsByTagName()方法
</script>
<ul>
<li>AAAAAAAA</li>
<li>BB</li>
</ul>
<ul id="nav">
<li>aaaa</li>
</ul>
<script>
//1.返回的是 获取过来元素对象的集合,以伪数组的形式存储的
//2.想要依次打印,遍历伪数组
//3.得到元素对象是动态的
var lis=document.getElementsByTagName('li');
console.log(lis);
for(var i=0;i<lis.length;i++){
console.log(lis[i]);
}
//4.element.getElementsByTagName() 可以得到这个元素里面的某些标签
var nav=document.getElementById('nav');//先选取id为nav的对象
var navLis=nav.getElementsByTagName('li');//再用nav取其中的元素
console.log(navLis);
</script>
通过HTML5新增的方法获取
.getElementsByClassName(),querySelector();
<div class="box">盒子</div>
<div class="box">盒子</div>
<div id="nav">
<ul>
<li>首页</li>
<li>产品</li>
</ul>
</div>
<script>
//1.返回的是 获取过来元素对象的集合,以伪数组的形式存储的
var boxes=document.getElementsByClassName('box');
//2.querySelector 返回指定选择器的第一个元素对象
//3.querySelector 参数要明确选择器的类型,如class对应.类名;id对应#id名
var firstBox=document.querySelector('.box');
var nav=document.querySelector('#nav');
var li=document.querySelector('li');//输出第一个
//4.querySelectorAll 返回指定选择器的所有元素对象集合
var lis=document.querySelector('li');//输出所有的两个
</script>
特殊元素获取
获取body,HTML元素
<script>
//返回body元素对象
var bodyEle=document.body;
console.log(bodyEle);
console.dir(bodyEle);
//返回HTML元素对象
var htmlEle=document.documentElement;
console.log(htmlEle);
console.dir(htmlEle);
</script>
事件基础
事件概述
事件的三部分:事件源 事件类型 事件处理程序
- 事件源:事件被触发的对象,如HTML里的按钮
- 事件类型:如何触发,什么事件 如鼠标点击(onclick),鼠标经过
- 事件处理程序 通过一个函数赋值的方式 完成
<button id="btn">click me!</button>
<script>
var btn=document.getElementById('btn');//选择元素
btn.onclick=function(){
alert('success');
}
</script>
执行事件的步骤
- 获取事件源
- 注册事件(绑定事件)
- 添加事件处理程序(采取函数赋值形式)
常见鼠标事件
操作元素
改变元素内容
元素可以不添加事件
<button>显示当前系统时间</button>
<div>某个时间</div>
<p>1123</p>
<script>
var btn=document.querySelector('button');
var div=document.querySelector('div');
btn.onclick=function(){
div.innerText=getToDay();
}
function getToDay(){
var date= new Date();
var year=date.getFullYear();
var month=date.getMonth()+1;
var dates=date.getDate();
var arr= ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
var day=date.getDay();
var h=date.getHours();
h=h<10?'0'+h:h;
var m=date.getMinutes();
m=m<10?'0'+m:m;
var s=date.getSeconds();
s=s<10?'0'+s:s;
return year+'年'+month+'月'+dates+'日'+' '+arr[day]+h+'时'+m+'分'+s+'秒';
}
//元素可以不用添加事件
var p=document.querySelector('p');
p.innerText=getToDay();
</script>
innerText和innerHTML的区别
- innerText(非标准)
不识别HTML标签,所以用标签修改文字内容样式无效
去除空格和换行 - innerHTML(W3C标准)
识别HTML标签
保留空格和换行
常用元素的属性操作
- innerText和innerHTML
- src、href
- id、alt、title
- 表单元素
<button>按钮</button>
<input type="text" value="输入内容">
<script>
var btn=document.querySelector('button');
var input=document.querySelector('input');
btn.onclick=function(){
input.value='被点击了';
//this指向事件函数的调用者,disabled可以控制表单是否被禁用
this.disabled=true;
}
</script>
- 样式属性操作
- 行内样式
<div id="last"></div>
<script>
var div=document.getElementById('last');
div.onclick=function(){
this.style.backgroundColor='purple';
}
</script>
点击显示密码案例
思路:
核心算法:
利用一个flag变量,通过判断flag值,如果是1,切换为文本框,如果是0,切换为密码框
<style>
.box{
position: relative;
width: 400px;
border-bottom: 1px solid #cccccc;
margin: 100px auto;
}
.box input{
width: 370px;
height: 30px;
border: 0;
outline: none;
}
.box img{
width: 30px;
position: absolute;
/* top: 5px; */
right: 10px;
}
</style>
</head>
<body>
<div class="box">
<label for="">
<img src="images/close.png" alt=""id="eye">
</label>
<input type="password" name="" id="pwd">
</div>
<script>
var eye =document.getElementById('eye');
var pwd=document.getElementById('pwd');
var flag=0;
eye.onclick=function(){
if(flag==0){
pwd.type='text';
eye.src='images/open.png';
flag=1;
}else{
pwd.type='password';
eye.src='images/close.png';
flag=0;
}
}
</script>
</body>
关闭元素案例
思路:
核心算法:
利用样式的显示和隐藏,display:none隐藏;display:block显示
循环精灵图案例
思路:
核心算法:
(1)图片排列有规律(竖着排成一列)
(2)利用for循环修改图片的背景位置
<script>
var lis=document.querySelectorAll('li');
console.log(lis);
for(var i=0;i<lis.length;i++){
var index=i*44;//索引号*44就是位置距离
lis[i].style.backgroundPosition='0 -'+index+'px';//用移动位置的方式,只需要移动Y轴
}
</script>
显示隐藏文本框内容
思路:
核心算法:
(1)焦点事件:onfocus获得焦点;onblur失去焦点
(2)如果获得焦点,判断表单里面内容是否为默认文字,如果是,清空表单内容
(3)如果失去焦点,判断表单是否为空,为空则恢复到默认值
(4)注意文字颜色的转换
<style>
input {
color: #999;
}
</style>
</head>
<body>
<input type="text" value="手机">
<script>
var text = document.querySelector('input');
text.onfocus=function(){
if(this.value=='手机'){
this.value='';
}
this.style.color='#333';
}
text.onblur=function(){
if(this.value==''){
this.value='手机';
this.style.color='#999';
}
}
</script>
- 类名样式
<div id="last" class="first"></div>
<script>
div.onclick=function () {
this.className='change';
//保留原先的类名
this.className='first change';
}
</script>
密码框提示信息错误案例
思路:
核心算法:
(1)首先判断的事件是表单失去焦点 onblur
如果输入正确则提示正确的信息颜色为绿色小图标变化; 如果输入不是6到16位,则提示错误信息颜色为红色 小图标变化
(2)因为里面变化样式较多,我们采取className修改样式
作业
排他思想
利用多层循环将元素组件化
- 所有元素全部清除样式(多层循环)
- 给所选元素设置样式
例子:
<button></button>
<button></button>
<script>
var btns=document.getElementsByTagName('button');
for(var i=0;i<btns.length;i++){
btns[i].onclick=function(){
//先把所有颜色去掉
for(var i=0;i<btns.length;i++){
btns[i].style.backgroundColor='';
}
//再将点击的元素的颜色更换
this.style.backgroundColor='pink';
}
}
</script>
换肤案例:
思路:
核心算法:
(1)给四个图片利用循环注册点击事件
(2)点击图片,页面背景改为当前图片
(3)把所选的图片的src路径取出,给body作为背景
表格隔行换色案例:
思路:
核心算法:
全选取消全选案例:
思路:
核心算法:
自定义属性操作
自定义属性目的:为了保存并使用数据。有些数据可以保存在页面中而不是数据库中
- 获取属性值
区别 | |
---|---|
element.属性 | 获取内置属性值(元素本身自带的属性) |
elemen.getAttribute(‘属性’) | 获得自定义的属性(标准) |
- 设置属性值
区别 | |
---|---|
element.属性=‘值’ | 设置内置属性值(元素本身自带的属性) |
elemen.setAttribute(‘属性’,‘值’) | 设置自定义的属性(标准) |
- 移除属性
element.removeAttribute(‘属性’)
tab切换案例
思路:
核心算法:
H5自定义属性操作
- 设置H5自定义属性
规定自定义属性必须以 data- 开头并且赋值 - 获取H5自定义属性
- 兼容系能够获取用getAttribute方法
- H5新增:element.dataset.属性 或者 element.dataset[‘属性’] ie11才支持(如果直接dataset则会获取到一个集合,包含所有data-开头的自定义属性)
节点操作
获取元素 | 区别 |
---|---|
利用父子兄节点层级关系 | 逻辑性强,兼容性较差 |
利用DOM提供的方法 | 逻辑性不强,繁琐 |
- 节点概述
至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值) 三个属性。
- 节点层级
- 父级节点
node.parentNode
var erweima = document.querySelector('.erweima');
// var box = document.querySelector('.box');
//就近原则,如果找不到则返回null
var box=erweima.parentNode;
- 子节点
(1)parentNode.childNodes(标准),包含所有子节点(元素节点,文本节点等)
(2)parentNode.children(非标准,但是浏览器均支持)
只读属性,返回所有的子元素节点
(3)parentNode.firstchild/lastchild
找不到返回null,包含所有节点
(4)parentNode.firstElementChild/lastElementChild(ie9以上支持)
(5)实际开发中,找子节点的第一个子元素和最后一个子元素
var ol=document.querySelector('ol');
ol.children[0],ol.children[ol.children.length-1]
新浪下拉菜单案例
思路:
核心算法:
- 兄弟节点
node.nextSibling(下一个兄弟节点)
node.previousSibling(上一个兄弟节点)
node.nextElementSibling(下一个兄弟元素节点)
node.previousElementSibling(上一个兄弟元素节点)
兄弟节点解决兼容性,自己封装一个函数
- 创建和添加节点
- 删除节点
简单版留言发布案例
思路:
核心算法:
- 复制节点
动态生成表格案例
思路:
核心思路:
- 三种动态创建元素的区别
动态创建元素 | 区别 |
---|---|
document.write() | 直接将内容写入页面的内容流,但是 如果文档流执行完毕后,调用这个内容会导致页面重新绘制,将原先的内容删除 |
element.innerHTML | 1.将内容写入某个DOM节点,不会导致页面全部重绘 2.创建多个元素效率更高(不用拼接字符串,采取数组形式拼接),结构稍微复杂 |
document.createElement() | 创建多个元素是效率会低一点点,但结构更清晰 |
//innerHTML,耗时为个位数毫秒
var inner=document.querySelector('.inner');
var arr=[];
for(var i=0;i<1000;i++){
arr[i]='<a href="#">百度</a>';
}
inner.innerHTML=arr.join('');
//document.createElement(),耗时平均为20毫秒
var create =document.querySelector('.create');
for(var i=0;i<1000;i++){
var a = document.createElement('a');
create.appendChild(a);
}
事件高级
注册事件(绑定事件)
两种方式:传统方式 和 方法监听注册方式
注册方式 | 区别 |
---|---|
传统注册方式 | 1.利用on开头的事件 2.<button οnclick=“alert(‘hi’)”></button> 3.btn.οnclick=function(){} 4.特点: 注册事件的唯一性 5.同一个元素同一个时间只能设置一个处理函数,最后注册的处理函数覆盖前面的处理函数 |
方法监听注册方式 | 1.W3C标准 2.addEventListener()方法 3.IE9之前的IE不支持,使用attachEvent()代替(非标准) 4.特点:同一个元素同一个事件可以注册多个监听器 5.按注册顺序依次执行 |
- addEventListener 事件监听方式
兼容性解决方案
删除事件(解绑事件)
兼容性解决方案
DOM事件流(重点)
- 事件流描述 的是从页面中接受事件的顺序
- 事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流
<div class="father">
<div class="son">son盒子</div>
</div>
<script>
捕获阶段, 如果addEventListener 第三个参数是true 那么则处于捕获阶段
var son =document.querySelector('.son');
var father =document.querySelector('.father');
处于捕获阶段:document >>> html >>> body >>> father >>> son,从document开始判断,有监听器则进行,无则继续
son.addEventListener('click',function () { alert('son') },true);
father.addEventListener('click',function () { alert('father') },true);
因为按照顺序捕获,所以即使点击的是son的区域块,会先弹出father,在弹出son
冒泡阶段, 如果addEventListener 第三个参数是false或者省略 那么则处于冒泡阶段
var son =document.querySelector('.son');
var father =document.querySelector('.father');
处于冒泡阶段:son >>> father >>> body >>> html >>> document,从son开始判断,有监听器则进行,无则继续
son.addEventListener('click',function () { alert('son') });
father.addEventListener('click',function () { alert('father') });
document.addEventListener('click',function () { alert('document') })
因为按照顺序冒泡,所以点击的是son的区域块,会先弹出son,在弹出father,在弹出document
事件对象(重点)
- 概述
1. event 就是一个事件对象 写到侦听函数的 小括号里面,当形参看
2. 事件对象只有在有了事件才会存在,他是系统自动创建,不需要传递参数
3. 事件对象 是我们事件的一系列相关数据的集合 跟事件相关的
比如鼠标点击里面就包含了鼠标的相关信息(鼠标坐标);
如果是键盘事件里面就包含键盘事件的信息 比如判断用户所按的键
4. 事件对象我们可以自己命名 比如event 、evt、e
5. 事件对象也有兼容性问题,ie678通过window.event 兼容性的写法e=e||window.event
var div=document.querySelector('div');
//div.οnclick=function(event){}
div.addEventListener('click',function (event) {console.log(event); })
-
常见属性和方法
-
e.target
-
e.preventDefault()
阻止冒泡兼容性的方案
事件委托(重点)
事件委托:也成为事件代理,在Jquery里称为事件委派
- 原理
不是每个子节点单独设置事件监听器,而是事件监听器设置在父节点上,然后利用冒泡原理影响设置每个子节点。 - 作用
只操作一次DOM,提高程序性能
常用的鼠标事件
- 鼠标右键菜单contextmenu
- 鼠标选中selectstart
禁用:
document.addEventListener('contextmenu/selectstart',function (e) {
e.preventDefault();
})
- 鼠标事件对象MouseEvent 和 键盘事件对象KeyboardEvent
- MouseEvent
常用的键盘事件
常用的键盘事件对象
1.e.keyCode >>> keyup和keydown按键ASCII码不区分大小写(以大写为准);keypress区分大小写
2.keydown和keypress在文本框的特点:他们两个事件出发的时候,文字还没有落入文本框