- DOM对象
- DOM接口
- DOM结构
- 获取元素
- onload
- getElementsByClassName
- getAttribute
- DOM节点
- 层次节点属性
- 节点操作
- write())
- createElement())
- insertBefore())
- insertAfter())
- replaceChild() 替换节点 替换节点)
- cloneNode() 克隆节点 克隆节点)
- removeChild() 删除节点 删除节点)
- 操作样式
- style
- 获取样式属性和操作样式属性
- cssText 样式文本
- getComputedStyle
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属性的节点列表 |
- 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>
上面问题解决问题
- 将script标签移动的body之后
- 使用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>
- 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>