实际开发中,JavaScript不是在F12控制台中玩的,而是要操作HTML和CSS(复习)。HTML和CSS又被抽象为:
Document Object Model,文档对象模型,是W3C制定的用于访问结构化(structured)文档的标准。包含:
换言之,HTML DOM 是关于如何获取、修改、添加或删除 HTML 元素的标准。(还是增删改查,^_^)
在 HTML DOM 中,所有事物都是节点(node),所有的节点共同构成一颗节点“树”(tree,复习):
以如下HTML代码:
<!DOCTYPE html> <html> <head> <title>源栈欢迎您!</title> <style> .red { color: red; } </style> </head> <body> <h1>源栈欢迎您!</h1> <div> <p>HTML DOM结构示范</p> <p id='mole'> 先学习,后付费。见: <a name="yz" href="https://17bang.ren" target="_blank">一起帮·源栈课堂</a> 。 </p> <p class="red"> 但我们认为,将其图示为 <strong style="color:darkblue">嵌套结构</strong> 更容易理解。 </p> <img name="yz" src="/images/源栈小九-small.png" alt="温柔大方的小九姐姐" /> <quote></quote> </div> <div> <a href="#">QQ:2282636022</a> </div> </body> </html>
实际上就是这样一个“嵌套”结构:
#体会:所有节点组成一颗树!
树中的所有节点均可通过 JavaScript 进行访问、修改、创建或删除:这就是JavaScript的基本功能之一!
一般从document开始,以getElement开头,包括:
document.getElementById('mole')注意:JavaScript中也可以(不推荐/不规范地)直接通过点Id拿到该元素,比如:
window.mole这会造成一些费解的问题,详见后文.submit()不是方法
document.getElementsByTagName('p')同样的,一些浏览器也支持点出一些特定的标签,比如form
document.forms //注意复数形式
注意:
在已获取的元素上可以进一步的使用getElementXXX(),比如:
//不要忘了[0] document.getElementsByTagName('div')[0].getElementsByTagName('a')
但通常我们利用一些内置的(build-in)方法/属性,通过父/子/兄弟……关系,找到:
注意区分:node(节点)和element(元素),节点包含text/comment等类型……
PS:在ES6中还借鉴JQuery选择器(后文详述),引入了querySelector()
在找到DOM元素后,对DOM元素进行操作,获取/修改:
演示区别:
注意:
document.getElementsByTagName('p')[0].innerHTML = "<a href='https://17bang.ren/'>一起帮·源栈课堂</a>"
document.getElementsByTagName('img')[0].getAttribute("src")
document.getElementsByTagName('img')[0].setAttribute("src", "/images/源栈小九.png" )
也可以直接点(.)出:
document.getElementsByTagName('img')[0].src
但是,这两者的结果有所不同(演示)。我们可以理解为:
延伸阅读:JQuery的attr()和prop()
此外,.出的属性还可以再进一步的.出它的子属性,比如:
document.getElementsByTagName('strong')[0].style.fontSize = "50px"
注意JavaScript中变量/字段/属性等命名不能包含中划线(-),所以CSS中的font-size变成了fontSize。
有一个固定的套路:
let quote = document.createElement('quote'); //<quote></quote> quote.setAttribute('id', 'lucky-stack'); //<quote id='lucky-stack'></quote> quote.style.cssFloat = 'right'; //<quote id='lucky-stack' style='float:right'></quote> let text = document.createTextNode('一起帮·源栈'); quote.appendChild(text); //<quote id='lucky-stack' style='float:right'>一起帮·源栈</quote> document.getElementsByTagName('div')[0].appendChild(quote);
或者可以用它替换(replace)其他DOM元素
先将div抽取出来:
let div = document.getElementsByTagName('div')[0];演示:
div.children[1].replaceWith(quote);
div.replaceChild(quote, div.children[1] );
remove引导的两个常用方法:
div.children[1].remove()
div.removeChild(div.children[1])
注意:实际开发中,删除(再也没了,不能再通过document.出)和隐藏是不一样的,不要混淆:
div.style.display="none"; div.style.visibility = "hidden";
div.hidden = true
属性还可以使用removeAttribute()删除,也可以说是元素的“改”了……
不认识下面内容的同学自行复习:
<form> <label>用户名:<input type="text" name="username" /></label><br /> <label>密码:<input type="password" name="password" /></label><br /> <label>确认密码:<input type="password" /></label><br /> <div> <label>学费支付:</label> <label><input type="radio" value="order" name="fee"/>先付费</label> <label><input type="radio" value="payoff" name="fee"/>后付费</label> </div> <div> <label>学习课程:</label> <select name="courses"> <option value="front">前端</option> <option value="backend">后端</option> <option value="database">数据库</option> </select> </div> <div> <label>学习计划:</label><br /> <textarea name="study-plan"></textarea> </div> <input type="submit" value="提交" /> <input type="reset" value="重置" /> <label><input type="checkbox" id="remember"/>记住我</label> </form>
使用value属性:
checkbox / radio:可以通过其checked值判断它是否被用户选中。演示:
document.getElementsByTagName("input")[3].checked理解:获取label中的checkbox,O(∩_∩)O哈哈~
document.getElementsByTagName("form")[0].lastElementChild.getElementsByTagName("input")[0].checked
但对于select而言,就需要使用option的selected属性,判断其是否被选中。
有时候我们需要获取的是选中项的文本(不是value):
{ let options = document.getElementsByTagName("select")[0].children; for (let i = 0; i < options.length; i++) { if (options[i].selected) { console.log(options[i].innerHTML); } } }
观察课堂演示,@想一想@:最外层{}的作用是什么?
还有一种更简单的方法,利用select的selectedIndex获取被选中项的下标/索引,然后利用children[selectedIndex]:
document.getElementsByTagName("select")[0].selectedIndex;
都是禁用。但复习:两者的区别
演示:获取和设置
注意:readOnly的O是大写。
<input type="file" id="icon" multiple />注意不能直接使用value,否则得到的只能是文件名(路径)
要拿到文件,需要使用files属性:(详见:更多文件内容操作)
document.getElementById("icon").files
利用JavaScript完成DOM操作,实际上分成两个部分:
这两者是独立的:所以两者之间的交互天然是有消耗的。
注意:两个独立“模块”之间的消耗是最大的,常常是性能瓶颈。同理的还有数据库连接、HTTP连接……
应尽量避免:
本章作业名为:dom.html
多快好省!前端后端,线上线下,名师精讲
更多了解 加: