一个元素可以修改它的内容、属性和样式。
一、修改
1.修改属性
(1)字符串类型的HTML标准属性(上篇)
(2)bool类型的HTML标准属性(上篇)
(3)自定义扩展属性
HTML标准中没有规定,程序员根据自身的需要自发添加的属性就是自定义属性。
a:自定义属性经常用于代替id、class或元素选择器,作为查找触发事件的元素的条件;CSS的各种选择器均有自己的不足之处:
i. id选择器,只能选1个;
ii. class选择器,本职工作是定义样式,而样式的修改极其频繁!如果用class选择器查找元素绑定事件,一旦样式类发生变化,程序必然出错;
iii. 元素选择器,因为实现同一种效果,可选的标签名优很多,没有统一规定。如果用元素选择器查找触发事件的元素,绑定事件,则元素一改,功能又立刻出错。
为了解决以上问题,就可以为元素添加自定义属性,当查找触发事件的元素时,用属性选择器[自定义属性]来查找即可。
b:在js中访问自定义扩展属性
要注意自定义属性不能用 . 访问,因为自定义属性是后天程序员自发添加的,在HTML标准中没有规定。所有在内存中的元素对象上,不包含自定义扩展属性!
可以用旧核心DOM:
元素.getAttribute("自定义属性名")
元素.setAttribute("自定义属性名", "属性值")
在新版的HTML5标准中,有新的规定:
①HTML中,所有自定义属性名必须以data-开头:<元素 data-自定义属性名="属性值">
②如果在html中以data-开头了,则js中: 元素.dataset.自定义属性名。
举例:点击按钮,记录次数;
<body>
<button data-n="0" data-btn>click me</button>
<script>
//想点按钮,给n属性的值+1
//DOM 4步
//1. 查找触发事件的元素
// 本例中: 查找带有data-btn属性的一个按钮
var btn = document.querySelector("[data-btn]");
//2. 绑定事件处理函数
btn.onclick = function () {
//3. 查找要修改的元素
//4. 修改元素
//4.1 获取自己身上data-n属性中保存的旧点击次数,转为整数
var n = parseInt(
this.getAttribute("data-n")
);
//4.2 次数+1
n++;
//4.3 再放回去
this.setAttribute("data-n", n);
}
</script>
</body>
2.修改样式
(1)修改内联样式
格式:元素.style.css属性="属性值"
由于有些css属性名中带-,这样会和减法的-号冲突;所以所有带-的css属性名必须去-变驼峰,比如:font-size -> fontSize、background-color -> backgroundColor、list-style-type -> listStyeType。
(2)获取样式
使用元素.style.css属性的方式,只能获取内联样式,无法获得内部或外部样式表中层叠或继承来的css属性值。所以今后要想获得元素任意css属性值,都要获得计算后的样式。计算后的样式就是最终应用到一个元素上的所有css属性的总和。
获取方法分为两步:
i. 先获得计算后的样式对象:var style=getComputedStyle(元素对象);
ii. 从完整的样式对象中只提取个别css属性:style.css属性;
举例:获取h1元素计算后的样式;
<body>
<h1 id="h1" style="color:yellow">Welcome</h1>
<p>Welcome to my web site</p>
<script>
var h1 = document.getElementById("h1");
//用style,获得字体颜色,背景颜色,字体大小
console.log(h1.style.color);
console.log(h1.style.backgroundColor);
console.log(h1.style.fontSize);
//用计算后的样式,获得字体颜色,背景颜色,字体大小
var style = getComputedStyle(h1);
console.log(style.color);
console.log(style.backgroundColor);
console.log(style.fontSize);
</script>
</body>
在实际的项目中,很多效果都需要批量修改一个元素的多个css属性,而.style一句话只能修改一个css属性,如果修改多个css属性时代码会很繁琐;所以只要批量设置一个元素的多个css属性,都用class代替.style。
二、添加/删除元素
1.添加一个新元素
(1)创建一个新的空元素对象:
var 新元素对象=document.createElement("标签名")
//eg:
var a=document.createElement("a");//<a></a>
(2)为新元素添加必要属性:
元素对象.属性名=新值
//eg:
a.innerHTML="go to tmooc";
a.href="http://tmooc.cn";
//<a href=" http://tmooc.cn "> go to tmooc </a>
(3)将新元素添加到DOM树的指定父元素下:
//在父元素下末尾追加新元素
父元素.appendChild(新元素)
//在父元素下插入到一个现有子元素之前
父元素.insertBefore(新元素,现有子元素)
//替换父元素下的一个现有的子元素
父元素.replaceChild(新元素,现有子元素)
举例:创建一个a元素和一个文本框;
<body>
<script>
//向页面中添加一个a
// 1.创建一个空元素
var a = document.createElement("a");
// 2.为新元素添加必要属性
a.innerHTML = "进入百度官网";
a.href = "www.baidu.com";
// 3.将新元素添加到DOM树
document.body.appendChild(a);
//再创建普通的文本框
var input = document.createElement("input");
//将文本框放在a的后边?
document.body.appendChild(input)
//将文本框放在a的前边?
//document.body.insertBefore(input, a);
//用文本框替换a?
//document.body.replaceChild(input,a);
</script>
</body>
2.优化
修改DOM树的内容会导致重排重绘,但频繁重排重绘会降低页面加载的效率,如果父元素已经在页面上了,要添加多个平级子元素,就要借助于文档片段对象来实现。
文档片段是指内存中临时保存多个平级子元素的虚拟父元素,使用方法:
(1)先创建文档片段对象:
var 文档片段对象=document.createDocumentFragment();
(2)将子元素先添加到文档片段对象中
文档片段对象.appendChild(子元素)
(3)将文档片段对象一次性添加到页面上
父元素.appendChild(文档片段对象);
3.删除元素
父元素.removeChild(子元素)
举例:动态生成表格;
<head>
<title>动态创建表格</title>
<meta charset="utf-8" />
<style>
table {
width: 600px;
border-collapse: collapse;
text-align: center;
}
td,
th {
border: 1px solid #ccc
}
</style>
</head>
<body>
<div id="data">
<table>
<thead>
<tr>
<th>姓名</th>
<th>薪资</th>
<th>年龄</th>
<th>删除</th>
</tr>
</thead>
</table>
</div>
<script>
var json = [{
"ename": "Tom",
"salary": 11000,
"age": 25
},
{
"ename": "John",
"salary": 13000,
"age": 28
},
{
"ename": "Mary",
"salary": 12000,
"age": 25
}
];
//1. 先创建一个tbody
var tbody = document.createElement("tbody");
//2. 再遍历json数组中每个员工对象
for (var emp of json) {
//每遍历一个员工对象,就创建一个tr,追加到tbody中
var tr = document.createElement("tr");
tbody.appendChild(tr);
//3. 遍历当前员工对象中每个属性值
for (var key in emp) {
//每遍历一个属性值,就创建一个td,追加到tr中。并设置当前td的内容为当前属性的属性值
var td = document.createElement("td");
tr.appendChild(td);
td.innerHTML = emp[key];
}
//说明当前行的属性值td已经添加完成
//就可以为当前行中再多添加一个td
var td = document.createElement("td");
tr.appendChild(td);
//创建button,放入td中
var btn = document.createElement("button");
btn.innerHTML = "删除";
td.appendChild(btn);
// 为当前按钮绑定单击事件
btn.onclick = function () {
// 点哪个按钮,就让哪个删除
// 查找tbody
var tbody = document.querySelector("#data>table>tbody");
// 获得当前点击的删除按钮
var str = this.parentElement.parentElement;
// 获得员工姓名当前tr下的第一个td
var ename = tr.childNodes[0].innerHTML;
// 先确认,再删除
var result = confirm(`是否继续删除${ename}`);
if (result == true) {
tbody.removeChild(tr);
}
}
}
//3. 整个遍历结束后,再将tbody一次性追加到table中
var table = document.querySelector("#data>table");
table.appendChild(tbody);
</script>
</body>