应用程序编程接口,就是一个工具,以便于能轻松实现想要完成的功能
Web API是浏览器提供的一套操作浏览器功能和页面元素的API(DOM和BOM)
可以改变网页的内容、结构和样式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G2sT7SRi-1570005298851)(media\DOM树.png)]
文档:一个页面就是一个文档 document 元素:页面中的所有标签都是元素,element 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),node
DOM把以上内容都看作是对象
注意:
因为文档页面从上往下加载,所以先有标签,然后才能getElementById参数是字符串,所以需要加引号返回的是一个 element 对象console.dir 可以打印返回的元素对象,更好的查看里面的属性和方法
类名选择器
HTML5新增的
返回指定选择器的第一个对象
<div class="box"> <ul> <li>15212</li> <li>1641238</li> </ul> </div> <div class="box"> <ul> <li>151232</li> <li>1612348</li> </ul> </div> <script> //注意这里括号里面必须有“.”,因为需要指定选择的选择器 var boxs = document.querySelector('.box'); console.log(boxs); </script>返回指定选择器的所有对象集合 用法和querySelector()一样
获取body元素
获取html元素
JavaScript使我们有能力创建动态页面,而事件是可以被JavaScript侦测到的行为。 网页中的每个元素都可以产生某些触发JavaScript的事件。
事件都有:
鼠标事件触发条件onclick鼠标点击左键触发onmouseover鼠标经过触发onmouseout鼠标离开触发onfocus获得鼠标焦点触发onblur失去鼠标焦点触发onmousemove鼠标移动触发onmouseup鼠标弹起触发onmousedown鼠标按下触发JavaScript可以改变网页内容、结构和样式,我们可以利用DOM操作元素来改变元素里面的内容、属性等。
disabled 让某个表单被禁用,不能被点击, 用法:
btn.onclick = function () { btn.disabled = true; //或者写成下面这种 this.disabled = true; //this指向的是时间函数的调用者 }案例:仿京东显示密码,点击按钮将密码框显示为文本框,并可以查看密码明文
算法:利用一个flag变量,如果是1就切换为文本框,如果是0就切换为密码框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> * { margin: 0; padding: 0; } form { position: relative; width: 1000px; height: 500px; border: 1px solid red; margin: 100px auto 0; } input { display: block; width: 800px; height: 50px; line-height: 30px; color: #3c3c3c; margin: 50px auto 50px; padding-left: 20px; box-sizing: border-box; border: 1px solid red; } label img { top: 164px; right: 120px; position: absolute; width: 24px; } </style> </head> <body> <form action="#"> <input type="text" id="userName" placeholder="请输入你的用户名"> <label for=""> <img src="images/闭眼.png" alt=""> </label> <input type="password" id="password" placeholder="请输入你的密码"> </form> <script> var eye = document.querySelector('img'); var password = document.getElementById('password'); var flag = 0; eye.onclick = function () { if (flag === 0) { password.type = 'text'; eye.src = 'images/睁眼.png'; flag = 1; } else { password.type = 'password'; eye.src = 'images/闭眼.png'; flag = 0; } } </script> </body> </html>行内样式操作,修改元素样式,如果样式比较少或者功能简单的情况下使用 注意:
里面的属性是驼峰命名法JS修改的是行内样式,权重比CSS的高类名样式操作,适合样式比较多的情况下使用 修改了元素的类名
**注意:**这个方法直接修改了类名,也就是说会覆盖原来的类名,原来的就不生效了 如果想要保留原先的类名,这样做:
//假设first 是原来的类名,change是想加入的 this.className = 'first change';获得焦点 onfocus 失去焦点 onblur
案例:京东搜索框,默认是“手机”两个字,当用户点击搜索框的时候,“手机”两个字消失,当输入文本之后,保持文本内容不变
分析:
如果获得焦点,判断里面是否是默认文字,如果是默认文字,就清空表单内容如果失去焦点,判断表单是否为空,如果为空,则表单内容改为默认文字获得焦点的时候,把文本框里的文字变黑失去焦点的时候,文本框文字变浅 <input type="text" value="手机"> <script> var input = document.querySelector('input'); input.onfocus = function () { if (this.value === '手机') { input.value = ''; } this.style.color = '#3c3c3c'; } input.onblur = function () { if (this.value === '') { input.value = '手机'; } this.style.color = '#999'; } </script>案例:密码提示框,选中的时候提示密码的长度和标准,失去焦点的时候,检查密码是否合乎规范
分析:
如果获得焦点,提示密码的长度和标准如果失去焦点,检查密码是否合乎规范,如果不符合规范,就提示因为改变的样式比较多,所以用className来修改样式 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> div { width: 600px; margin: 100px auto; } .message { display: inline-block; font-size: 12px; color: #999; background: url(images/message.png) no-repeat left center; background-size: 16px; padding-left: 20px; } .error { display: inline-block; font-size: 12px; color: red; background: url(images/error.png) no-repeat left center; background-size: 16px; padding-left: 20px; } .right { display: inline-block; font-size: 12px; color: green; background: url(images/right.png) no-repeat left center; background-size: 16px; padding-left: 20px; } </style> </head> <body> <div class="register"> <input type="password" class="pwd"> <p class="message">请输入6~16位密码</p> </div> <script> var pwd = document.querySelector('.pwd'); var message = document.querySelector('.message'); pwd.onblur = function() { if (pwd.value.length > 16 || pwd.value.length < 6) { message.className = 'error'; message.innerHTML = '您输入的位数不对,要求6~16位'; } else { message.className = 'right'; message.innerHTML = '对辽~'; } } </script> </body> </html>两层循环,先排除其他人,然后再设置自己的样式
<button>按钮1</button> <button>按钮2</button> <button>按钮3</button> <button>按钮4</button> <button>按钮5</button> <script> var btns = document.querySelectorAll('button'); for (var i = 0; i < btns.length; i++) { btns[i].onclick = function () { // 1. 先把所有颜色的背景颜色都清空 for (var j = 0; j < btns.length; j++) { btns[j].style.backgroundColor = ''; } // 2. 再把想要的背景颜色改成pink this.style.backgroundColor = 'pink'; } } </script>案例:百度换肤效果
分析:
利用循环给一组元素注册点击事件当鼠标经过一张图片,当前的页面背景换成经过的图片,鼠标移开之后,换回默认的当点击了图片,当前的页面背景换成点击的图片核心算法:把当前图片的src路径取过来,给body作为背景 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> * { margin: 0; padding: 0; } body { background: url(images/bg1.jpg) no-repeat center top; } li { list-style: none; } .baidu { overflow: hidden; margin: 100px auto; background-color: #fff; width: 410px; padding-top: 3px; } .baidu li { float: left; margin: 0 1px; cursor: pointer; } .baidu img { width: 100px; } </style> </head> <body> <ul class="baidu"> <li><img src="images/bg1.jpg" alt=""></li> <li><img src="images/bg2.jpg" alt=""></li> <li><img src="images/bg3.jpg" alt=""></li> <li><img src="images/bg4.jpg" alt=""></li> </ul> <script> //获取元素 var images = document.querySelector('.baidu').querySelectorAll('img'); for (var i = 0; i < images.length; i++) { //temp 存储原来的背景 var temp; images[i].onclick = function () { document.body.style.backgroundImage = 'url(' + this.src + ')'; temp = 'url(' + this.src + ')'; } images[i].onmouseover = function () { temp = document.body.style.backgroundImage; document.body.style.backgroundImage = 'url(' + this.src + ')'; } images[i].onmouseout = function () { document.body.style.backgroundImage = temp; } } </script> </body> </html>案例: 表单全选取消全选
分析:
点击上面全选复选框,下面所有的复选框都选中(全选)再次点击全选复选框,下面所有的复选框都不中选(取消全选)如果下面复选框全部选中,上面全选按钮就自动选中如果下面复选框有一个没有选中,上面全选按钮就不选中所有复选框一开始默认都没选中状态下面复选框需要全部选中,上面全选才能选中做法:给下面所有复选框绑定点击事件,每次点击,都要循环查看下面所有的复选框是否有没选中的,如果有一个没选中的上面全选就不选中。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> table { width: 800px; height: 500px; margin: 0 auto; border: 1px solid #999; text-align: center; } table tbody tr { background-color: rgb(163, 163, 163); } thead { background-color: skyblue; } </style> </head> <body> <table> <thead> <tr> <th><input type="checkbox" name="" id="checkAll" ></th> <th>商品</th> <th>价格</th> </tr> </thead> <tbody> <tr> <td><input type="checkbox" name="" id=""></td> <td>iPhone Xs Max</td> <td>10000</td> </tr> <tr> <td><input type="checkbox" name="" id=""></td> <td>iPad Pro</td> <td>5000</td> </tr> <tr> <td><input type="checkbox" name="" id=""></td> <td>iWatch</td> <td>3000</td> </tr> <tr> <td><input type="checkbox" name="" id=""></td> <td>AirPods</td> <td>1000</td> </tr> </tbody> </table> <script> var checkAll = document.querySelector('#checkAll'); var trs = document.querySelector('tbody').querySelectorAll('tr'); var tbCheck = document.querySelector('tbody').getElementsByTagName('input'); for (var i = 0; i < trs.length; i++) { trs[i].onmouseover = function () { this.style.backgroundColor = 'rgb(200, 200, 200)'; } trs[i].onmouseout = function () { this.style.backgroundColor = ''; } } checkAll.onclick = function () { for (var j = 0; j < tbCheck.length; j++) { tbCheck[j].checked = checkAll.checked; } } //下面的全部选中,上面的就选中 for (var i = 0; i < tbCheck.length; i++) { tbCheck[i].onclick = function () { // flag 控制全选按钮是否被选中 var flag = true; for (var j = 0; j < tbCheck.length; j++) { if (!(tbCheck[j].checked)) { flag = false; break; // 退出for循环,提高运行效率 } } checkAll.checked = flag; } } </script> </body> </html>分析:
一个大盒子,里面上下两个小盒子上面的模块,点击某一个之后,这个的背景色是红色,其余的是灰色(排他思想)点击某一个之后,显示这个模块对应的内容,其他的隐藏,这个要写到点击事件里面下面的显示内容和上面的小 li 一一对应核心思路: 给上面的tab_list 添加自定义属性,属性号从0开始当点击上面的模块,下面的队形的显示模块开始显示,其他的隐藏 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> * { margin: 0; padding: 0; } ul { list-style: none; } .tab { width: 800px; height: 500px; margin: 200px auto; } .tab_list { height: 50px; background-color: rgb(162, 162, 162); border-bottom: 2px solid #c81623; } .tab_list ul li { float: left; display: inline-block; width: 150px; height: 50px; line-height: 50px; text-align: center; cursor: pointer; } .tab_list .current { background-color: #c81623; color: #fff; } .item { display: none; } </style> </head> <body> <div class="tab"> <div class="tab_list"> <ul> <li class="current">商品介绍</li> <li>规格与包装</li> <li>售后保障</li> <li>商品评价(1.1万+)</li> <li>手机社区</li> </ul> </div> <div class="tab_con"> <div class="item" style="display: block"> 商品介绍模块内容 </div> <div class="item"> 规格与包装模块内容 </div> <div class="item"> 售后保障模块内容 </div> <div class="item"> 商品评价模块内容 </div> <div class="item"> 手机社区模块内容 </div> </div> </div> <script> var tab_list = document.querySelector('.tab_list'); var lis = tab_list.querySelectorAll('li'); var items = document.querySelectorAll('.item'); for (var i = 0; i < lis.length; i++) { //给5个li设置索引号 lis[i].setAttribute('index', i); lis[i].onclick = function () { //干掉其他人 for (var j = 0; j < lis.length; j++) { lis[j].className = ''; } this.className = 'current'; var index = this.getAttribute('index'); for (var k = 0; k < items.length; k++) { items[k].style.display = 'none'; } items[index].style.display = 'block'; } } </script> </body> </html>自定义属性目的:为了保存并使用数据,有些数据保存到页面中,为不是数据库中
但是有些自定义属性容易引以歧义,不容易判断是内置属性还是自定义属性,所以H5给我们新增了自定义属性 H5规定自定义属性以 “data-” 开头
注意:
<div data-list-name="andy"></div> <script> var div = document.querySelector('div'); console.log(div.getAttribute('data-list-name')); //上下三种方法都可以,但是如果用下面这两种方法的话,要用驼峰命名法 console.log(div.dataset.listName); console.log(div.dataset['listName']); </script>利用DOM提供的方法获取元素 (逻辑性不强,繁琐)
document.getElementById()document.getElementByTagName()document.querySelector 等等利用 (简单、符合逻辑)
利用父子兄的节点关系获取元素逻辑性强,但是兼容性差[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pATaFkOZ-1570005298854)(media\DOM树.png)]
页面中所有的内容(标签、属性、文本、注释等)都是节点。节点用node表示。
HTML DOM树中的所有节点均可通过JavaScript 进行访问,所有HTML节点均可被修改,也可以创建或删除。
一般的,节点至少由nodeType(节点类型)、 nodeName(节点名称)、 nodeValue(节点值)这三个基本属性。
元素节点 nodeType 为1属性节点 nodeType 为2文本节点 nodeType 为3 (文本节点包括文字、空格、换行等等)在实际开发中,节点操作主要操作的是元素节点。
最常见的是父子兄层级关系。
node.parentNode
注意:得到的离元素最近的父级节点(亲爸爸),如果找不到就返回null
parentNode.childNodes (标准)
返回包含指定节点的子节点的集合,该集合为即时更新的集合 包含的子节点包含元素节点、文本节点等等
所以用 nodeType 判断,用for循环遍历
parentNode.children (非标准)
得到所有的子元素节点,虽然是非标准的,但是得到了浏览器的支持,所以以后大量使用这个
parentNode.firstChild
返回第一个子节点,找不到返回null,不管是文本节点还是元素节点都能找到
parentNode.firstElementChild
返回第一个子元素节点,找不到返回null,只返回元素节点(IE9以上才支持)
parentNode.lastChild
返回最后一个子节点,找不到返回null,不管是文本节点还是元素节点都能找到
parentNode.lastElementChild
返回最后一个子元素节点,找不到返回null,只返回元素节点(IE9以上才支持)
实际开发中的办法:
parentNode.children[i]
案例:新浪下拉菜单
分析:nav导航栏中有ul和li,li下面又有ul和li,第二层ul和li在鼠标移上去的时候才显示
导航栏里面的li都要有鼠标经过的效果,所以需要循环注册核心原理:当鼠标经过li 的时候,孩子的ul 和li 显示,当鼠标离开,则隐藏 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>新浪网</title> <style> * { margin: 0; padding: 0; } ul { list-style: none; } a { text-decoration: none; } .nav { width: 800px; margin: 200px auto; position: relative; } .nav>li { width: 80px; height: 100%; line-height: 41px; color: #333; float: left; position: relative; text-align: center; } .nav>li>a:hover { background-color: #eee; } .nav li ul { display: none; position: absolute; top: 41px; left: 0; width: 100%; border-left: 1px solid #fecc5b; border-right: 1px solid #fecc5b; box-sizing: border-box; } .nav li ul li { border-bottom: 1px solid #fecc5b; /* width: 50px; text-align: center; */ } .nav ul li a:hover { background-color: #FFF5DA; } </style> </head> <body> <ul class="nav"> <li> <a href="#">微博</a> <ul> <li> <a href="#">私信</a> </li> <li> <a href="#">评论</a> </li> <li> <a href="#">@我</a> </li> </ul> </li> <li> <a href="#">微博</a> <ul> <li> <a href="#">私信</a> </li> <li> <a href="#">评论</a> </li> <li> <a href="#">@我</a> </li> </ul> </li> <li> <a href="#">微博</a> <ul> <li> <a href="#">私信</a> </li> <li> <a href="#">评论</a> </li> <li> <a href="#">@我</a> </li> </ul> </li> </ul> <script> //获取元素 var nav = document.querySelector('.nav'); var lis = nav.children; //循环注册事件 for (var i = 0; i < lis.length; i++) { lis[i].onmouseover = function () { this.children[1].style.display = 'block'; } lis[i].onmouseout = function () { this.children[1].style.display = 'none'; } } </script> </body> </html>node.nextSibling 得到下一个兄弟节点,包括元素节点和文本节点 node.previousSibling 得到上一个兄弟节点,包括元素节点和文本节点
//下面两个方法只有IE9以上才能兼容 node.nextElementSibling 得到下一个兄弟元素节点,只有元素节点 node.previousElementSibling 得到上一个兄弟元素节点,只有元素节点
document.createElement(‘tagName’)
这个方法创建由tagName指定的 HTML 元素,因为这些元素原先不存在,是根据我们的需求动态生成的,所以也称为动态创建元素节点。
node.appendChild(child);
它是追加元素,是在指定父节点的子节点的末尾添加。
node.insertBefore(child, 指定元素);
分析:
页面组成:一个文本域,一个提交按钮,一个留言板当点击提交按钮的时候,先判断文本域内容是不是空,如果是空,就警告如果不是空,就新建一个li,然后把文本域的内容赋值给li,然后在ul里面的前面添加linode.removeChild(child);
从DOM中删除一个子节点,返回删除的节点
案例分析:
在留言板案例的基础上添加功能当把文本域的内容幅值给 li 的时候,多添加一个删除的链接,循环把所有的链接获取过来,当我们点击一个链接的时候,删除当前链接所在的 li阻止链接跳转需要添加javascript:void(0);或者 javascript:; <script> //获取元素 var btn = document.querySelector('button'); var text = document.querySelector('textarea'); var ul = document.querySelector('ul'); //注册事件 btn.onclick = function () { if (text.value == '') { alert('您没有输入任何内容'); return false; } else { var li = document.createElement('li'); //将文本域的内容赋值给li,同时后面添加一个删除留言的a链接 li.innerHTML = text.value + "<a href='javascript:;'>删除</a>"; ul.insertBefore(li, ul.children[0]); var as = document.querySelectorAll('a'); for (var i = 0; i < as.length; i++) { as[i].onclick = function () { //删除的是a当前所在的li ul.removeChild(this.parentNode); } } } } </script>node.cloneNode() 这个方法返回一个节点的副本
注意:
如果括号里面的参数为空,那么只是浅拷贝,即只复制节点本身,不克隆里面的子节点如果括号里面的参数为true,那么是深拷贝,复制标签并且复制里面的内容总结:不同浏览器下,innerHTML比createElement效率高
文档对象模型
修改DOM元素的属性,DOM元素的内容、属性、表单的值等
修改元素属性:src、href、title等修改普通元素内容:innerHTML、innerText修改表单元素:value、type、disable等修改元素样式:style、className给元素添加事件,称为注册时间或者绑定事件。
注册事件有两种方式:传统方式和方法监听注册方式
eventTarget.addEventListener(type, listener[, useCapture]) 方法将指定的监听器注册到eventTarget 上,当该对象触发指定的事件时,就会执行事件处理函数。
该方法接收三个参数:
type : 事件类型字符串,比如click、mouseover,注意这里不要带on,是字符串,带引号listener : 事件处理函数,事件发生时,会调用该监听函数useCapture : 可选函数,是一个布尔值,默认是false 。学完DOM事件流之后,再进一步学习该特性非标准,请尽量不要在生产环境中使用它
eventTarget.attackEvent(eventNameWithon, callback)eventTarget.attackEvent方法将指定的监听器注册到eventTarget 上,当该对象触发指定的事件时,指定的回调函数将会被执行。
该方法接收两个参数:
ventNameWithon : 事件类型字符串,比如onclick,onmouseover, 这里要带oncallback : 事件处理函数,当目标触发事件时回调函数将被调用事件流描述的是从页面中接收事件的顺序。
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
包括三个阶段:
事件捕获阶段处于目标阶段事件冒泡阶段注意:
JS代码只能执行捕获或者冒泡其中的一个阶段onclick 和 attachEvent 只能得到冒泡阶段addEventListener (type, listener[, useCapture]) 第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(不写默认就是false),表示在事件冒泡阶段电泳事件处理程序。在实际开发中,我们很少使用事件捕获,我们更关注事件冒泡有些事件是没有冒泡的,比如onblur、onfocus、onmouseover、onmouseleave虽然事件冒泡有时候会带来麻烦,但是有时候又会巧妙的做某些事情,我们后面讲解兼容性写法:
event = event || windoe.event;this 返回的是绑定事件的对象(元素)
e.target 返回的是点击的那个对象,就是谁触发了这个事件
var ul = document.querySelector('ul'); ul.addEventListener('click', function (e) { console.log(this); console.log(e.target); }) // <ul>...</ul> // <li>123</li>三种方法:
e.preventDefaule(); 是一个方法,适合普通浏览器e.returnValue;是一个属性,适用于 IE 6 7 8return false; 没有兼容性问题,但是需要注意后面的语句就不执行了,直接跳出事件委托的原理:不给每个子节点单独设置事件监听器,而是设置在其父节点上,然后利用冒泡原理设置每个子节点。
**例如:**给 ul 注册点击事件,然后利用事件对象的 target 来找到当前点击的 li ,然后事件冒泡到 ul 上, ul 有注册事件,就会触发事件监听器。
只操作了一次 DOM ,提高了程序的性能。
跟随鼠标的小鸟:
当按下的时候,keydown 执行在 keypress 之前。
注意:
keyup 和 keydown 事件不区分字母大小写, a 和 A 得到的都是65keypress 区分大小写,a 得到的是97,A 得到的是 65京东按下 s 键定位到搜索框:
检测用户是否按下了 s 键盘,如果按下 s 键,就把光标定位到搜索框里面。
快递单号查询:
查询快递单号的时候,上面一个更大的盒子显示同样的内容(这里的字号更大)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-or1AE7R9-1570005298862)(media\express.png)]
注意:
keydown 和 keypress 触发的时候,文字还没有落入文本框中。
keyup 触发的时候,文字已经输入到文本框中。
BOM(Brower Object Model) 即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window。
BOM 是由一系列相关的对象构成,并且每个对象都提供了很多方法和属性。
BOM 缺乏标准,JavaScript 语法的标准化组织是 ECMA,DOM 的标准化组织是 W3C,BOM 最初是 Netscape 浏览器标准的一部分。每个浏览器都有自己的标准。
BOM 比 DOM 更大,它包括 DOM。
window document location navigation screen historywindow 对象是浏览器的顶级对象,它具有双重角色。
它是 JS 访问浏览器窗口的一个接口。它是一个全局对象,定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法。在调用的时候可以省略 window,前面学习的对话框都属于 window 对象方法,如 alert()、prompt() 等。
window.onload 是窗口(页面)加载事件,当文档内容完全加载完成后会触发该事件(包括图像、脚本文件、CSS文件等)。
window.onload 只能写一次,当写了很多个的时候,只有最后一个起作用, 所以推荐第二种写法。
这个事件当 DOM 加载完成时触发,不包含 CSS、图片、flash 等。
IE9+ 支持。
这是调整窗口大小的时候的触发事件。包括窗口高度和宽度。
经常用来实现响应式布局。 window.inner.width 当前屏幕的宽度
window 对象提供了2个好用的方法——定时器:
setTimeout()setInterval() window.setTimeout(调用函数, [延迟的毫秒数]); setTimeout() 方法用于设置一个定时器,该定时器在定时器到期后执行调用函数。这个 window 在调用的时候可以省略。这个延时时间单位是毫秒,可以省略,如果省略默认是0。这个调用函数可以直接写函数,还可以写函数名,函数名后面不写括号。页面中可能有很多的定时器,我们经常给定时器加标识符(名字)。setInterval() 方法重复调用一个函数,每隔这个时间,就去调用一次回调函数
分析:
这个倒计时是不断变化的,所以使用 setInterval() 来实现三个黑色盒子里面分别放时分秒三个黑子盒子的利用 innerHTML 放入计算的小时分钟秒数第一次之前也是间隔一定的毫秒数,所以在定时器的前面先调用一下刷新时间的函数,防止第一次刷新之前有空白 <body> <div> <span class="hour">1</span> <span class="minute">2</span> <span class="second">3</span> </div> <script> var hour = document.querySelector('.hour'); var minute = document.querySelector('.minute'); var second = document.querySelector('.second'); var inputTime = +new Date('2019-9-22 18:00:00'); // 在定时器获取之前,先运行一次,这样不会显示原始默认的1 2 3 getInterval(); // 每秒钟获取一次事件 setInterval(getInterval, 1000); function getInterval() { var nowTime = +new Date(); var interval = (inputTime - nowTime) / 1000; //两个日期相差的秒数 var hours, minutes, seconds; hours = Math.floor(interval / 60 / 60 % 24); hours = hours < 10 ? '0' + hours : hours; hour.innerHTML = hours; minutes = Math.floor(interval / 60 % 60); minutes = minutes < 10 ? '0' + minutes : minutes; minute.innerHTML = minutes; seconds = Math.floor(interval % 60); seconds = seconds < 10 ? '0' + seconds : seconds; second.innerHTML = seconds; } </script> </body>点击发送验证码之后,该按钮在60秒只能不能再被点击,防止重复发送短信
this 的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定 this 到底指向谁,一般情况下 this 的最终指向的是那个调用它的对象。
JS 的一大特点就是单线程,也就是说,同一时间只能做一件事,这是因为 JS这门语言诞生的使命导致的—— JS 是为处理页面中用户的交互,以及操作 DOM 而诞生的。比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。应该先添加,然后再删除。
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程。于是,JS 中出现了 同步 和 异步 。
<script> console.log(1); setTimeout(function () { console.log(3); }, 1000); console.log(2); </script>运行结果是 1 2 3
<script> console.log(1); setTimeout(function () { console.log(3); }, 0); console.log(2); </script>运行结果是 1 2 3
同步任务:同步任务都在主线程上执行,形成一个执行栈。
异步任务: JS 的异步是通过回调函数实现的。
一般而言,异步任务有以下三种类型:
普通事件:如click、resize 等资源加载,如load、error 等定时器,包括setInterval、setTimeout 等异步任务相关回调函数添加到任务队列中(任务队列也称为消息队列)。
由于主现程不断地重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环(evwnt loop)。
window 对象给我们提供了一个 location 属性用于获取或设置窗体的URL,并且可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为 location 对象。
统一资源定位符(Uniform Resource Locator,URL)是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
URL 的一般语法结构为:
porotocol://host[:port]/path/[?query]#fragment http://www.itcast.cn/index.html?name=andy&age=18#link 组成说明protocol通信协议,常用的http、ftp、maito等host主机(域名)port端口号,可选,省略时使用默认断开,如http的默认端口80path路径,由零或多个“/”格开的字符串,一般用来表示主机上的一个目录或者文件地址query参数,以键值对的形式,通过符号 & 分割开来fragment片段,# 后面的内容常见于链接,锚点案例分析:
利用定时器做倒计时效果location.href 跳转页面 <div>将在5秒钟之后跳转到首页!</div> <script> setTimeout(function() { location.href = 'http://www.baidu.com'; }, 5000); </script>主要练习数据在不同页面之间的传递
案例分析:
第一个登陆页面,里面有提交表单,action 提交到 index.html 页面第二个页面可以使用第一个页面的参数,利用了 location.search 参数截取字符串用 substr分隔符,将 = 前后的分隔开login.html :
<form action="index.html"> <input type="text" name="username" id=""> <input type="submit" value="登录"> </form>index.html :
<div></div> <script> // substr(起始位置, 截取几个字符) var params = location.search.substr(1); var arr = params.split('='); var div = document.querySelector('div'); div.innerHTML = '欢迎您!会员' + arr[1] + '!'; </script>navigator对象包含有关浏览器的信息,它有很多属性,我们最常用的是userAgent,该属性可以返回由客户机发送服务器的useragent头部的值。
window对象给我们提供了一个history对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL。
history 对象方法作用back()后退功能forward()前进功能go(参数)前进后退功能,参数如果是1,前进一个页面,如果是-1,后退一个页面history 对象在一般的实际开发中比较少用,但是会在一些 OA 办公系统中见到。