0%

JavaScript|DOM编程艺术

image-20210904233422857

DOM

DOM的构成

1.文档:DOM的”D”

“D”即”document”,中文为文档,但一个网页加载到web浏览器时,就会生成一份网页的结构性的文档,文档中包含着许多对象,对象之间的关系又构成了一个模型。

2.对象:DOM的”O”

“O”即”object”,中文为对象。对象就是一种独立的数据集合,所以文档内容就是一个个对象的属性方法构成的。

3.模型:DOM的”M”

”M“即”model“,中文为模型。模型的含义是某种事物的表现形式。浏览器会为我们提供当前网页的地图,而我们就可以用js去读这份地图

至此,我们不难理解,所谓DOM就是把网页的文档内容表示成了一棵树,有树干和树枝的从属关系,而我们就可以顺藤摸瓜地了解整棵树

从html的角度来看,标签的包含关系和并列关系就是这样类似的模型

4.节点

更加准确地描述DOM,应该要引入节点这个概念,文档是由节点构成的集合。每个节点都是一个对象

一份DOM包括的节点

  • 元素节点,对应html的标签层级关系,其中元素就是这棵节点树的根元素
  • 文本节点,对应html的文本,所以文本节点是在元素节点内部的
  • 属性节点,对应html标签的属性信息,所以所以属性节点也是包含在元素节点内的

DOM与HTML的连结

在css层叠样式表中,我们可以使用class属性(为元素分组)和id元素(给元素唯一的认证)实现html和css的连结,而DOM与HTML的连结与此类似。

每个节点都是一个对象,我们通过js选择器来定位节点,然后修改节点的属性和方法来实现交互

1.js选择器

与css的选择器类似,Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问并交互

选择方法:

1
2
3
4
5
6
7
8
9
10
11
12
 //不常用的选择方法: 

document.getElementsByTagName(); // 标签,有时太多个要用上数组

document.getElementsById(); // 通过id寻找标签

document.getElementsByClassName(); //通过class寻找标签

//常用且与css选择器非常一致的方法:
document.querySelector(); //获取匹配的第一个元素!

document.querySelectorAll(); //获取元素集合,

简介用法:

1
var title= document.querySelector(“h1”);    
2.document与类的交互

(1)使用classList函数

为标签增加了一个类,类里面有属性

1
document.getElementById("myDIV").classList.add("mystyle");

常用函数:

1
2
3
4
5
add(class1, class2, ...) // 在元素中添加一个或多个类名

remove(class1, class2, ...) //移除元素中一个或多个类名

toggle(class, true|false) //在元素中切换类名,存在则移除,不存在则添加,用于某种开关切换

(2)使用attribute函数,attributes 属性返回指定节点属性的集合(不仅可以修改类还可以修改其他参数)

1
document.querySelector("li").attributes.class.value="title";  // 将li的class类型改成了title
1
document.querySelector("li").setAttribute("class","title"); //为li添加class=“title”的属性

(3)getAttribute与setAttribute

定位找到对应节点后,我们可以用getAttribute查询其中的元素中各种属性的值,而setAttribute则可以更改这些值,和上述更改类的方法类似

3.与文本内容的交互

(1)html提供的方法

1
2
3
document.querySelector("h1").innerHTML="Goodbye";

document.querySelector("h1").innerHTML="<em>Goodbye</em>>";

//修改文本的内容,甚至可以写入html代码修改文本样式

但值得注意的是,innerHTML属性只适用于html文档,浏览器在执行xhtml文档时不会执行innerHTML属性

1
document.querySelector("h1").textContent="Goodbye";

//只能修改文本内容

(2)DOM方法

DOM方法的核心是插入新的子节点,再添加文本属性。

  • createElement创造一个新的元素节点

  • appendChild为元素子节点找个父节点

  • createTextNode创造文本节点

  • appendChild为文本子节点找个父节点

    实例:

    1
    2
    3
    4
    5
    6
    7
    var para = document.creatElement("p");//创造一个元素节点p
    var testdiv = document.getElementById("testdiv") ; //定位父节点
    testdiv.appendChild(para);//确定父子关系
    var text = document.creatTextNode("Hello");
    //创造文本节点
    para.appendChild(text);//把文本节点加到元素节点中

(3)补充节点定位方案

insertBefore()方法

把一个新元素插到一个现有元素前面

1
paretElement.insertBefore(newElement,targetElement)
  • 想插入的新元素newElement
  • 现有元素targetElement
  • 两元素共同父元素

insertAfter()方法

事实上DOM并没有这个函数,所以需要自己创建

1
2
3
4
5
6
function insertAfternewElementtargetElement
var parent targetElement.parentNode
if (parent.lastchild == targetElement )(
parent.appendchild(newElement);
else
parent.insertBefore(newElement, targetElement.nextsibling);
4.更改元素样式

(1)更改内嵌style法

文档内的每个元素都是一个对象,它们的style属性也是一个对象

1
document.getElementById("id").style.property="值"

样式表:https://www.w3school.com.cn/jsref/dom_obj_style.asp

使用案例:

获取style属性中的font-family值

1
2
3
4
5
6
7
8
9
10
11
12
13
<meta http-equiv=“content-type“content=“text/html;charset=utf-8/>
<title>example</title>
<script type = "text/javascript">
window.onload= function (){
var para document.getElementById("example")
alert(The font family is“+ para style.fontFamily);
</script>
<p id=“example“style="color: grey;
font-family: 'Arial',sans-serif;">
An example of a paragraph
</p〉
</body>
</html>

可以获取定位元素节点通过改变值来更改样式

变量简化语句

1
2
var buttoncolor = document.
(".game button").style.backgroundColor;//错误示范
1
var buttoncolor = document.querySelector(".game button").style;//到此为止

数组的使用

1
2
3
4
5
var buttoncolor = document.querySelector(".game button").style;

var colo = ["yellow", "gold", "blue", "grey", "brown", "black"];

buttoncolor.backgroundColor = colo[2];

(2)js刷新元素class法

style属性采用“Camel记号”来记名,但只能检索到内嵌载html中的样式信息,而无法读取到外部css的样式信息

一些涉及到大量规律性样式的,css也许很难实现,但用js更改样式的方法则很简单

js刷新元素class法不在是在行为层(js)更改样式,而是在表现层(css)更改。这里就要用到className属性来替换元素的class

1
2
3
4
5
6
7
8
9
function styleHeaderSiblings(){
if(Document.getElementsBy TagName)return false;
var headers = document.getElementsBy TagName(“h1”);
for (var i=0; i<headers.length; i++)(
var elem =getNextElementheaders[i]. nextSibling)
elem.className= "intro";
}
}

以上代码是class属性覆盖,若要实现追加,则需要自己写一个函数

追加方法:

1
elem.className +=" intro"

注意:intro的第一个字符是空格

实例:

1
2
3
4
5
6
7
8
9
10
function addClass(element, value){
if (element. className){
element.className.value
if else {
newClassName.element.className;
newClassName+=" ";
newClassName+= value;
element className newClassName;
}
}

这样的方案使网页的行为层和表示层彻底分离,js只刷新了className属性,而style属性不受任何影响

再对函数抽象化有:

1
2
3
4
5
6
function styleElementSiblings(tag, theclass)(
if (!document. getByTagName)return false;
var elems=document.getElementsByTagName (tag);
for (var i=0; i<elems.length; i++)
var elem= getNextElement(elems[i]. nextSibling)
addclass(elem, theclass);

一个通用的样式变换模板就形成了

5.事件响应

(1)css事件

css和js在事件响应上有所重叠的部分——css的hover等伪class属性允许我们根据html元素的状态来改变样式,而DOM也可以通过onmouseover等事件处理函数来实现。

如果只是改变某个元素的呈现效果,css就够用了

1
2
3
a:hover{
color:#c60;
}

如果想改变某个元素的行为,则更多地使用DOM

1
2
3
4
5
6
7
8
9
var rows = document.getElementbuTagName("a");
for(var i=0; i<rows.length; i++){
rows[i].onmouseover = function(){
this.style.color = "#c60"
}
rows[i].onmouseover = function(){
this.style.color = "black"
}
}

(2)用功能制造事件

1
2
document.querySelector("button").addEventlistener("click",function(){
document.querySelector("h1").classList.toggle("title");})

选择一个标签,给它一个事件,并赋予功能,功能是修改另一个标签——这是最简单的交互,以后会更详细地讲js的事件

DOM小结

在需要对文档里的现有信息进行检索时,以下DOM方法最有用:

  • getElementById()
  • getElementByTagName ()
  • getAttribute()

在需要把信息添加到文档里去时,以下DOM方法最有用:

  • createElement()
  • createTextNode()
  • appendChild()
  • insertBefore()
  • setAttribute()