实际开发中,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
多快好省!前端后端,线上线下,名师精讲
更多了解 加: