webAPI
web APIs和JavaScript基础关联
JavaScript组成
JavaScript
ECMAScript——JavaScript语法
DOM——页面文档对象模型
BOM——浏览器对象模型
其中DOM和BOM关联到web APIs里
web API阶段
webAPI是w3c组织的标准
web APIs主要学习DOM和BOM
web APIs是js所独有的部分
主要学习页面交互功能
需要学习js的基础课程内容做基础
js学习ECMAScript基础语法为后面做铺垫,Web APIs是js的应用,大量使用js基础语法做交互效果
API和web API
API
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作的制作细节。
简单理解:API是给程序员提供的一种工具,以便简单实现想要完成的功能
web API
Web API是浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM)
MDN详细API:https://developer.mozilla.org/zh-CN/docs/Web/API
API是为我们程序员提供的一个接口,帮助我们实现某种功能,会使用就行,不必纠结内部结构如何实现
Web API主要是针对浏览器提供的接口,主要针对浏览器做交互效果
Web API一般都是有输入和输出的(函数的传参和返回值),WebAPI很多都是方法(函数)
学习WebAPI可以结合前面学习内置对象方法的思路学习
DOM
DOM简介
文档对象模型(Document Object Model) ,是w3c组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口
w3c以经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式
DOM树
文档:一个页面就是一个文档,DOM中使用document表示
元素:页面中的所有标签都是元素,DOM中使用element表示
节点:网页中的所有的内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
DOM把以上内容都看成是对象
获取元素
获取元素的方法:
根据ID获取
根据标签名获取
通过HTML5新增的方法获取
特殊元素获取
根据ID获取元素
使用getElementById()方法可以获取带有ID的元素对象
get——获得
element——元素
by——通过
id是大小写敏感的字符串,为的是id唯一性
返回的是一个匹配了id的DOM的Element对象,若没找到这返回null
var a=document.getElementById(‘a’)//获取了id=a的元素
1var a=document.getElementById('a')//在前面的标签中设置了id=“a”的元素2console.dir(a)//在控制台下显示的是div#a,这就顾名思义了。更好的查看属性和方法根据标签名获取元素
使用getElementsByTagName()方法可以返回带指定标签名的对象的集合
返回的是获取元素对象的集合,以伪数组的形式进行存储的
获取某个元素里面的标签
首先获取该元素
var a=document.getElementById('a'),然后再获取该元素下的子元素:
var li=a.getElementsTayName('span')需要注意的是Element要用复数即Elements,因为获取的标签是多个
xxxxxxxxxx271<ul>2 <li>this is a list</li>3 <li>this is a list</li>4 <li>this is a list</li>5 <li>this is a list</li>6 <li>this is a list</li>7</ul>8<ul id="a">9 <i>this my love</i>10 <i>this my love</i>11 <i>this my love</i>12 <i>this my love</i>13 <i>this my love</i>14</ul>15<script>16 var lis = document.getElementsByTagName('li')//获取整个页面的<li>标签17 console.log(lis)18 console.log(lis[0])//这样可以只打印第一个li标签19 for(var i=0;i<lis.length;i++){20 console.log(lis[i])//对数组进行遍历,这样就能够渲染出数组内容了21 }22</script>23<script>24 var ul=document.getElementsById('a')//获取<ul id="a">下的<li>标签25 var lis= ul.getElementsByTagName('li')//获取id='a'元素下的所有li标签26 console.log(lis)27</script>根据类名获取元素(HTML5新增的方法)
这个是HTML5新增的方法,目前情况来说具有兼容性问题
使用document.getElementsByClassName(‘classname’)
这个的用法和通过标签名对元素进行选择是一样的用法,这里不过多介绍
直接选择对应的标签(HTML5新增方法)
使用querySelector(中文翻译名为查询选择)——document.querySelector()
querySelector返回的是选择器的第一个元素对象,切记里面的选择器需要加符号,只能选择在页面中从上到下的第一个发现得元素对象
querySelectorAll()选择所有在页面中出现的指定元素标签
可以进行循环遍历渲染具体的文本内容
如若不考虑兼容性推荐使用此方法
xxxxxxxxxx301<div class="box">2 this is by class name3</div>4<div class="box">5 this is by class name6</div>7<div class="box">8 this is by class name9</div>10<div class="box">11 this is by class name12</div>13<div class="box">14 this is by class name15</div>16<div class="box">17 this is by class name18</div>19<div id="a">20 this is by id name21</div>22<span>23 this is by tay name24</span>25<script>26 var box=document.querySelector('.box')//只选择第一个出现的类名为box的元素标签27 var boxs=document.querySelectorAll('.box')//选择页面中所有类名是box的元素,以伪数组进行存储28 var bo=document.querySelector('#a')29 var span=document.querySelector('span')30</script>获取特殊元素
获取body标签
方法:
var body=document.body
获取html标签
方法:
var html=document.documentElement
html标签比较特殊
事件基础
JavaScript使我们有能力创建动态页面,而事件是可以被JavaScript侦察到的行为
简单理解:触发——>响应机制
网页中的每一个元素都可以产生某些可以触发的JavaScript事件,例如点击某个按钮时产生一个事件,然后执行某些操作
事件是由三部分组成:(事件三要素)
事件源——事件被触发的对象
事件类型——如何触发 什么事件 比如鼠标点击(onclick) 还是鼠标经过触发 还是键盘按下触发
事件处理程序——是通过一个函数赋值的方式
xxxxxxxxxx91<button id="bu">2 3</button>4<script>5 var but=document.getElementById('bu')6 but.onclick = function(){7 alert('this is a onclick')8 }9</script>执行事件的步骤:
获取事件
注册事件(绑定事件)
添加事件处理程序(采取函数赋值形式)
操作元素
JavaScript的DOM操作可以改变网页的内容、结构和样式,我们可以利用DOM操作元素来改变元素里面的内容,属性等
改变元素内容
element.innerText
从起始位置到终止位置的内容,但它去除了html标签,同时空格和换行也会被换掉
element.innerHTML
起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
表单元素的属性操作
利用DOM可操作如下表单元素的属性
type 、value、checked、selected、disabled
xxxxxxxxxx131<button>2 enter3</button>4<input type="text" value="please input content">5<script>6var but=document.querySelector('button')7var inp=document.querySelector('input')8but.onclick=function(){9 inp.value="this is a input"10 but.disabled=true//点击按钮后按钮被禁用了11 this.disabled=true//也可以使用这种方式来禁用按钮,this指向的是事件函数的调用者,这里指向button12}13</script>案例:密码隐藏和现实切换
x1<!--这里主要介绍js部分的编码-->2<script>3var but=document.getElementById('but')4var ic=document.getElementById('i')5var pas=document.getElementById('passww')6var flag=07but.onclick=function(){8 if(flag==0){9 ic.innerHTML = ""10 pas.type = "text"11 flag=112 }else{13 flag = 0/* 利用变量一正一反来进行判断 */14 ic.innerHTML = ""15 pas.type = "password"16 }17
18}19
20</script>案例:循环精灵图
首先精灵图排列要有规律的——每个小图片的坐标是索引号乘于小图片间的距离(索引从0开始)
核心思路利用for循环修改精灵提的背景图片位置background-position
xxxxxxxxxx61<script>2var lis=document.querySlectorAll('li')3for(var i=0;i<lis.length;i++){4 lis[i].style.backgroundPosition="i -(i*44)"5}6</script>操作元素总结:
排他思想
利用for循环绑定事件
xxxxxxxxxx201<body>2 <button>1</button>3 <button>2</button>4 <button>3</button>5 <button>4</button>6 <button>5</button>7</body>8<script>9 //获取按钮元素10 var btns=document.getElementsByTayName('button');11 for(var i=0;i<btns.length;i++){12 btns[i].onclick=function(){//利用循环给每个按钮添加一个点击事件13 //先将当前按钮的样式重置,点击的时候再添加上新的样式14 for(var i=-;i<btns.length;i++){15 btns[i].style.backgroundColor="none"16 }//然后在修改新的样式17 this.style.backgroundColor="pink"//this获取点击的对象18 }19 }20</script>自定义属性的操作
element.属性:获取属性值
element.getAttribute(‘属性’)
区别:
element.属性 获取内置属性值(元素本身自带的属性)
element.getAttribute(‘属性’);主要获取自定义的属性(标准)我们程序员自定义的属性
设置属性值
element.属性=“值” 设置内置属性值
element.setAttribute(‘属性’,‘值’),主要针对于自定义属性
移除属性值
element.removeAttribute(‘属性’)
节点操作
获取元素的两种方法:
一、利用DOM提供方法获取元素
document.getElementByI()
document.getElementsByTagName()
document.querySelector等
但是有个缺点——逻辑性不佳,操作繁琐
二、利用节点的层次关系获取元素
利用父子兄节点的关系获取元素
逻辑性强,但兼容性差
节点概述
网页中所有的内容都是节点(标签,属性,文本,注释等),在DOM中,节点使用node来表示
HTML DOM树中的所有节点均可通过JavaScript进行访问,所有HTML元素(节点),均可被修改,也可以创建和删除
一般的,节点至少拥有nodeType(节点类型),nodeName(节点名称)和nodeValue(节点值)这三个基本属性
元素节点nodeType为1
属性节点nodeType为2
文本节点nodeType为3(节点文本包含文字,空格,换行等)
在实际开发中,节点操作主要操作的是元素节点
节点层级
利用DOM数可以把节点划分为不同层级的关系,常见的是父子兄层级关系
父级节点
node.parentNode
xxxxxxxxxx91<div id="a">2 <div id="b">3 4 </div>5</div>6<script>7 var b=document.getElemntById('b')8 b.parentNode//这样就可以直接获取父节点了,即id=a的div这元素,如果找不到父节点就返回空null9</script>parentNode属性可以返回某节点的父节点注意是最近的那个父节点
如果指定的父节点没找到就返回null
子节点
childNodes(标准)
xxxxxxxxxx101<ul id="ul">2 <li></li>3 <li></li>4 <li></li>5 <li></li>6</ul>7<script>8 var a=document.getElementById('ul')9 console.log(a.childNodes)//直接获取ul下的所有子节点10</script>获得的childNodes包括了换行、空格、文本等节点
如果想要获取里面的元素节点,则需要专门处理,所以一般不提倡使用childNodes
xxxxxxxxxx81<script>2 var a=document.gerElementById('a')3 for(var i=0;i<a.childNodes.length;i++){4 if(a.childNodes[i].npdeType==1){5 //a.childNodes[i]是元素节点6 }7 }8</script>parentNode.children(非标准)
可以获取到父节点下的所有子元素节点
parentNode.children是一个只读属性,返回所有的子元素节点,它只返回子元素节点,其余节点不返回,虽然children是一个非标准,但是得到了各个浏览器的支持,可以放心使用
若想获取指定的节点可以使用数组索引
a.children[0]
parentNode.firstChild
获取第一个子节点
parentBNode.firstElemntChild
获取第一个元素子节点——有兼容性问题
parentNode.lastChild
获取最后一个子节点
parentNode.lastElementChild
获取最后一个元素子节点——有兼容性问题
兄弟节点
node.nextSibling——
下一个兄弟节点(包含元素、文本等节点)
node.nextElementSibling——
下一个元素兄弟节点
node.previousSibling——
上一个兄弟节点(包含元素、文本等节点)
node.previousElementSibling——
上一个元素兄弟节点
创建节点
document.createElement('tagName')——创建节点
document.createElement()方法创建由tagName指定的HTML元素,因为这些元素原先是不存在的,是根据我们的需求动态生成的,所以我们也称之为动态创建元素节点
xxxxxxxxxx31<script>2var li = document.createElement('li')//创建了一个3</script>添加节点
node.appendChild(Child)——创建节点
node.appendChild()方法是将一个节点添加到指定父节点的子节点列表末端,类似于css里面的伪元素after
xxxxxxxxxx81<ul>2 3</ul>4<script>5var li = document.createElement('li')//创建了一个节点6var ul=document.querySelector('ul')7ul.appendChild(li)//这样就在ul里面添加了一个li元素8</script>node.insertBefore(child,指定元素)——在指定子元素的前面添加一个元素
xxxxxxxxxx101<ul>2 <li>123</li>3</ul>4<script>5var li = document.createElement('li')//创建了一个节点6var ul=document.querySelector('ul')7ul.appendChild(li)//这样就在ul里面添加了一个li元素8 var div=document.createElement('div')9 ul.insertBefore(div,ul.children[0])//在ul里的li-123里面添加了一个div元素10</script>想要在页面中添加某个元素需要 两步
创建元素
添加元素
删除节点
node.removeChild(child)
node.removeChild()方法从DOM中删除一个子节点,返回删除的节点
xxxxxxxxxx151<ul>2 <li>1</li>3 <li>2</li>4 <li>3</li>5</ul>6<button>delete</button>7<script>8 var ul=document.querySelector('ul')9 //ul.removeChild(ul.children[0])10 //删除了ul里的第一个li节点11 var but=document.querySelector('button')12 but.onclick=function(){13 ul.removeChild(ul.children[0])//没点击一次按钮就删除ul里的第一个li节点14 }15</script>复制节点(克隆节点)
node.cloneNode
node.cloneNode()方法返回调用该方法的节点的一个副本,也称为克隆节点/拷贝节点
xxxxxxxxxx121<ul>2 <li>1</li>3 <li>2</li>4 <li>3</li>5</ul>6<script>7 var ul=document.querySelector('ul')8var li= ul.children[0].node.cloneNode()//括号为空或者里面是false浅拷贝,只复制标签不复制内容9var li=ul.children[0].node.cloneNode(ture)//深拷贝,复制标签10ul.appendChild(li)//添加节点11</script>12
案例:动态创建单元格
xxxxxxxxxx301<table>2
3</table>4<script>5 var datas=[{6 name;"jack",7 subject:"javaScript",8 score;989 },{10 name:"Lili",11 subject:"javaScript",12 score:9613 },{14 name:"Mack",15 subject:"javaScript",16 score:8917 }]18var tbody=document.querySelector('table') 19for(var i=0;i<datas.length;i++){20 var tr=document.createElement('tr')21 tbody.appendChild(tr)22 for(var k in datas[i]){//遍历对象23 var td=document.createElement('td')24 tr.appendChild(td)//创建单元格25 //把对象里面的属性值给到td26 //datas[i][k]得到属性值27 td.innerHTML=datas[i][k]//单元格的到对象属性值28 }29}30</script>三种创建元素方式的区别
document.write()
element.innerHTML
document.createElement()
区别:
document.write是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
innerHTML创建多个元素通过拼接字符串创建元素耗时较长,innerHTML在创建多个元素时效率会更高(不要拼接字符串,采取数组形式进行拼接),结构稍微复杂,innerHTML是将内容写入某个元素DOM节点,不会导致页面全部重绘
document.createElement()创建元素时消耗时间叫短,不是通过拼接字符串进行创建元素
createElement()创建多个元素效率会稍微低一些,但结构清晰
不同浏览器下innerHTML的效率会更高
DOM核心
文档对象模型,是W3C组织推荐的处理可扩展标记语言的标准编程接口
W3C已经定义了一系列的DOM接口,通过这些接口可以改变网页内容、结构和样式
对于JavaScript为了能够是JavaScript操作HTML、JavaScript就有了一套自己的dom 编程接口
对于HTML、dom使得html形成一颗DOM树,包含元素、文档、节点
通过获取过来的DOM元素是一个对象,所以称之为文档对象模型
关于DOM操作我们主要针对元素的操作,主要有创建、增、删、改、查、属性操作、事件操作
创建
document.write
innerHTML
createElement
增
appendChild
insertBefore
删
removeChild
改
–主要是修改DOM的元素属性,DOM元素的内容,属性,表单的值等
修改元素属性:src、href、title等
修改普通元素内容:innerHTML、innerText
修改表单元素:value、type、disabled等
修改元素样式:style、className
查
DOM提供的API方法:getElementById、getElementByTagName、getElementByClassName等
H5提供的新方法:querySelector、querySelectorAll 提倡
利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling)提倡
属性操作
setAttribute:设置dom的属性值
getAttribute:得到dom的属性值
removeAttribute:移除属性
事件操作
给元素注册事件,采取事件源事件类型=事件处理程序
鼠标事件
| 鼠标事件 | 触发条件 |
|---|---|
| onclick | 鼠标左键单击 |
| onmouseover | 鼠标经过触发 |
| onmouseout | 鼠标离开触发 |
| onfocus | 获得鼠标焦点触发 |
| onblur | 失去焦点触发 |
| onmousemove | 鼠标移动触发 |
| onmouseup | 鼠标弹起触发 |
| onmousedown | 鼠标按下触发 |
事件高级
注册事件
给元素添加事件称为注册事件会在绑定事件
注册事件有两种方式:传统方式和方法监听注册事件
传统注册方式
利用on开头的事件,如:onclick
<button onclick=""></button>btn.onclick=function(){}
特点:注册事件的唯一性
在同一个元素同一个事件只能设置一个处理函数,在后注册的处理函数将会覆盖前面注册的处理函数
方法监听注册方式
W3C标准推荐方式
addEventListener()它是一个方法
IE9之前的IE不支持此方法,可使用attachEvent()代替
特点:同一个元素同一个事件可以注册多个监听器
会按照注册顺序依次执行
addEventListener事件监听方式
eventTarget.addEventListener(type,listener,useCapture)
eventTarget.addEventListener()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数
该方法三个函数:
type:事件类型字符串,比如click、mouseover。注意这里不带on
listener:事件处理函数、发生事件时会调用该监听器
useCapture:可选参数,是一个布尔值,默认false,学完DOM事件后再进行学习
xxxxxxxxxx161<button>2 enter3</button>4<script>5 var but=document.querySelector("button")6 but.addEventListener('click',function(){7 alert('this is a button')8 })9 but.addEventListener('click',function(){10 alert('this is a gril')11 })//这样的话button就可以注册两个函数事件了12 //attachEvent ie9以前的版本支持13 but.attachEvent('onclick',function(){14 alert('this is a bug')15 })16</script>删除事件方式
传统删除事件方式
onclick=null——对事件进行解绑
xxxxxxxxxx101<button>2 3</button>4<script>5var bu=document.querySelector('button')6bu.onclick=function(){7 alert('this is a button')8 bu.onclick=null//这个事件只能点击一次,之后点击不再弹出警告框9}10</script>方法监听删除事件方式
removeEventListener(type,functionname
xxxxxxxxxx111<button>2 3</button>4<script>5 var bu=document.querySelector('button')6 bu.addEventListener('click',fn)//这种方法不能移除匿名函数,所以需要在之后添加一个命名的函数然后调用函数名进行调用7 function fn(){8 alert('this is a button')9 bu.removeEventListener('click',fn)//事件监听移除函数——对函数进行解绑10 }11</script>detachEvent(type,functionname)
xxxxxxxxxx111<button>2 3</button>4<script>5 var bu=document.querySelector('button')6 bu.attachEvent('onclick',fn)7 function fn(){8 alert('this is a boss')9 bu.detachEvent('onclick',fn)10 }11</script>DOM事件流
事件流是描述的是从页面中接收事件的顺序
事件发生时会在元素节点之间按照特定的顺序传播,这个是传播过程——也叫DOM事件流
DOM事件流3个阶段:
捕获阶段
当前目标阶段
冒泡阶段
事假冒泡:IE最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程
事件捕获:网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到最具体的元素接收的过程
注意:
js代码中只能执行捕获或者冒泡其中的一个阶段
onclick和attachEvent只能得到冒泡阶段
addEventListener(type,listener[,useCapture])第三个参数如果是true,表示在事件捕获阶段调用事件处理程序,如果是false(不写默认是false),表示在世间冒泡阶段调用事件处理程序
如果是处于冒泡阶段那就会先执行最底层的事件,再执行上一层事件,反之如果是在捕获阶段则就最先执行最高层事件再执行下层事件
实际开发过程中很少使用事件捕获,我们更加关注事件冒泡
有些事件是没有冒泡的
onblur
onfocus
onmouseenter
onmouseleave
事件对象
xxxxxxxxxx101<button>2 3</button>4
5<script>6 var bu=document.querySelector('button')7 bu.onclick=function(event){//在function后面的括号里添加一个参数就形成了事件对象,event就是一个事件对象,当形参来看8 console.log(event)9 }10</script>event就是一个事件对象,写到函数括号里面
事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要传递参数
事件对象是事件的一系列相关数据的集合,跟事件相关的,比如鼠标点击里面就包含了鼠标的相关信息——比如鼠标坐标
这个事件我们可以自己命名,不一定只有event
事件对象也有兼容性问题(又他妈是IE浏览器这个毒瘤)(解决e=e||window.event)
简单理解:事件发生后,跟事件相关的一些信息数据的集合都放在这个对象里面,这个对象就是事件对象,它有很多属性和方法
事件对象的属性和方法
| 事件属性和方法 | 说明 |
|---|---|
| e.target | 返回触发事件的对象 标准 |
| e.srcElement | 返回触发事件的对象 非标准 |
| e.type | 返回事件的类型 不如click |
| e.cancelBubble | 该属性阻止冒泡 非标准 |
| e.preventDefault() | 该属性阻止默认事件(默认行为) 标准 |
| e.returnValue | 该属性阻止默认事件(默认行为) 非标准 |
| e.stopPropagation() | 阻止冒泡 标准 |
阻止冒泡
阻止冒泡的两种方式
事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点
事件冒泡本身的结构会带来一些坏处,有时需要对它进行阻止
阻止事件冒泡
标准写法:利用实践对象里面的stopPropagation()方法
xxxxxxxxxx71<script>2bu.addEventListener('click',function(e){3
4 alert('this is a button')5e.stopPropagation()//阻止事件冒泡6})7</script>非标准写法:cancelBubble属性(需要考虑兼容性)
xxxxxxxxxx81<script>2bu.addEventListener('click',function(e){3
4 alert('this is a button')5e.stopPropagation()//阻止事件冒泡6 e.cancelBubble=true7})8</script>事件委托
事件委托又称事件代理,在jQuery里面称事假委派
事件委托的原理
不是给每个节点单独设置事件监听器,而是事件监听器设置在父节点上,然后利用事件冒泡原理影响设置每个子节点
事件委托的作用
只操作了一次DOM,提高程序性能
xxxxxxxxxx131<ul>2 <li>this is a li</li>3 <li>this is a li</li>4 <li>this is a li</li>5 <li>this is a li</li>6</ul>7<script>8var ul=document.querySelector('ul')9ul.assEventListener('click',function(e){10 alert('this is a alert')//这样得到的就是没点击一个li都会有一个弹窗11 e.target.style.backgroundColor="pink"//点击哪个li,哪个li的背景颜色就会变成pink色12})13</script>常用的鼠标事件
禁止鼠标右键菜单
contextmenu主要控制如何显示上下文菜单,主要用于程序员取消默认的上下文菜单
xxxxxxxxxx51<script>2doccument.addEventListener('contecxmenu',function(e){3 e.preventDefault()//这样就阻止了右键菜单,但是文本照样可以通过快捷键复制文本4})5</script>禁止鼠标选中
selectstart
xxxxxxxxxx51<script>2doccument.addEventListener('selectstart',function(e){3 e.preventDefault()//这样就不能选中文本了,连复制的机会都没有4})5</script>鼠标事件对象
event对象代表事件的状态,跟事件相关的一系列信息的集合,现阶段主要是鼠标事件对象MouseEvent和键盘事件对象KeyboarEvent
| 鼠标事件对象 | 说明 |
|---|---|
| e.clientX | 返回鼠标相对于浏览器窗口可视区的X坐标 |
| e.clientY | 返回鼠标相对于浏览器窗口可视区的Y坐标 |
| e.pageX | 返回鼠标相对于文档页面的X坐标 |
| e.pageY | 返回鼠标相对于文档页面的Y坐标 |
| e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
| e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
xxxxxxxxxx71<script>2 document.addEventListener('click',function(e){3 console.log(e.clienX)4 console.log(e.clienY)//不管窗口的高度,只能给出相对于当前视口的坐标5 console.log(e.pageX)//这里就能根据设置的窗口高度给出对应的坐标6 })7</script>案例:跟随鼠标
用到的鼠标事件:mousemove
xxxxxxxxxx131<body>2 <!-- 核心原理——没吃移动鼠标,都会获得鼠标的坐标,把鼠标坐标作为图片的绝对定位坐标 -->3 <img src="../html/1.jpg" alt="" style="position:absolute;">4</body>5<script>6
7 document.addEventListener('mousemove',function(e){8 var img=document.querySelector('img')9 img.style.left=e.clientX+"px"10
11 img.style.top=e.clientY + "px"12 })13</script>常用的键盘事件
| 键盘事件 | 触发条件 |
|---|---|
| keyup | 某个键盘按键被松开时触发 |
| keydown | 某个键盘按键按下时触发 |
| keypress | 某个键盘按键被按下时触发 但他不能识别功能键 ,比如Ctrl shift等 |
xxxxxxxxxx51<script>2docuemnt.addEventListener('keyup',function(){3 alert('this is keyboard function')//在键盘上按下任意键松开时触发4})5</script>keydown的执行顺序永远在前面,keypress其次,keyup最后
键盘事件对象
xxxxxxxxxx61<script>2docuemnt.addEventListener('keyup',function(e){3 alert('this is keyboard function')//在键盘上按下任意键松开时触发4 console.log(e.kye)//识别到按下的键盘按键是哪个5})6</script>keyup和keydown不区分大小写、keypress区分大小写
| 键盘事件对象属性 | 说明 |
|---|---|
| keyCode | 返回该键的ASCLL码值 |
| key | 返回按键的名称 |
BOM
BOM概述
BOM(Browser Object Model)浏览器对象模型,它是提供了独立于内容而于浏览器窗口进行交互的对象,其核心对象是window。
BOM由一系列相关对象构成,并且每个对象都提供了很多方法和属性
BOM缺乏标准,JavaScript语法标准化组织ECMA,DOM的标准化组织是W3C,BOM最初是Netscape浏览器标准的一部分
DOM和BOM对比:
DOM:
文档对象模型
DOM就是把文档当做一个对象来看待
DOM的顶级对象是document
DOM主要学习的是操作页面元素
DOM是W3C的标准
BOM:
浏览器对象模型
把浏览器当做一个对象来看待
BOM顶级对象是window
BOM学习的是浏览器窗口交互的一些对象
BOM是浏览器厂商在浏览器上定义的,兼容性较差
BOM比DOM更大,它包含了DOM
window对象的常见事件
窗口加载事件
xxxxxxxxxx31window.onload=function(){}2或者3window.addEventListener('load',funciton(){})window.onload是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS文件等)就调用处理函数
有了window.load就可以把js代码写到页面元素的上方,因为onload是等页面内容全部加载完毕,再去执行处理函数
window.load传统注册事件方式只能写一次,如果写多个,会以最后一个window为准
如果使用window.addEventListener是没有冲突的,可以写多个window.addEventListener
xxxxxxxxxx21document.addEventListener('DOMContentLoaded',function(){})2<!--这个DOMContentLoaded是等DOM加载完成后触发事件,不包括样式表、图片、flash等-->这个DOMContentLoaded是等DOM加载完成后触发事件,不包括样式表、图片、flash等,ie9以上才支持
如果页面图片很多的话,从用户访问到onload触发可能需要较长的等待时间,交互效果就不能实现了,必须影响到用户体验,此时使用DOMContentLoaded事件比较合适
load事件是等待页面全部加载完毕(包含图片、flash、css等)才执行函数
DOMContentLoaded 是等DOM加载完毕(不包含图片、flash、css等)就执行函数,加载速度更快一些
调整窗口大小
xxxxxxxxxx31window.onresize=function(){}2或3window.addEventListener('resize',function(){})window.onsezise是调整窗口大小加载事件,当触发时调用处理函数
注意:
只要窗口大小发生像素变化,就会触发事件
经常利用这个事件完成响应式布局,window.innerWidth当前屏幕宽度、window.innerHeight当前屏幕的高度
定时器
window对象提供了两种定时器
setTimeout()
setInterval()
setTimeout()定时器
xxxxxxxxxx21window.setTimeout(调用函数,[延迟毫秒数])<!--设个window在使用的时候可以省略-->2setTimeout()setTimeout()方法用于设置一个定时器,该定时器在定时器到期后执行调用函数,单位为毫秒。可以省略,如果省略这默认为0,立即执行
xxxxxxxxxx31setTimeout(function(){2alert('this is a shabi')3},2000)这个调用函数可以直接写一个函数,还可以写函数名
xxxxxxxxxx71
2<script>3 function a(){4alert('this is boop')5}6setTimeout(a,2000)7</script>调用函数还可以写成:在引号里写函数名,函数名后面加上括号,不提倡这种写法(太啰嗦)
xxxxxxxxxx61<script>2 function a(){3 alert('this is a gril')4 }5 setTimeout('a()',2000)<!--在引号里写函数名,函数名后面加上括号,不提倡这种写法(太啰嗦)-->6</script>页面中可能含有很多定时器,我们经常给定时器添加标识符(定时器的名字)
xxxxxxxxxx61<script>2function a(){3alert('this is a gril')4}5var a = setTimeout('a()',2000)<!--给定时器添加名字-->6</script>
回调函数
xxxxxxxxxx11window.setTimeout(调用函数,延迟毫秒数)setTimeout()这个调用函数我们也称之为回调函数callback
普通的函数是按照代码的顺序直接调用的,而这个函数需要等待时间才调用这个函数,因此称之为回调函数
停止setTimeout()定时器
window.clearTimeout(timeoutID)
window可以省略
xxxxxxxxxx121<button>2stop3</button>4<script>5var bu=document.querySelector('button')6var time=setTimeout(function(){7alert('this is a setTImeout')8},5000)9bu.addEventListener('click',function(){10clearTimeout(time)//关掉定时器11})12</script>
setInterval()定时器
window.setInterval(回调函数,间隔的毫秒数)
setInterval()方法重复调用一个函数,每隔这个时间就去调用一次回调函数
window可以省略
调用的时候函数名的写法和setTimeout一样
时间毫秒也是可以省略的,意思和setTimeout一样
因为定时器有很多所以也会个这个定时器命名(标识符)
停止setInterval定时器
window.clearInterval(intervalID)
clearInterval方法取消先前对调用的setInterval建立的定时器
window可以省略
里面的参数是定时器的标识符
xxxxxxxxxx201<button class="play">2 play3</button>4<button class="stop">5 stop6</button>7<script>8var play=document.querySelector=".play"9var stop=document.querySelector=".stop"10var timer=null//定义一个空的变量作为定时器的标识符且为全局变量11play.addEventListener('click',function(){12 timer = setInterval(function(){13 alert('this is a timer')14 },1000)15})//开始计时16 stop.document.addEventListener('click',function(){17 clearInterval(timer)18 })//停止计时19
20</script>this
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,一般情况下this的最终指向是那个调用它的对象
全局作用域或者普通函数中的this指向全局对象window(注意定时器里面的this指向window)
方法调用中谁调用,this指向谁
构造函数中的this指向构造函数的实例
js执行机制
js是单线程
JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事,这是因为JavaScript这门脚本语言诞生的使命所致——JavaScript是为处理页面中用户的交互,以及操作DOM而诞生的,比如我们对DOM元素进行添加和删除,应该先进行添加之后再删除
单线程就意味着,所有的任务都需要排队,前一个任务结束才会执行下一个任务,这所导致的问题是:如果js执行时间过长,这样就会造成页面的渲染不连贯
同步或者异步
为了解决js执行过长这个问题,利用CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,于是,JS中出现了同步和异步
同步
前一个任务结束了才能执行下一个任务,程序的执行顺序与任务的排列顺序是一致的,同步的
异步
在做一件事的同时还可以处理其他的事情
他们的区别就是在流水线上各个流程的执行顺序不同
同步任务
同步任务都在主线程上执行,形成执行栈
异步任务
JS的异步是通过回调函数实现的
异步任务三种类:
普通事件,如click、resize等
资源加载,如load、error等
定时器,包括setTimeout、setInterval等
异步任务相关的回调函数添加到任务队列中(任务队列也称为消息队列)
JS执行机制
先执行栈中的同步任务
异步任务(回调函数)放入任务队列中
一旦执行栈中的所有同步任务执行完毕,系统就会依次读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行
由于主线程不断的重复获得任务、执行任务、再获取任务、在执行,所以这种机制被称之为事件循环(eventloop)
location对象
window对象给我吗提供了一个location属性用于获取或设置窗口的URL,并且可以用于解析URL,因为这个属性返回的是一个对象,所以我们将这个属性也称之为location对象
URL
统一资源定位符(Uniform Resource Location,URL)是互联网上标准资源地址,互联网上的每一个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它
URL语法格式:
xxxxxxxxxx21protocol://host[:port]/path/[?query]#fragment2http://www/itcast.cn/index.html?name=andy&age=18#link| 组成 | 说明 |
|---|---|
| protocol | 通信协议 常用的http、ftp、maito等 |
| host | 主机(域名) |
| port | 端口号(可选),省略时使用方案的默认端口为80 |
| path | 路径 由零或多个‘/’符号隔开的字符串,一般用来表示主机上的一个目录或文件地址 |
| query | 参数 以键值对的形式 通过&符号分隔开来 |
| fragment | 片段 #后面内容 常见于链接 锚点 |
location对象的属性
| location对象属性 | 返回值 |
|---|---|
| location.href | 获取或者设置整个URL |
| location.host | 返回主机(域名) |
| location.port | 返回端口号 如果为填写返回空字符串 |
| location.pathname | 返回路径 |
| location.search | 返回参数 |
| location.hash | 返回片段 |
案例:获取URL参数
xxxxxxxxxx31<form action="index.html">2 <span><b>User Name:</b></span> <input type="text" name="uname"><input type="submit" value="submit">3</form>xxxxxxxxxx141<body>2<p></p>3</body>4<script>5 var usname=document.querySelector('p')6 //去掉? substr('起始的位置','截取几个字符')7 var p=location.search.substr(1)8 console.log(p);9 //利用split方法分隔数组split('=')10 var a=p.split('=')11 console.log(a[1]);12 usname.innerHTML="用户"+a[1]+"欢迎您"13
14</script>location对象的方法
| location对象方法 | 返回值 |
|---|---|
| location.assign() | 跟href一样,可以跳转页面(也称为重定页面) |
| location.replace() | 替换当前页面,因为不记录历史,所以不能后退页面 |
| location.reload() | 重新加载页面,相当于刷新按钮或者F5键 如果参数为true强制刷新Ctrl+F5 |
navigator对象
navigator对象包含有关浏览器的信息,它有很多属性,我们最常用的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部值
xxxxxxxxxx51if((navigator.userAgent.match(/phone|pad|pod|iphone|ipad|ios|ipod|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|WOSBrowser|BrowserNG|Webos|Symbian|Windows Phone)/i))){2 window.location.href="" //手机端3}else{4 window.location.href="" //电脑端5}history对象
window对象给我们提供了一个history对象,与浏览器历史记录进行交互,该对象包含用户(在浏览器窗口中)访问的URL
| history对象方法 | 作用 |
|---|---|
| back() | 可以后退功能 |
| forward() | 前进功能 |
| go(参数) | 前进后退功能参数如果是1前进1个页面,如果是-1,后退一个页面 |
类似于页面的返回撤回