DOM对象

  • D(文档)可以理解为整个 Web加载的网页文档
  • O(对象)可以理解为类似 window 对象之类的东西,可以调用属性和方法,这里我们说的是 document 对象
  • M(模型)可以理解为网页文档的树型结构

文档对象模型 (DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将web页面和脚本或程序语言连接起来。

DOM接口

javascript能够通过DOM接口实现以下功能

  • JavaScript 能够改变页面中的所有 HTML 元素
  • JavaScript 能够改变页面中的所有 HTML 属性
  • JavaScript 能够改变页面中的所有 CSS 样式
  • JavaScript 能够对页面中的所有事件做出反应
  • 每个 DOM 对象都包括属性,方法和事件。

DOM结构

加载 HTML 页面时,Web浏览器生成一个树型结构,用来表示页面内部结构。DOM 将 这种树型结构理解为由节点组成。

获取元素

方法名 作用
getElementById() 根据元素的id属性,获取该元素节点.
getElementsByTagName() 获取相同标签名的所有元素的集合
getElementsByName() 获取拥有相同name属性的节点列表
getAttribute() 获取特定元素节点属性的值
getElementsByClassName 获取拥有相同class属性的节点列表
  1. getElementById() 根据元素的id属性,获取该元素节点.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        // 在元素解析出来之前试图去获取该元素,得到的结果是null
        var app = document.getElementById("app");
        console.info(app);
    </script>
</head>
<body>
    <div id="app"></div>
</body>
</html>

上面问题解决问题

  1. 将script标签移动的body之后
  2. 使用window.onload方法加载
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function(){
            var app = document.getElementById("app");
            console.info(app);
        }
    </script>
</head>
<body>
    <div id="app"></div>
</body>
<script>
    var app = document.getElementById("app");
    console.info(app);
</script>
</html>

onload

window.onload方法会等待页面的所有资源都加载完成之后才会执行.

在下面的例子中,我们加载一张一亿像素的世界地图,如果网速不是特别快的情况下会比较明显地,只有地图资源加载完了,onload里的方法才会被执行


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function(){
           console.log("onload");
        }
    </script>
</head>
<body>
    <div id="app">
        <img src="http://www.onegreen.net/maps/Upload_maps/201711/2017110917545743.jpg" alt="">
    </div>
</body>

</html>
  1. getElementsByTagName() 获取相同标签名的所有元素的集合
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   <ul>
       <li>html</li>
       <li>css</li>
       <li>js</li>
   </ul>
</body>
<script>
    var list = document.getElementsByTagName("li");
    console.log(list)
</script>
</html>

从上图中,我们可以看出这个集合和数组的结构是一样.我们可以尝试用数组的方式来获取这个集合里的元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   <ul>
       <li>html</li>
       <li>css</li>
       <li>js</li>
   </ul>
</body>
<script>
    var list = document.getElementsByTagName("li");
    for(var i=0;i<list.length;i++){
        var li = list[i];
        console.log("元素",li);
    }
</script>
</html>

getElementsByClassName

获取拥有相同class属性的节点列表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <span class="title">html列表</span>
    <p>html好简单</p>
    <span class="title">css列表</span>
    <p>css好漂亮</p>
    <span class="title">javascript</span>
    <p>javascript好牛逼哦</p>
</body>
<script>
    var titles = document.getElementsByClassName("title");
    console.log(titles);
</script>
</html>

虽然getElementsByClassName()和getElementsByTagName()获取到的都是类似数组的元素集合.但是有些数组方法是不可以直接使用的

下面的例子报错

<script>
    var list = document.getElementsByTagName("li");
    list.forEach(function(item){
        console.log(item);
    })
</script>
TypeError: list.forEach is not a function

getAttribute

获取元素节点的指定属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app" class="myapp" name="firstApp" ></div>
</body>
<script>
   var app = document.getElementById("app");
   console.log(app.getAttribute("name")); //firstApp
   console.log(app.getAttribute("class")); //myapp
   console.log(app.getAttribute("id")); //app
</script>
</html>

DOM节点

节点类型分为:

  • 元素节点
  • 属性节点
  • 文本节点

DOM节点有三个主要的属性:

  • nodeName 节点名称,每种节点都有名称
  • nodeType 节点类型,1 元素节点 ,2 属性节点,3文本节点
  • nodeValue 节点值
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app" class="myapp" name="firstApp" ></div>
    <button value="click">点击</button>
</body>
<script>
   var app = document.getElementById("app");
   console.log(app.nodeType);//1
   console.log(app.nodeName);//DIV
   console.log(app.nodeValue);//null

   var attrs = app.attributes[0];
    console.log(attrs.nodeType);//2
    console.log(attrs.nodeValue);//app
    console.log(attrs.nodeName);//id

    var button = document.getElementsByTagName("button")[0].childNodes[0];
    console.log(button.nodeType);//3
   console.log(button.nodeName);//#text
   console.log(button.nodeValue);//点击
</script>
</html>

层次节点属性

属性名 作用
childNodes 获取当前元素的所有子节点
firstChild 获取当前元素的第一个子节点
lastChild 获取当前元素的最后一个子节点
parentNode 获取当前元素的父级节点
previousSibling 获取同级元素的前一个节点
previousElementSibling 获取同级元素的前一个元素,忽略文本节点
nextSibling 获取同级元素的后一个节点
nextElementSibling 获取同级元素的后一个元素,忽略文本节点
attributes 获取当前元素的所有属性节点
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <div id="header">header</div>
        <div id="section">
            <div id="asdie">aside</div>
            <div id="content">content</div>
        </div>
        <div id="foot">footer</div>
    </div>
</body>
<script>
    var app = document.getElementById("app");
    console.log("childNodes", app.childNodes);
    console.log("firstChild", app.firstChild);
    console.log("lastChild", app.lastChild);

    var section = document.getElementById("section");
    console.log("previousSibling", section.previousSibling);
    console.log("previousElementSibling", section.previousElementSibling);
    console.log("nextSibling", section.nextSibling);
    console.log("nextElementSibling", section.nextElementSibling);
    console.log("parentNode", section.parentNode);
    console.log("parentElement", section.parentElement);
</script>

</html>

节点操作

javascript可以对DOM元素进行创建,赋值,插入,删除以及替换操作

方法 说明
write() 将任意字符串插入到文档中
createElement() 创建一个元素节点
appendChild() 将新节点追加到子节点列表中
createTextNode() 创建文本节点
insertBefore() 将新节点插入在前面
replaceChild() 将新节点替换旧节点
cloneNode() 复制节点
removeChild() 移除节点

write()

document.write("hello");
document.write("<div>javascript</div>")

渲染的源码如下

createElement()

创建一个元素对象,需要将该元素对象通过appendChild的方式插入到页面中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

</body>
<script>
    var app = document.createElement("div");
    app.innerHTML = "<h1>您好!app</h1>";
    var body = document.body;
    //将创建出来的app元素插入到body中
    body.appendChild(app);
</script>
</html>

insertBefore()

将新节点插入在前面 insertBefore(newEle,existingEle); 该方法需要通过要插入的节点的父节点来调用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <div id="main"></div>
        <div id="foot"></div>
    </div>
</body>
<script>
    var app = document.getElementById("app");
    var main = document.getElementById("main");
    var header = document.createElement("div");
    header.id = "header";
    app.insertBefore(header,main)
</script>
</html>

在main元素之前插入一个header元素

insertAfter()

javascript本身没有提供insertAfter()函数,我们需要自己定义

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <div id="main"></div>
        <div id="foot"></div>
    </div>
</body>
<script>
    //在根构造函数的元素对象上新增一个inserAfter函数
    Object.prototype.inserAfter = function(newEle,existingEle){
        var nextEle = existingEle.nextSibling;
        //判断是否是最后一个元素,如果是最后一个元素,就直接使用appendChild插入到列表的最后
        if(!nextEle){
            this.appendChild(newEle);
            return;
        }
        console.log(this);
        //将新元素插入到nextEle的前面即可
        this.insertBefore(newEle,nextEle);
    }   
    var app = document.getElementById("app");
    var content = document.createElement("div");
    content.id = "content";
    var main = document.getElementById("main");
    //将新建的content元素插入到main元素之前
    app.inserAfter(content,main);
</script>
</html>

replaceChild() 替换节点

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <div id="main"></div>
        <div id="foot"></div>
    </div>
</body>
<script>
    var content = document.createElement("div");
    content.id = "content";
    var main = document.getElementById("main");
    var app = document.getElementById("app");
    app.replaceChild(content,main);
</script>
</html>

cloneNode() 克隆节点

cloneNode(true|false) true:表示是否深度克隆.将该元素的所有子节点一起克隆了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <div class="main">
            <div id="aside"></div>
            <div id="content"></div>
        </div>
        <div id="foot"></div>
    </div>
</body>
<script>
    var main = document.getElementsByClassName("main")[0];
    var app = document.getElementById("app");
    var newMain = main.cloneNode(true);
    var secondMain = main.cloneNode(false);
    app.appendChild(newMain);
    app.appendChild(secondMain);
</script>
</html>

removeChild() 删除节点

    var main = document.getElementsByClassName("main")[0];
    var app = document.getElementById("app");
    app.removeChild(main);

操作样式

style

任一HMTL元素标签都会有一个样式属性: style,可以通过这个属性获取元素的内联样式信息,CSStypeDeclaration对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   <div id="app"></div>
</body>
<script>
    var app = document.getElementById("app");
    console.log(app.style);
</script>
</html>

样式属性较多,这里只能截取部分内容

获取样式属性和操作样式属性


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #app {
            width: 500px;
            height: 100px;
            color: red;
            background-color: orange;
        }
    </style>
</head>
<body>
   <div id="app" style="width:200px;height:200px;background-color:cyan">
    www.githuo.com
    </div>
</body>
<script>
    var app = document.getElementById("app");
    //获取指定的样式属性
    console.log(app.style.color);
    console.log(app.style.width);
    console.log(app.style.height);
    console.log(app.style.backgroundColor);
    //设置元素样式
    app.style.color = "black"
    console.log(app.style.color);
</script>
</html>

cssText 样式文本

获取元素完整的样式字符串

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   <div id="app" style="width:200px;height:200px;background-color:cyan">
    www.githuo.com
    </div>
</body>
<script>

    var app = document.getElementById("app");
    //width:200px;height:200px;background-color:cyan
    console.log(app.style.cssText);
    //重新设置样式字符串,
    app.style.cssText = "width:300px;height:100px;background-color:red"
    console.log(app.style.cssText);
</script>
</html>

getComputedStyle

通过计算元素的样式,返回相应的值.如果本身设置了样式,返回元素的样式本身,如果本身没有设置样式,非IE浏览器返回默认样式,IE浏览器则返回auto

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #app {
            color:black;
        }
    </style>
</head>
<body>
   <div id="app" style="width:200px;background-color:cyan">
    www.githuo.com
    </div>
</body>
<script>
    var app = document.getElementById("app");
    var style = window.getComputedStyle?window.getComputedStyle(app,null):null||app.currentStyle;
    console.log(style.width);
    console.log(style.height);
    console.log(style.color);
</script>
</html>

results matching ""

    No results matching ""