JavaScript分为 ECMAScript,BOM,DOM。
BOM:是指浏览器对象模型,使JavaScript有能力与浏览器进行对象。
DOM:是指文档对象模型,通过它,可以访问HTML文档的所有元素。
一、浏览器对象
JavaScript可以获取浏览器提供的很多对象,并并进行操作。
window
window对象不但充当全局作用域,而且表示浏览器窗口。
window对象的属性:
1. innerWidth
和innerHeight
属性,可以获取浏览器窗口的内部宽度和高度。内部宽高是指除去菜单栏、工具栏、边框等占位元素后,用于显示网页的净宽高。
2. outerWidth
和outerHeight
属性,可以获取浏览器窗口的整个宽高。
window对象的方法:
window.open() 打开一个新的window窗口
window.close() 关闭当前的window窗口
navigator
navigator对象表示浏览器的信息,最常用的属性如下:
navigator.appName 浏览器名称;
navigator.appVersion 浏览器版本;
navigator.language 浏览器设置的语言;
navigator.platform 操作系统类型;
navigator.userAgent 浏览器设定的User-Agent字符串
screen
screen对象表示屏幕信息,常用的属性如下:
screen.width 屏幕宽度,以像素为单位;
screen.height 屏幕高度,以像素为单位;
screen.availWidth 可用的屏幕宽度;
screen.availHeight 可用的屏幕高度;
screen.colorDepth 返回颜色位数,如8、16、24。
history
这个对象属于历史遗留对象,对于现代Web页面来说,由于大量使用AJAX和页面交互,简单粗暴地调用history.back()
可能会让用户感到非常愤怒。
新手开始设计Web页面时喜欢在登录页登录成功时调用history.back()
,试图回到登录前的页面。这是一种错误的方法。
任何情况,你都不应该使用history
这个对象了。
location
location对象用于获得当前页面的地址(URL),也可以把浏览器重定向到新的页面。
location.href 获取当前页面的url
location.href = "https://www.baidu.com" 页面跳转到百度
location.reload() 重新加载页面
弹出框
可以在 JavaScript 中创建三种消息框:警告框、确认框、提示框。
警告框
警告框经常用于确保用户可以得到某些信息。
当警告框出现后,用户需要点击确定按钮才能继续进行操作。
语法:alert("这是警告框")
确认框
确认框用于使用户可以验证或者接受某些信息。
当确认框出现后,用户需要点击确定或者取消按钮才能继续进行操作。
如果用户点击确认,那么返回值为 true。如果用户点击取消,那么返回值为 false。
语法:confirm("这是确认框?")
提示框
提示框经常用于提示用户在进入页面前输入某个值。
当提示框出现后,用户需要输入某个值,然后点击确认或取消按钮才能继续操纵。
如果用户点击确认,那么返回值为输入的值。如果用户点击取消,那么返回值为 null。
语法:prompt("请输入内容", "默认内容")
计时相关
通过使用JavaScript,我们可以在一段时间后再执行代码,而不是在函数在调用后立即执行。
setTimeout()
语法:var t = setTimeout("JS语句或函数", 毫秒)
第一个参数可以是函数调用或普通的JS语句,第二个参数单位是毫秒,就是过了多少毫秒,执行第一个参数给定的函数或语句。
clearTimeout()
语法:clearTimeout(setTimeout_variable)
// 在指定时间之后执行一次相应函数 var timer = setTimeout(function(){alert("abc");}, 5000) // 取消setTimeout设置 clearTimeout(timer);
setInterval()
setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。
setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。
语法:setInterval("JS语句", 时间间隔)
clearInterval()
clearInterval() 方法可取消由 setInterval() 设置的 timeout。
clearInterval() 方法的参数必须是由 setInterval() 返回的 ID 值。
语法:clearInterval(setinterval返回的ID值)
var timer = setInterval(function(){console.log("abc");}, 3000) // 取消setInterval设置 clearInterval(timer);
二、 文档对象
DOM(Document Object Model)是一套对文档的内容进行抽象和概念化的方法。
由于HTML文档被浏览器解析后就是一棵DOM树,要改变HTML的结构,可以通过JavaScript操作来操作DOM。
操作DOM节点实际上就是以下几个操作:
- 更新:更新该DOM节点的内容,相当于更新了该DOM节点表示的HTML的内容;
- 遍历:遍历该DOM节点下的子节点,以便进行进一步操作;
- 添加:在该DOM节点下新增一个子节点,相当于动态增加了一个HTML节点;
- 删除:将该节点从HTML中删除,相当于删掉了该DOM节点的内容以及它包含的所有子节点。
查找
在操作一个DOM节点前,我们需要通过各种方式拿到这个节点。常用的方法有document.getElementById(),document.getElementsByTagName(),以及CSS选择器getElementsByClassName。
由于ID在HTML文档中是唯一的,所以document.getElementById()
可以直接定位唯一的一个DOM节点。document.getElementsByTagName()
和document.getElementsByClassName()
总是返回一组DOM节点。要精确地选择DOM,可以先定位父节点,再从父节点开始选择,以缩小范围。
其他间接查找方法:
- parentElement 父节点标签元素
- children 所有子标签
- firstElementChild 第一个子标签元素
- lastElementChild 最后一个子标签元素
- nextElementSibling 下一个兄弟标签元素
- previousElementSibling 上一个兄弟标签元素
<!--用于测试的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>DOM操作练习</title> </head> <body> <div class="outer-div1"> <div class="inner-div1"> 内层div内容 </div> </div> <div class="outer-div2">外层div内容</div> <div class="outer-div2"> <div class="inner-div2"> <p id="inner-p1">内部段落一</p> <p id="inner-p2">内部段落二</p> </div> <div class="inner-div3"> <p id="inner-p3">内部段落三</p> </div> </div> <a href="https://www.163.com">网易</a> </body> </html>
更新
两种方法:1. innerHTML 2. innerText
插入
两种方法:1. appendChild 2. insertBefore
appendChild
当我们获得了某个DOM节点,想在这个DOM节点内插入新的DOM,应该如何做?
如果这个DOM节点是空的,例如,<div></div>
,那么,直接使用innerHTML = '<span>child</span>'
就可以修改DOM节点的内容,相当于“插入”了新的DOM节点。
如果这个DOM节点不是空的,那就不能这么做,因为innerHTML
会直接替换掉原来的所有子节点。
有两个办法可以插入新的节点。一个是使用appendChild
,把一个子节点添加到父节点的最后一个子节点。例如:
<!-- HTML结构 --> <p id="js">JavaScript</p> <div id="list"> <p id="java">Java</p> <p id="python">Python</p> <p id="scheme">Scheme</p> </div>
把<p id="js">JavaScript</p>
添加到<div id="list">
的最后一项:
var js = document.getElementById('js'), list = document.getElementById('list'); list.appendChild(js);
操作之后,HTML文档的变化:
<!-- HTML结构 --> <div id="list"> <p id="java">Java</p> <p id="python">Python</p> <p id="scheme">Scheme</p> <p id="js">JavaScript</p> </div>
因为我们插入的js
节点已经存在于当前的文档树,因此这个节点首先会从原先的位置删除,再插入到新的位置。
insertBefore
如果我们要把子节点插入到指定的位置怎么办?可以使用parentElement.insertBefore(newElement, referenceElement);
,子节点会插入到referenceElement
之前。
还是以上面的HTML为例,假定我们要把Haskell
插入到Python
之前:
<!-- HTML结构 --> <div id="list"> <p id="java">Java</p> <p id="python">Python</p> <p id="scheme">Scheme</p> </div>
可以这么写:
var list = document.getElementById('list'), ref = document.getElementById('python'), haskell = document.createElement('p'); haskell.id = 'haskell'; haskell.innerText = 'Haskell'; list.insertBefore(haskell, ref);
新的HTML结构如下:
<!-- HTML结构 --> <div id="list"> <p id="java">Java</p> <p id="haskell">Haskell</p> <p id="python">Python</p> <p id="scheme">Scheme</p> </div>
使用insertBefore
重点是要拿到一个“参考子节点”的引用。
删除
要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的removeChild
把自己删掉:
// 拿到待删除节点: var self = document.getElementById('to-be-removed'); // 拿到父节点: var parent = self.parentElement; // 删除: var removed = parent.removeChild(self); removed === self; // true
注意到删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置。
当你遍历一个父节点的子节点并进行删除操作时,要注意,children
属性是一个只读属性,并且它在子节点变化时会实时更新。
例如,对于如下HTML结构:
<div id="parent"> <p>First</p> <p>Second</p> </div>
当我们用如下代码删除子节点时:
var parent = document.getElementById('parent'); parent.removeChild(parent.children[0]); parent.removeChild(parent.children[1]); // <-- 浏览器报错
浏览器报错:parent.children[1]
不是一个有效的节点。原因就在于,当<p>First</p>
节点被删除后,parent.children
的节点数量已经从2变为了1,索引[1]
已经不存在了。
因此,删除多个节点时,要注意children
属性时刻都在变化。
操作表单
用JavaScript操作表单和操作DOM是类似的,因为表单本身也是DOM树。
不过表单的输入框、下拉框等可以接收用户输入,所以用JavaScript来操作表单,可以获得用户输入的内容,或者对一个输入框设置新的内容。
HTML表单的输入控件主要有以下几种:
- 文本框,对应的<input type="text">,用于输入文本;
- 口令框,对应的<input type="password">
,用于输入口令;
- 单选框,对应的<input type="radio">
,用于选择一项;
- 复选框,对应的<input type="checkbox">
,用于选择多项;
- 下拉框,对应的<select>,用于选择一项;
- 隐藏文本,对应的<input type="hidden">,用户不可见,但表单提交时会把隐藏文本发送到服务器。
获取值
如果我们获得了一个<input>
节点的引用,就可以直接调用value
获得对应的用户输入值:
// <input type="text" id="email"> var input = document.getElementById('email'); input.value; // '用户输入的值'
这种方式可以应用于text
、password
、hidden
以及select
。但是,对于单选框和复选框,value
属性返回的永远是HTML预设的值,而我们需要获得的实际是用户是否“勾上了”选项,所以应该用checked
判断:
// <label><input type="radio" name="weekday" id="monday" value="1"> Monday</label> // <label><input type="radio" name="weekday" id="tuesday" value="2"> Tuesday</label> var mon = document.getElementById('monday'); var tue = document.getElementById('tuesday'); mon.value; // '1' tue.value; // '2' mon.checked; // true或者false tue.checked; // true或者false
设置值
设置值和获取值类似,对于text
、password
、hidden
以及select
,直接设置value
就可以:
// <input type="text" id="email"> var input = document.getElementById('email'); input.value = 'test@example.com'; // 文本框的内容已更新
对于单选框和复选框,设置checked
为true
或false
即可。
练习代码:
// 测试使用代码
<!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> </head> <body> <div> <p> <input type="text" name="username" id="uname"> </p> <p> <input type="password" name="password" id="pwd"> </p> <p> <input type="radio" id="r1"> </p> <p> <input type="checkbox" id="c1"> </p> <p> <select name="city" id="cid"> <option value="1">北京</option> <option value="2">上海</option> <option value="3">广州</option> </select> </p> </div> </body> </html>
操作截图:
以上就是关于BOM和DOM学习的记录。大部分内容摘自廖雪峰老师的JavaScript教程博客。
参考文章:
https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/0014344997647015f03abc1bb5f46129a7526292a12ab26000
https://www.cnblogs.com/liwenzhou/p/8011504.html