Node对象与Element对象
你好! 这是我自己编辑的一些知识点。如果你想学习JavaScript的有关知识, 可以仔细阅读这篇文章,了解一下关于JavaScript的基本语法知识。
Node对象
Node对象是什么
-
DOM的标准规范中提供了Node对象,该对象主要提供了用于解析DOM节点树结构的属性和方法。
-
DOM树结构主要是依靠节点进行解析,称为DOM节点树结构。Node对象是解析DOM节点树结构的主要入口。
-
Node对象提供的属性和方法,可以实现遍历节点、插入节点和替换节点等操作。
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Node对象是什么</title>
</head>
<body>
<button id="btn">按钮</button>
<script>
console.log(document);
// 1.Node对象并不像Document对象一样 - 提供直接使用对象
// console.log(node);
// 2.Node类型不允许通过new关键字创建对象的
// var node=new Node();
// console.log(node);
var btnElement=document.getElementById('btn');
console.log(btnElement instanceof HTMLButtonElement);
// 定位页面元素其实就是Node对象 -> 称为元素节点
console.log(btnElement instanceof Node);
console.log(Node.prototype);
// 延伸
var btn=document.createElement('button');
console.log(btn instanceof Node);//true
</script>
</body>
</html>
继承链关系
Node对象是继承于EventTarget对象的,EventTarget是一个用于接收事件的对象。我们可以通过如下代码测试两者之间的继承关系:
console.log(Node.prototype instanceof Eventarget);
DOM的标准规范中的Document对象和Element对象都是继承于Node对象的。我们可以通过如下代码测试它们之间的继承关系:
console.log(Document.prototype instanceof Node);
console.log(Element.prototype instanceof Node);
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
console.log(Node.prototype instanceof EventTarget);//true
console.log(Document.prototype instanceof Node);//true
console.log(Element.prototype instanceof Node);//true
</script>
</body>
</html>
判断节点类型
Node对象中提供了nodeName、nodeType和nodeValue分别可以用于获取指定节点的节点名称、节点类型和节点的值。
DOM节点树结构中,我们实际开发最常见的节点有:
节点名称 | 含义 |
---|---|
元素节点 | 表示HTML页面中的标签(即HTML页面的结构) |
属性节点 | 表示HTML页面中的开始标签包含的属性 |
文本节点 | 表示HTML页面中的标签所包含的文本内容 |
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn" class="cls">按钮</button>
<script>
// 1.元素节点
var btnElement=document.getElementById('btn');
//元素节点的nodename属性值为标签名称(大写)
console.log(btnElement.nodeName);//BUTTON
console.log(btnElement.nodeType);//1
console.log(btnElement.nodeValue);//null
// 2.文本节点
var textNode=btnElement.firstChild;
// 文本节点的nodeName属性值是固定值(#text)
console.log(textNode.nodeName);//#text
console.log(textNode.nodeType);//3
// 文本节点的nodeValue属性值是文本内容
console.log(textNode.nodeValue);//按钮
textNode.nodeValue="hhhhh";
// 3.属性节点
var attrNode=btnElement.getAttributeNode('class');
//属性节点的nodeName属性值为当前元素的属性名称
console.log(attrNode.nodeName);//class
console.log(attrNode.nodeType);//2
// 属性节点的nodeValue属性值为当前元素的属性名称对应的值
console.log(attrNode.nodeValue);//cls
</script>
</body>
</html>
遍历节点
获取父节点
通过HTML页面中指定元素查找其父级节点,我们可以使用Node对象的parentNode属性实现:
var pNode=node.parentNode;
注意:在一个元素节点的父节点,可能是一个元素节点,也可能是一个文档节点。
var btn=document.getElementById('btn');
var parentNode=btn.parentNode;
var className=parentNode.className;
className+='animate';
parentNode.className=className;
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>获取父节点</title>
</head>
<body>
<ul id="parent">
<li>苹果</li>
<li id="xm">小米</li>
<li>华为</li>
</ul>
<script>
// 作为子节点
var xm=document.getElementById('xm');
// 通过子节点获取其父节点
var parent1=xm.parentNode;
console.log(parent1);
//parentElement属性-> 表示获取其父元素节点
var parent2=xm.parentElement;
console.log(parent2);
var html=document.documentElement;
console.log(html.parentElement);//null
console.log(html.parentNode);//文档节点
</script>
</body>
</html>
空白节点问题
通过HTML页面中指定元素查找其子节点,我们可以通过以下Node对象的属性实现:
属性名 | 描述 |
---|---|
childNodes | 获取指定节点的所有子节点 |
firstChild | 获取指定节点的第一个子节点 |
lastChild | 获取指定节点的最后一个子节点 |
空白节点本身就是节点解析方式的一个主要问题,不是针对某个属性或方法的问题。
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>空白节点问题</title>
</head>
<body>
<ul id="parent"><li>苹果</li><li id="xm">小米</li><li>华为</li></ul>
<script>
var parent=document.getElementById('parent');
// childNodes属性 - 获取指定节点的所有子节点
var children=parent.childNodes;
console.log(children.length);//3
/* 1.利用循环+判断筛选
var arr=[];
for (var i=0;i<children.length;i++){
var child=children[i];
if (child.nodeType===1){
arr.push(child);
}
}
console.log(arr);
*/
// 2.利用getElementByTagName()方法
var list=parent.getElementByTagName('li');
console.log(list);
</script>
</body>
</html>
空白节点
主流浏览器解析HTML页面内容为DOM节点树结构时,会产生空文本的空白节点。这是由HTML页面源代码中的换行引起的:
<div id="parent" class="button-group">
<button id="btn" name="btn" class="button">A Button</button>
<button name="btn" class="button">A Button</button>
<button name="btn" class="button">A Button</button>
</div>
空白节点的解决方案
在开发中,空白节点的问题将DOM节点树结构的解析及操作增加了不少的难度和麻烦。这里提供一种比较简单有效的解决方式:
1.弃用DOM中Node对象用于获取指定节点的子节点和兄弟节点的属性。
2.通过使用getElementByTagName()方法实现相应功能。
比如要查找HTML页面指定元素的所有子节点的话,可以按照如下代码示例实现:
var parentNode=document.getElementById('parent');
var children=parentNode.getElementsByTagName('button');
console.log(children);
说明:在关于DOM中为什么要具有空白节点以及更完整的解决方案,可以参考Mozilla社区的《DOM中的空白符》。
例:
/**
* 以下所谓的“空白符”代表:
* "\t" TAB \u0009 (制表符)
* "\n" LF \u000A (换行符)
* "\r" CR \u000D (回车符)
* " " SPC \u0020 (真正的空格符)
*
* 不包括 JavaScript 的“\s”,因为那代表如不断行字符等其他字符。
*/
/**
* 测知某节点的文字内容是否全为空白。
*
* @参数 nod |CharacterData| 类的节点(如 |Text|、|Comment| 或 |CDATASection|)。
* @传回值 若 |nod| 的文字内容全为空白则传回 true,否则传回 false。
*/
function is_all_ws( nod )
{
// Use ECMA-262 Edition 3 String and RegExp features
return !(/[^\t\n\r ]/.test(nod.data));
}
/**
* 测知是否该略过某节点。
*
* @参数 nod DOM1 |Node| 对象
* @传回值 若 |Text| 节点内仅有空白符或为 |Comment| 节点时,传回 true,
* 否则传回 false。
*/
function is_ignorable( nod )
{
return ( nod.nodeType == 8) || // 注释节点
( (nod.nodeType == 3) && is_all_ws(nod) ); // 仅含空白符的文字节点
}
/**
* 此为会跳过空白符节点及注释节点的 |previousSibling| 函数
* ( |previousSibling| 是 DOM 节点的特性值,为该节点的前一个节点。)
*
* @参数 sib 节点。
* @传回值 有两种可能:
* 1) |sib| 的前一个“非空白、非注释”节点(由 |is_ignorable| 测知。)
* 2) 若该节点前无任何此类节点,则传回 null。
*/
function node_before( sib )
{
while ((sib = sib.previousSibling)) {
if (!is_ignorable(sib)) return sib;
}
return null;
}
/**
* 此为会跳过空白符节点及注释节点的 |nextSibling| 函数
*
* @参数 sib 节点。
* @传回值 有两种可能:
* 1) |sib| 的下一个“非空白、非注释”节点。
* 2) 若该节点后无任何此类节点,则传回 null。
*/
function node_after( sib )
{
while ((sib = sib.nextSibling)) {
if (!is_ignorable(sib)) return sib;
}
return null;
}
/**
* 此为会跳过空白符节点及注释节点的 |lastChild| 函数
* ( lastChild| 是 DOM 节点的特性值,为该节点之中最后一个子节点。)
*
* @参数 par 节点。
* @传回值 有两种可能:
* 1) |par| 中最后一个“非空白、非注释”节点。
* 2) 若该节点中无任何此类子节点,则传回 null。
*/
function last_child( par )
{
var res=par.lastChild;
while (res) {
if (!is_ignorable(res)) return res;
res = res.previousSibling;
}
return null;
}
/**
* 此为会跳过空白符节点及注释节点的 |firstChild| 函数
*
* @参数 par 节点。
* @传回值 有两种可能:
* 1) |par| 中第一个“非空白、非注释”节点。
* 2) 若该节点中无任何此类子节点,则传回 null。
*/
function first_child( par )
{
var res=par.firstChild;
while (res) {
if (!is_ignorable(res)) return res;
res = res.nextSibling;
}
return null;
}
/**
* 此为传回值不包含文字节点资料的首尾所有空白符、
* 并将两个以上的空白符缩减为一个的 |data| 函数。
*( data 是 DOM 文字节点的特性值,为该文字节点中的资料。)
*
* @参数 txt 欲传回其中资料的文字节点
* @传回值 文字节点的内容,其中空白符已依前述方式处理。
*/
function data_of( txt )
{
var data = txt.data;
// Use ECMA-262 Edition 3 String and RegExp features
data = data.replace(/[\t\n\r ]+/g, " ");
if (data.charAt(0) == " ")
data = data.substring(1, data.length);
if (data.charAt(data.length - 1) == " ")
data = data.substring(0, data.length - 1);
return data;
}
获取子节点
通过HTML页面中指定元素查找其子节点,我们可以通过以下Node对象的属性实现:
属性名 | 描述 |
---|---|
childNodes | 获取指定节点的所有子节点 |
firstChild | 获取指定节点的第一个子节点 |
lastChild | 获取指定节点的最后一个子节点 |
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>获取子节点</title>
<script src="my tools3.js"></script>
</head>
<body>
<ul id="parent">
<li>苹果</li>
<li id="xm">小米</li>
<li>华为</li>
</ul>
<script>
var parent=document.getElementById('parent');
var children=myTools.childNodes(parent);
console.log(children);
// var firstChild=parent.firstChild;
// firstChild=firstChild.nextSibling;
// console.log(firstChild);
var firstChild=myTools.firstChild(parent);
console.log(firstChild);
var lastChild=parent.lastChild;
lastChild=lastChild.previousSibling;
console.log(lastChild);
</script>
</body>
</html>
myTools:
//创建对象 - 专门用于封装解决空白节点问题
var myTools={
//解决获取其所有子节点childNodes属性的问题
childNodes : function(parentNode){
var children=parentNode.childNodes;
var arr=[];
for (var i=0;i<children.length;i++){
var child=children[i];
if (child.nodeType===1){
arr.push(child);
}
}
return arr;
},
firstChild : function(parentNode){
var firstChild=parentNode.firstChild;
firstChild=firstChild.nextSibling;
return firstChild;
}
}
获取相邻兄弟节点
通过HTML页面中指定元素查找其相邻兄弟节点,我们可以通过以下Node对象的属性实现:
属性名 | 描述 |
---|---|
previousSibling | 获取指定节点的前面相邻兄弟节点 |
nextSibling | 获取指定节点的后面相邻兄弟节点 |
-
获取相邻前面兄弟节点
-
Node对象提供了previousSibling属性用于获取指定节点的前面相邻兄弟节点:
-
var previousNode=node.previousSibling;
-
previousSibling属性返回的previousNode表示当前节点的前一个兄弟节点。
-
注意:如果当前节点无前一个兄弟节点,则previousSibling属性返回null。
-
var elemdocument.getElementById('btn'); var previousSibling=elem.previousSIbling;
-
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>获取相邻兄弟节点</title>
<script src="my tools3.js"></script>
</head>
<body>
<ul id="parent">
<li>苹果</li>
<li id="xm">小米</li>
<li>华为</li>
</ul>
<script>
var xm=document.getElementById('xm');
var prev=xm.previousSibling;
prev=prev.previousSibling;
console.log(prev);
console.log(prev.previousSibling);//空白节点
console.log(prev.previousSibling.previousSibling);//null
var next=xm.nextSibling;
next=next.nextSibling;
console.log(next);
</script>
</body>
</html>
插入节点
appendChild()方法
Node对象提供的appendChild()方法可以向指定节点的子节点列表的最后添加一个新的子节点。
var child=node.appendChild(child);
-
appendChild()方法的参数child表示添加的新的子节点,同时该子节点也是appendChild()方法的返回值。
-
var parent=document.getElementById('parent'); var button=document.createElement('button'); button.setAttribute('class','button'); var text=document.createTextNode('A New Button'); button.appendChild(text); //将新节点添加到父节点中 parent.appendChild(button);
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>appendChild()方法</title>
</head>
<body>
<ul id="parent">
<li>苹果</li>
<li id="xm">小米</li>
<li>华为</li>
</ul>
<script>
var parent=document.getElementById('parent');
var newli=document.createElement('li');
var textNode=document.createTextNode('三星');
newli.appendChild(textNode);
/*
parentNode.appendChild(chidNode)
*说明
*parentNode - 表示指定节点(作为父节点)
*childNode - 表示被添加的节点(作为子节点)
*特点 - 被添加在指定节点所有子节点列表的最后
*/
parent.appendChild(newli);
</script>
</body>
</html>
insertBefore()方法
Node对象除了提供了appendChild()方法可以实现插入节点之外,还提供了insertBefore()方法同样可以实现插入节点的功能。
var insertedElement=parentElement.insertBefore(newElement,referenceElement);
- 参数referenceElement表示指定节点的某个子节点。
- 参数newElement表示插入的节点。
- 调用insertBefore()方法的parentElement表示指定的节点。
- 作为返回值的insertedElement表示被插入的节点,即newElement。
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>insertBefore()方法</title>
</head>
<body>
<ul id="parent">
<li>苹果</li>
<li id="xm">小米</li>
<li>华为</li>
</ul>
<script>
//获取指定父节点
var parent=document.getElementById('parent');
//创建新的子节点
var newli=document.createElement('li');
var textNode=document.createTextNode('三星');
newli.appendChild(textNode);
//获取目标节点
var xm=document.getElementById('xm');
parent.insertBefore(newli,xm);
//DOM中的Node对象并没有提供insertAfter()方法
</script>
</body>
</html>
insertAfter:
function insertAfter(parentNode,newChild,currenChild){
var nextNode=currenChild.nextSibling.nextSibling;
if (nextNode===null){
parentNode.appendChild(newChild);
}else{
parentNode.insertBefore(newChild,nextNode);
}
}
Object.defineProperty(Node.prototype,'insertAfter',{
value : function(newChild,currenChild){
var nextNode=currenChild.nextSibling.nextSibling;
if (nextNode===null){
this.appendChild(newChild);
}else{
this.insertBefore(newChild,nextNode);
}
}
})
删除节点
Node对象提供了removeChild()方法实现从HTML页面中删除指定节点。
var oldChild=node.removeChild(child);
OR
element.removeChild(child);
- 调用removeChild()方法的node表示child参数的父节点。
- child参数则表示要删除的那个节点。
oldChild则用于存储要删除的节点的引用,即oldChild===child.当然,如果我们需要完成的仅仅只是删除节点操作的话,并不需要定义变量来存储被删除的节点。
注意:在上述语法结构中,如果child参数不是node的子节点的话,调用该方法时会报错。
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>删除节点</title>
</head>
<body>
<ul id="parent">
<li>苹果</li>
<li id="xm">小米</li>
<li>华为</li>
</ul>
<li id="sx">三星</li>
<script>
//获取指定父节点
var parent=document.getElementById('parent');
//获取目标节点
var xm=document.getElementById('xm');
parent.removeChild(xm);
var sx=document.getElementsById('sx');
parent.removeChild(sx);//报错
</script>
</body>
</html>
替换节点
Node对象提供了replaceChild()方法实现HTML页面中节点的替换功能。
var.replacedNode=parentNode.replaceChild(newChild,oldChild);
- 调用replaceChild()方法的parentNode表示被替换节点oldChild的父级节点。
- 参数oldChild表示HTML页面中被替换的节点。replaceChild()方法的返回值也是被替换的节点,即oldChild==replaceNode.
- 参数newChild则表示用于替换的新节点。如果该节点已经存在于DOM节点数结构中的话,则它会被从原始位置删除。
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>替换节点</title>
</head>
<body>
<ul id="parent">
<li>苹果</li>
<li id="mi">小米</li>
<li>锤子</li>
</ul>
<ul id="game">
<li>星际争霸</li>
<li id="ms">魔兽世界</li>
<li>王者荣耀</li>
</ul>
<script>
//1.获取目标节点的父节点
var parent=document.getElementById('parent');
//2.获取目标节点
var mi=document.getElementById('mi');
//3.创建新节点
var newli=document.createElement('li');
var textNode=document.createTextNode('华为');
newli.appendChild(textNode);
var ms=document.getElementById('ms');
/*
parentNode.replaceChild(newChild,currentChild);
*参数
*parentNode - 表示目标(被替换)节点的父节点
*newChild - 表示替换(新)节点
*currentChild - 表示目标节点
*情况
*替换节点 - 是新创建的节点 ->替换
*节点 - 是页面已存在的节点 ->移动+替换
*/
parent.replaceChild(ms,mi);
</script>
</body>
</html>
复制节点
Node对象提供了cloneNode()方法实现HTML页面中节点的复制功能。
var dupNode=node.cloneNode(deep);
- 调用cloneNode()方法的node表示被克隆的节点,返回值dupNode表示克隆后的新节点。
- 参数deep则表示是否采用深度克隆。如果为true,则该节点的所有后代节点也都会被克隆;如果为false,则只克隆该节点本身。
注意:参数deep如果默认不传递的话,值为false。但在旧版本的浏览器中,你始终需要指定deep参数。
var parent=document.getElementById('parent');
var btn=document.getElementById('btn');
//复制目标节点
var clone=btn.cloneNode(true);
parent.appendChild(clone);
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>复制节点</title>
</head>
<body>
<button id="btn">按钮</button>
<script>
var btn=document.getElementById('btn');
/*
node.cloneNode(deep);
*deep参数 - 是否复制当前节点的后代节点
*true - 表示复制后代节点
*false - 默认值,表示不复制后代节点
*注意 - 复制操作时,注意ID属性的值
*/
var newBtn=btn.cloneNode(true);
var body=document.body;
body.appendChild(newBtn);
</script>
</body>
</html>
textContent属性
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p id="p1">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Voluptatem, autem ipsum! Sunt minima optio consequatur possimus nisi, maiores totam tenetur expedita accusantium veniam sint at et laborum quibusdam placeat distinctio.</p>
<script>
var pe=document.getElementById('p1');
//节点方式进行解析
// var textNode=pe.firstChild;
// var content=textNode.nodeValue;
/*
textContent属性
*作用 - 设置或获取指定节点的文本内容
*注意 - 具有浏览器兼容问题(IE6/7/8不支持)
*/
if (pe.textContent===undefined) {
//IE6/7/8不支持
var content=pe.innerText;
}else{
//其他浏览器支持
var content=pe.textContent;
}
console.log(content);
</script>
</body>
</html>
Element对象
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn">按钮</button>
<script>
//1.DOM并没有提供element对象
// console.log(element);
//2.DOM不允许创建element对象
// var element=new Element();
// console.log(element);
/*
1.HTMLButtonElement对象
2.Node对象
3.Element对象
*/
var btn=document.getElementById('btn');
console.log(btn instanceof HTMLButtonElement);//true
console.log(btn instanceof Node);//true
console.log(btn instanceof Element);//rue
//Element是继承于Node
console.log(Element.prototype instanceof Node);//true
// HTMLElement是继承于Element
console.log(HTMLElement.prototype instanceof Element);//true
// HTMLButtonElement是继承于HTMLElement
console.log(HTMLButtonElement.prototype instanceof HTMLElement);//true
</script>
</body>
</html>
定位页面元素
定位页面元素的方法
Element对象提供了属性和方法实现定位页面元素功能。
该对象与Document对象提供的属性和方法实现定位页面元素功能的区别在于,Document对象定位的是HTML页面中所有指定元素,而Element对象定位的是指定元素内所有指定元素。
目前Element对象提供实现定位页面元素的方法具有如下几种:
- getElementsByTagName()方法:通过页面元素的元素名定位元素。
- getElementsByClassName()方法:通过页面元素的class属性值定位元素。
- querySelector()方法:通过CSS选择器定位第一个匹配的元素。
- querySelectorAll()方法:通过CSS选择器定位所有匹配的元素。
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul id="city">
<li>北京</li>
<li>天津</li>
<li>太原</li>
</ul>
<ul id="game">
<li>星际争霸</li>
<li>英雄联盟</li>
<li>王者荣耀</li>
</ul>
<script>
//document代表当前HTML页面
var list1=document.getElementsByTagName('li');
console.log(list1);
//element代表指定标签
var city=document.getElementById('city');
var list2=city.getElementsByTagName('li');
console.log(list2);
</script>
</body>
</html>
遍历元素
获取子元素
通过HTML页面中指定元素查找其子元素,我们可以通过以下Element对象的属性实现:
属性名 | 描述 |
---|---|
children | 获取指定节点的所有子元素 |
childElementCount | 获取指定元素的所有子元素的个数 |
firstElementChild | 获取指定节点的第一个子元素 |
lastElementChild | 获取指定节点的最后一个子元素 |
例:
var myTools={
firstElementChild:function(element){
if (element.firstElementChild===undefined) {
return element.children[0];
}else{
return element.firstElementChild;
}
},
lastElementChild:function(){
if (element.lastElementChild===undefined) {
var children=element.children;
return children[children.length-1];
}else{
return element.lastElementChild;
}
},
childElementCount:function(){
if (this.childElementCount===undefined) {
var children=element.children;
return children.length;
}else{
return element.childElementCount;
}
}
}
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul id="city">
<li>北京</li>
<li>天津</li>
<li>太原</li>
</ul>
<script>
var city=document.getElementById('city');
//获取所有子元素 - 不存在浏览器兼容问题
var children=city.children;
console.log(children);
//以下三个属性都具有浏览器兼容问题
var firstChild=city.firstElementChild;
console.log(firstChild);
var lastChild=city.lastElementChild;
console.log(lastChild);
var childCount=city.childElementCount;
console.log(childCount);
</script>
</body>
</html>
获取相邻兄弟元素
-
获取相邻后面兄弟元素
Element对象提供了nexElementSibling属性用于获取指定元素的后面相邻兄弟元素:
var nextElem=node.nextElementSibling;
- nextElementSibling属性返回的nextElem表示当前元素的后一个兄弟元素。
注意:如果当前元素无后一个兄弟元素,则nextElementSibling属性返回null.
var elem=document.getElementById('btn'); var nextSibling=elem.nextElementSibling;
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul id="city">
<li>北京</li>
<li id="tj">天津</li>
<li>太原</li>
</ul>
<script>
var tjElement=document.getElementById('tj');
console.log(tjElement.previousElementSibling);
console.log(tjElement.nextElementSibling);
var parent=document.getElementById('city');
var children=parent.children;
console.log(children);
// var index=children.indexOf(tjElement);
// console.log(index);
// var arr=[];
// for(var i=0;i<children.length;i++){
// arr.push(children[i]);
// }
// console.log(arr);
// var index=arr.indexOf(tjElement);
// console.log(index);
var index=0;
for(var i=0;i<children.length;i++){
if(children[i]===tjElement){
index=i;
}
}
console.log(index);
</script>
</body>
</html>
属性操作
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn" class="cls">按钮</button>
<script>
var btn=document.getElementById('btn');
//获取属性
console.log(btn.getAttribute('class'));
//设置属性
btn.setAttribute('name','button');
//删除属性
// btn.removeAttribute('name');
//判断是否具有某个属性
console.log(btn.hasAttribute('name'));
//判断是否具有属性 - 具有浏览器兼容问题
console.log(btn.hasAttributes());
</script>
</body>
</html>
innerHTML属性
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul id="city">
<li>北京</li>
<li id="tj">天津</li>
<li>太原</li>
</ul>
<script>
//为<ul>元素添加新的<li>元素
// var newli=document.createElement('li');
// var textNode=document.createTextNode('重庆');
// newli.appendChild(textNode);
// var city=document.getElementById('city');
// city.appendChild(newli);
var city=document.getElementById('city');
var html=city.innerHTML;//获取指定元素的HTML代码
console.log(html);
html+='<li>重庆</li>';
city.innerHTML=html;
//innerHTML属性的问题 - 安全问题(innerHTML属性的值不能由用户写)
</script>
</body>
</html>