【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
一、 认识DOM
DOM(Document Object Model,文档对象模型):定义访问和处理HTML文档的标准方法。DOM 将 HTML 文档呈现为带有 元素、属性和文本的树结构(节点树)。
先来看看下面代码:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=gb2312"/>
<title>DOM</title>
</head>
<body>
<h2>
<a href="http://www.imooc.com">javascript DOM</a>
</h2>
<p>
对HTML元素进行操作,可添加、改变或移除CSS样式等
</p>
<ul>
<li>JavaScript</li>
<li>DOM</li>
<li>CSS</li>
</ul>
</body>
</html>
将 HTML 代码分解为 DOM 节点层次图:
文档构成:
HTML 文档可以说由 节点 构成的集合,DOM 节点有:
-
元素节点:上图中<html>、<body>、<p>等都是元素节点,即标签。
-
文本节点 :向用户展示的内容,如<li>...</li>中的JavaScript、DOM、CSS等文本。
-
属性节点: 元素属性,如<a>标签的链接属性href="http://www.imooc.com"。
看下面代码:
<a href="http://www.imooc.com">JavaScript DOM</a>
二、元素节点获取方式
2.1、通过 ID 获取元素
学过HTML/CSS样式,都知道,网页由标签将信息组织起来,而标签的
id
属性值是唯一的,就像是每人有一个身份证号一样,只要通过身份证号就可以找到相对应的人。那么在网页中,我们通过id
先找到标签,然后进行操作。
语法:
document.getElementById("id")
看看下面代码:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=gb2312"/>
<title>获取元素</title>
<script type="text/javascript">
var mye = document.getElementById("con");//获取元素存储在变量mye中
document.write(mye);// 输出变量mye
</script>
</head>
<body>
<h3>Hello</h3>
<p id="con">I love JavaScript</p>
</body>
</html>
结果:null或[object HTMLParagraphElement]
注:获取的元素是一个对象,如想对元素进行操作,我们要通过它的属性或方法。
2.2、 getElementsByName() 方法
返回带有指定名称的节点对象的集合。
语法:
document.getElementsByName(name)
与getElementById()
方法不同的是,通过元素的 name
属性查询元素,而不是通过id
属性。
注意:
- 因为文档中的
name
属性可能不唯一,所有getElementsByName()
方法返回的是元素的数组,而不是一个元素。 - 和数组类似也有
length
属性,可以和访问数组一样的方法来访问,从0
开始。
看看下面的代码:
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
function getElements(){
var x = document.getElementsByName("alink");
alert(x.length);
}
</script>
</head>
<body>
<a name="alink" href="#">我是链接一</a>
<a name="alink" href="#">我是链接二</a>
<a name="alink" href="#">我是链接三</a>
<br />
<input type="button" onclick="getElements()" value = "看看几个链接?" />
</body>
</html>
运行结果:
2.3、 getElementsByTagName() 方法
返回带有指定标签名的节点对象的集合。
返回元素的顺序是它们在文档中的顺序。
语法:
document.getElementsByTagName(Tagname)
说明:
Tagname
是标签的名称,如p
、a
、img
等标签名。- 和数组类似也有
length
属性,可以和访问数组一样的方法来访问,所以从0
开始。
看看下面代码,通过getElementsByTagName()获取节点。
<!DOCTYPE HTML>
<html>
<head>
<title>JavaScript</title>
</head>
<body>
<p id="intro">我的课程</p>
<ul>
<li>JavaScript</li>
<li>JQuery</li>
<li>HTML</li>
<li>JAVA</li>
<li>PHP</li>
</ul>
<script>
// 获取所有 li 集合
var list = document.getElementByTagName('li');
// 访问无序列表:[0]索引
li = list[0];
// 获取 list 的长度
document.write(list.length);
// 弹出 li 节点对象的内容
document.write(li.innerHTML);
</script>
</body>
</html>
2.4、上述三种方式的区别
以人来举例说明,人有能标识身份的身份证,有姓名,有类别(大人、小孩、老人)等。
-
ID 是一个人的身份证号码,是唯一的。所以通过getElementById获取的是指定的一个人。
-
Name 是他的名字,可以重复。所以通过getElementsByName获取名字相同的人集合。
-
TagName可看似某类,getElementsByTagName获取相同类的人集合。如获取小孩这类人,getElementsByTagName("小孩")。
把上面的例子转换到HTML中,如下:
<input type="checkbox" name="hobby" id="hobby1"> 音乐
-
input标签就像人的类别。
-
name属性就像人的姓名。
-
id属性就像人的身份证。
方法总结如下:
方法 | 说明 | 结果集 |
---|---|---|
getElementById | 通过指定 id 获得元素 | 1个 |
getElementsByName | 通过元素名称 name 属性获得元素 | 1组 |
getElementsByTagName | 通过标签名称获得元素 | 1组 |
**注意:**方法区分大小写
通过下面的例子(6个name="hobby"的复选项,两个按钮)来区分三种方法的不同:
<input type="checkbox" name="hobby" id="hobby1"> 音乐
<input type="checkbox" name="hobby" id="hobby2"> 登山
<input type="checkbox" name="hobby" id="hobby3"> 游泳
<input type="checkbox" name="hobby" id="hobby4"> 阅读
<input type="checkbox" name="hobby" id="hobby5"> 打球
<input type="checkbox" name="hobby" id="hobby6"> 跑步
<input type="button" value = "全选" id="button1">
<input type="button" value = "全不选" id="button1">
-
document.getElementsByTagName("input")
,结果为获取所有标签为input的元素,共8个。 -
document.getElementsByName("hobby")
,结果为获取属性name="hobby"的元素,共6个。 -
document.getElementById("hobby6")
,结果为获取属性id="hobby6"的元素,只有一个,"跑步"这个复选项。
三、节点属性
3.1、属性详解
在文档对象模型 (DOM) 中,每个节点都是一个对象。
属性 | 描述 |
---|---|
nodeName | 节点的名称:返回一个字符串,其内容是给定节点的名字 |
nodeType | 节点的类型: 返回一个整数,这个数值代表给定节点的类型 |
nodeValue | 节点的值: 返回给定节点的当前值 |
3.1.1、 nodeName 属性
节点的名称,是只读的。
说明:
- 元素节点的 nodeName 与标签名相同
- 属性节点的 nodeName 是属性的名称
- 文本节点的 nodeName 永远是 #text
- 文档节点的 nodeName 永远是 #document
3.1.2、 nodeValue 属性
节点的值
说明:
- 元素节点的 nodeValue 是 undefined 或 null
- 文本节点的 nodeValue 是文本自身
- 属性节点的 nodeValue 是属性的值
3.1.3、nodeType 属性
节点的类型,是只读的。
以下常用的几种结点类型:
元素类型 | 节点类型 |
---|---|
元素 | 1 |
属性 | 2 |
文本 | 3 |
注释 | 8 |
文档 | 9 |
3.2、属性值获取:getAttribute() 方法
通过元素节点的属性名称获取属性的值。
语法:
elementNode.getAttribute(name)
说明:
- elementNode:使用
getElementById()
、getElementsByTagName()
等方法,获取到的元素节点。 - name:要想查询的元素节点的属性名字
举例: 获取 h1 标签的属性值:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=gb2312"/>
<title>getAttribute()</title>
</head>
<body>
<h1 id="alink" title="getAttribute()获取标签的属性值" onclick="hattr()">点击我,获取标签的属性值</h1>
<script type="text/javascript">
function hattr(){
var anode = document.getElementById("alink");
var attr1 = anode.getAttribute("id");
var attr2 = anode.getAttribute("title");
document.write("h1标签的ID:" + attr1 + "<br>");
document.write("h1标签的title:" + attr2 );
}
</script>
</body>
</html>
运行结果:
h1标签的ID :alink
h1标签的title :getAttribute()获取标签的属值
3.3、 属性值设置: setAttribute() 方法
setAttribute()
方法增加一个指定名称和值的新属性,或者把一个现有的属性设定为指定的值。
语法:
elementNode.setAttribute(name,value)
说明:
- name: 要设置的属性名。
- value: 要设置的属性值。
注意:
-
把指定的属性设置为指定的值。如果不存在具有指定名称的属性,该方法将创建一个新属性。
-
类似于
getAttribute()
方法,setAttribute()
方法只能通过元素节点对象调用的函数。
四、 遍历节点树
属性 | 描述 |
---|---|
childNodes | 返回一个数组,这个数组由给定元素节点的子节点构成 |
firstChild | 返回第一个子节点 |
lastChild | 返回最后一个子节点 |
parentNode | 返回一个给定节点的父节点 |
nextSibling | 返回给定节点的下一个兄弟节点 |
previousSibling | 返回给定节点的上一个兄弟节点 |
以层次图中 ul
为例,它的父级节点 body
,它的子节点3
个li
,它的兄弟结点h2
、P
。
4.1、childNodes
访问给定 元素节点 下 的所有子节点的列表。
返回的 值可以看作是一个数组,具有 length 属性。
语法:
elementNode.childNodes
注意:如果选定的节点没有子节点,则该属性返回不包含节点的 NodeList。
举例:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>无标题文档</title>
</head>
<body>
<ul>
<li>JavaScript</li>
<li>jQuery</li>
<li>PHP</li>
</ul>
<script type="text/javascript">
var x = document.getElementByTagName("ul")[0].childNodes;
document.write("UL子节点个数:" + x.length + "<br />");
document.write("节点类型:" + x[0].nodeType);
</script>
</body>
</html>
运行结果: IE:
UL子节点个数:3
节点类型:1
其它浏览器:
UL子节点个数:7
节点类型:3
出现上述结果的原因如下:
- IE全系列、firefox、chrome、opera、safari兼容问题
- 节点之间的空白符,在firefox、chrome、opera、safari浏览器是文本节点,在 IE中会忽略掉。如下:
<ul> 空白节点
<li>javascript</li> 空白节点
<li>jQuery</li> 空白节点
<li>PHP</li> 空白节点
</ul>
如果把代码改成这样:
<ul><li>javascript</li><li>jQuery</li><li>PHP</li></ul>
运行结果:(IE和其它浏览器结果是一样的)
UL子节点个数:3
节点类型:1
4.2、 firstChild and lastChild:访问子节点的第一和最后项
(1) firstChild
属性
返回
childNodes
数组的第一个子节点。
如果选定的节点没有子节点,则该属性返回 NULL。
语法:
node.firstChild
说明:
与 elementNode.childNodes[0]
是同样的效果。
(2)、 lastChild 属性
返回
childNodes
数组的最后一个子节点。
如果选定的节点没有子节点,则该属性返回 NULL。
语法:
node.lastChild
说明:
与 elementNode.childNodes[elementNode.childNodes.length-1]
是同样的效果。
注意: 上一节中,我们知道 Internet Explorer 会忽略节点之间生成的空白文本节点,而其它浏览器不会。我们可以通过检测节点类型,过滤子节点。 (以后章节讲解)
4.3、 访问父节点:parentNode
获取指定节点的父节点。
注意:
浏览器兼容问题,chrome、firefox等浏览器标签之间的空白也算是一个文本节点。
语法:
elementNode.parentNode
注意:父节点只能有一个。
举例:
(1)、获取 P 节点的父节点,代码如下:
<div id="text">
<p id="con"> parentNode 获取指点节点的父节点</p>
</div>
<script type="text/javascript">
var mynode= document.getElementById("con");
document.write(mynode.parentNode.nodeName);
</script>
运行结果:
parentNode 获取指点节点的父节点
DIV
(2)、 访问祖节点:
elementNode.parentNode.parentNode
看看下面的代码:
<div id="text">
<p>
parentNode
<span id="con"> 获取指点节点的父节点</span>
</p>
</div>
<script type="text/javascript">
var mynode= document.getElementById("con");
document.write(mynode.parentNode.parentNode.nodeName);
</script>
运行结果:
parentNode获取指点节点的父节点
DIV
4.4、 访问兄弟节点:nextSibling、previousSibling
(1)、nextSibling
属性
可返回某个节点之后紧跟的节点(处于同一树层级中)。
语法:
nodeObject.nextSibling
说明: 如果无此节点,则该属性返回 null。
(2)、 previousSibling
属性
可返回某个节点之前紧跟的节点(处于同一树层级中)。
语法:
nodeObject.previousSibling
说明:如果无此节点,则该属性返回 null。
(3)、举例
注意:
- 两个属性获取的是节点。
- Internet Explorer 会忽略节点间生成的空白文本节点(例如,换行符号),而其它浏览器不会忽略。
如何获取正确的兄弟节点,解决方法:
遍历兄弟节点时判断节点nodeType是否为1(元素节点),不是继续遍历直到获得的是 元素节点 为止。 如下代码:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>nextsibling</title>
</head>
<body>
<ul id="u1">
<li id="a">javascript</li>
<li id="b">jquery</li>
<li id="c">html</li>
</ul>
<ul id="u2">
<li id="d">javascript</li>
<li id="e">jquery</li>
<li id="f">html</li>
</ul>
<script type="text/javascript">
function get_nextSibling(n){
var x=n.nextSibling;
while(x.nextSibling != 1){
x = x.nextSibling;
}
retrun x;
}
var x = document.getElementByTagName("li")[0];
document.write(x.nodeName);
document.write("=");
document.write(x.innerHTML);
var y = get_nextSibling(x);
document.write("nextSibling:" + y.nodeName);
document.write("=");
document.write(y.innerHTML);
</script>
</body>
</html>
运行结果:
LI = javascript
nextsibling: LI = jquery
五、修改节点树
方法 | 描述 |
---|---|
createElement(element) | 创建一个新的元素节点 |
createTextNode() | 创建一个包含给定文本的新文本节点 |
appendChild() | 指定节点的最后一个子节点列表之后添加一个新的子节点 |
insertBefore() | 将一个给定节点插入到一个给定元素节点的给定子节点前面 |
removeChild() | 从一个给定元素中删除一个子节点 |
replaceChild() | 把一个给定父元素里的一个子节点替换为另外一个节点 |
注意: 前两个是 document 方法。
5.1、 创建节点
(1)创建 元素 节点:createElement
createElement()
方法可创建元素节点。 此方法可返回一个 Element 对象。
语法:
document.createElement(tagName)
参数:
tagName:字符串值,这个字符串用来指明创建元素的类型。
注意:要 与 appendChild() 或 insertBefore() 方法联合使用,创建后将元素显示在页面中。
实例: 我们来创建一个按钮,代码如下:
<script type="text/javascript">
var body = document.body;
var input = document.createElement("input");
input.type = "button";
input.value = "创建一个按钮";
body.appendChild(input);
</script>
**效果:**在HTML文档中,创建一个按钮。
我们也可以使用 setAttribute(见第五章节) 来设置属性,代码如下:
<script type="text/javascript">
var body= document.body;
var btn = document.createElement("input");
btn.setAttribute("type", "text");
btn.setAttribute("name", "q");
btn.setAttribute("value", "使用setAttribute");
btn.setAttribute("onclick", "javascript:alert('This is a text!');");
body.appendChild(btn);
</script>
效果: 在HTML文档中,创建一个文本框,使用setAttribute设置属性值。 当点击这个文本框时,会弹出对话框“This is a text!”。
(2)创建文本节点:createTextNode
createTextNode()
方法创建新的文本节点,返回新创建的 Text 节点。
语法:
document.createTextNode(data)
参数: data : 字符串值,可规定此节点的文本。
实例: 我们来创建一个 <div> 元素并向其中添加一条消息,代码如下:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>无标题</title>
<style type="text/css">
.message{
width:200px;
height:100px;
background-color:#CCC;
}
</style>
</head>
<body>
<script type="text/javascript">
var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
document.body.appendChild(element);
</script>
</body>
</html>
运行结果:
5.2、 插入节点
(1) appendChild()
在指定节点的最后一个子节点列表之后添加一个新的子节点。
语法:
appendChild(newnode)
参数:
- newnode:指定追加的节点。
实例:
<div id="test"><p id="x1">HTML</p><p>JavaScript</p></div>
<script type="text/javascript">
var otest = document.getElementById("test");
var newnode = document.createElement("p");
newnode.innerHEML = "This is a new p";
// appendChild方法添加节点
otest.appendChild(newnode);
</script>
运行结果:
HTML
JavaScript
This is a new p
(2) insertBefore()
insertBefore()
方法可在已有的子节点前插入一个新的子节点。
语法:
insertBefore(newnode,node);
参数:
- newnode: 要插入的新节点。
- node: 指定此节点前插入节点。
实例:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>无标题</title>
</head>
<body>
<div id="div1"><p id="x1">JavaScript</p><p>HTML</p></div>
<script type="text/javascript">
var otest = document.getElementById("div1");
var node = document.getElementById("x1");
var newnode = document.createElement("p");
newnode.innerHEML = "This is a new p";
otest.insertBefore(newnode,node);
</script>
</body>
</html>
运行结果:
This is a new p
JavaScript
HTML
注意:
otest.insertBefore(newnode,node);
也可以改为:
otest.insertBefore(newnode,otest.childNodes[0]);
5.3、 删除节点:removeChild()
removeChild()
方法从子节点列表中删除某个节点。
如删除成功,此方法可返回被删除的节点,如失败,则返回 NULL。
语法:
nodeObject.removeChild(node)
参数:
- node :必需,指定需要删除的节点。
实例:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>无标题</title>
</head>
<body>
<div id="div1"><h1>HTML</h1><h2>javascript</h2></div>
<script type="text/javascript">
var otest = document.getElementById("div1");
var x = otest.removeChild(otest.childNodes[1]);
document.write("删除节点的内容:" + x.innerHTML);
</script>
</body>
</html>
运行结果:
HTML
删除节点的内容: javascript
注意:
-
把删除的子节点赋值给 x,这个子节点不在 DOM 树中,但是还存在内存中,可通过 x 操作。
-
如果要完全删除对象,给 x 赋 null 值,代码如下:
var otest = document.getElementById("div1");
var x = otest.removeChild(otest.childNodes[1]);
x=null;
5.4、 替换元素节点:replaceChild()
replaceChild
实现子节点(对象)的替换。返回被替换对象的引用。
语法:
node.replaceChild (newnode,oldnew )
参数:
- newnode : 必需,用于替换 oldnew 的对象。
- oldnew : 必需,被 newnode 替换的对象。
举例:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>无标题</title>
</head>
<body>
<script type="text/javascript">
function replaceMessage(){
var newnode=document.createElement("p");
var newnodeText = document.createTextNode("JavaScript");
newnode.appendChild(newnodeText);
var oldNode = document.getElementById("oldnode");
oldnode.parentNode.replaceChild(newnode,oldnode);
}
</script>
<h1 id="oldnode">Java<h1>
<a href="javascript:replaceMessage()">"Java" 替换 "JavaScript"</a>
</body>
</html>
**效果 **: 将 文档中的 Java
改为 JavaScript
。
注意:
- 当 oldnode 被替换时,所有与之相关的属性内容都将被移除。
- newnode 必须先被建立。
来源:oschina
链接:https://my.oschina.net/u/3739435/blog/2243670