一. 修改:
1. 获取或修改元素的内容:
2. 获取或修改元素的属性:
(1). 获取或修改字符串格式的HTML标准属性
(2). 获取或修改bool类型的HTML标准属性
(3). 获取或修改自定义扩展属性的值:
a. 什么是自定义扩展属性: HTML标准中没有规定的,程序员根据自己的需要,自发添加的自定义名称的属性
b. 何时: 2个用途
1). 代替其他选择器,作为选择触发事件的元素的条件:
i. 其他选择器的问题:
id选择器只能查找一个元素
元素选择器受HTML元素修改的影响,因为实现同一个效果,不一定都用一种元素。如果页面元素发生改变,也会影响js程序
比如: 实现按钮: a, input, button, div, span, ...
class选择器的缺点是class本职工作不是为元素添加事件,而是修改元素的css样式!class在修改样式时,同样变化也很频繁!class只要一变,也可能影响js代码
ii. 问题: 如何保证HTML中元素变化和class变化不影响已经写好的js呢?!
iii. 解决: 自定义扩展属性:
iv. 好的榜样: bootstrap: 都是用自定义扩展属性为元素添加交互行为
<元素 data-toggle="dropdown">
为当前元素添加交互行为
2). 在客户端网页中临时缓存业务数据,减少向服务器反复发送请求的次数,提高加载效率!
i. 问题: 在首次加载页面时,只拿到首屏所需的数据,没有为之后的切换,提前准备数据。结果,每次切换都要重新向服务器发送请求,请求新的数据——大量增加了请求的次数,降低加载效率和用户体验
ii. 解决: 首屏加载时,就要考虑后边变化时所需的数据,一次性将后续变化所需的所有数据都请求到客户端,缓存在网页中HTML元素的自定义属性上。当后续发生变化时,可从当前元素自己身上获得提前缓存的数据,无需重新向服务器发送ajax请求。
c. 如何使用自定义扩展属性:
1). 为HTML元素添加自定义扩展属性
i. 不标准做法: <元素 自定义属性名="属性值">
ii. 标准做法: HTML5标准中规定所有自定义扩展属性应该都加上data-前缀
比如: <button data-myclick="tj">
<img src="img/1s.jpg" data-lg="img/1L.jpg">
2). 获取或修改自定义扩展属性值:
i. 因为自定义扩展属性不是HTML标准属性,所以浏览器不认识!所以在扫描HTML元素时,就不会将自定义扩展属性添加到内存中的元素对象上!
ii. 所以,自定义扩展属性绝对不能用.访问!
iii. 两种方式可以获取或修改自定义扩展属性:
①. 核心DOM的getAttribute()和setAttribute()可以访问元素的自定义扩展属性
强调: 使用getAttribute()和setAttribute()访问自定义扩展属性时,必须写完整属性名,也就是必须加data-前缀
②. HTML5规定: 所有data-开头的自定义扩展属性,都可用:
元素.dataset.属性名
数据的集合 —— 所有data-开头的属性值的集合
强调: 使用dataset属性,访问自定义扩展属性时,dataset后的属性名不用加data-前缀
其中: 元素的dataset属性,会自动收集当前元素在HTML中的所有data-开头的自定义扩展属性
3). 查找带有自定义扩展属性的元素: 用属性选择器
var 元素=任意父元素.querySelector("[data-属性名=属性值]")
var 类数组对象=任意父元素.querySelectorAll("[data-属性名=属性值]")
补: 如果将a做成一个死链接: 只有a的样子,没有a的功能
错误: <a href=""> 刷新页面
错误: <a href="#"> 回到顶部
正确: <a href="javascript:;">
其中: javascript意思是不让a跳转页面,而是在当前页面执行一条js语句
比如: <a href="javascript:alert('疼!')">
其中: ; 是一条什么都不做的空语句!
3. 获取或修改元素的样式:
(1). 修改元素的内联样式: 元素.style.css属性="属性值"
a. 强调: 如果要修改的css属性名带-,应该去横线变驼峰命名!
1). 驼峰: 首字母小写,之后每个单词首字母大写!
2). 比如: z-index -> zIndex
list-style-type -> listStyleType
background-color -> backgroundColor
b. 强调: 如果css属性值带单位: 比如px,则必须加px单位!不加,则属性值无效!
c. 只能修改内联样式!通过内联样式来覆盖样式表中的样式!
无权修改样式表中多个元素共用的样式!
(2). 获取元素的完整样式:
1). 问题: 元素.style只代表内联样式,获取时,也只能获得内联样式!
2). 解决: 如果想获得一个元素上最终应用的所有样式,应该获得计算后的样式
i. 什么是计算后的样式: 最终应用到这个元素上的样式表中的样式以及内联样式等所有样式属性的集合!
ii. 何时: 今后,只要想获得一个元素的某个css属性值,都要用计算后的样式
iii. 如何: 2步
①先获得计算后的样式的完整对象
var style=getComputedStyle(元素对象)
获得 计算后的样式
意为: 获得指定元素的计算后的样式的集合对象
②再从计算后的样式集合对象中获得想要的css属性值
style.css属性
3). 问题: 能否通过计算后的样式,修改外部的样式表中的样式!
答: 计算后的样式都是只读的!禁止修改!
如果非要修改,应该修改h1的内联样式,来覆盖外部样式表中的样式.
(3). 示例: 获得元素计算后的样式
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> h1{
} </style> </head> <body> <h1 id="h1" style="color:yellow">welcome</h1> <p>welcome to my web site</p> <script> var h1=document.getElementById("h1"); //先获得h1元素对象最终应用的所有样式属性的集合 var style=getComputedStyle(h1); //想获得h1的color属性 //不好的做法: console.log(h1.style.color) console.log(style.color) //想获得h1的backgroundColor属性 //不好的做法: console.log(h1.style.backgroundColor) console.log(style.backgroundColor) //想获得h1的fontSize属性 //不好的做法: console.log(h1.style.fontSize) console.log(style.fontSize) //想通过style对象修改h1的字体为64px style.fontSize="64px"; </script> </body> |
(3). 批量修改一个元素的多个css属性:
a.元素.style.css属性="新值" 缺点: 2个:
1). 一句话只能修改一个css属性,如果要同时修改一个元素的多个css属性代码会很繁琐!
2). 频繁修改css属性,会导致重排重绘!降低网页加载的效率
i. 网页加载过程:
ii. 重排重绘:
b. 解决: DOM优化: 能用一句话修改的,就绝不用多句话修改:
1). 元素.style.backgroundColor="blue"
元素.style.display="none"
以上代码会导致两次重排重绘
其实可合并为:
元素.style.cssText=" display:none"
修改之后,只需要一次重排重绘!
但是依然要写出每个css属性,所有代码繁琐!
2). 用修改class代替修改多个css属性
i. 先在css中定义一系列class,作为备用的样式
ii. 用程序控制何时使用哪个class到元素上!
二. 添加删除元素:
1. 添加元素: 3步:
(1). 创建新的空元素
var 新元素对象=document.createElement("元素名")
创建 元素
意为创建一个新的指定名称的空元素
比如: var a=document.createElement("a")
结果: <a></a>
问题: 缺关键属性,用户无法正常使用
(2). 为新元素添加必要属性
a.href="http://tmooc.cn";
a.innerHTML="go to tmoocn"
<a href=" http://tmooc.cn "> go to tmoocn </a>
问题: 没有在DOM树上,用户看不见!
(3). 将新元素添加到DOM树上
a. 在指定父元素下的所有子元素末尾追加
父元素.appendChild(新子元素)
追加
b. 在指定父元素下的某个子元素之前插入
父元素.insertBefore(新元素, 现有子元素)
插入xxx之前
c. 在指定父元素下,替换某个子元素
父元素.replaceChild(新元素, 现有子元素)
替换xxx个孩子