JavaScript - 父节点 - 兄弟节点 - 子节点 - 对象获取方法 - HTMLCollection对象 和 NodeList 对象 各自所能使用的方法 - 测试 - 新手笔记

基本知识

理解 HTML 父节点、兄弟节点、子节点

理解 HTML 对象

理解 HTML DOM (Document Object Model 文档对象模型)大致了解就行,先埋坑

一、js 测试笔记:

  1. 如果在 js 中,某一段代码突然出错了,js 是不会报错的,所以这里就是非常让人郁闷,你运行时,也就不知道哪里出问题了,和其他的编程语言的调试机制相比,就很难受;
  2. js 如果在某一段代码出问题时,既不会报错,也不会继续执行下面的代码,但是前面的代码倒是会执行,只是报错之后的所有代码都不会再执行;
  3. 最最容易出问题的地方在于,有没有加分号 ; 这个问题,注意函数的花括号不需要加 ; 分号,但是但是基本的代码表达式,都是要加 ; 分号的,否则报错不显示,很坑的,特别注意是英文的分号 ; 而不是中文的;分号

二、在线测试代码:

(找些在线代码编程网站测试,链接:菜鸟教程 js 在线代码编程

复制过去运行。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Muxiu Test</title>
</head>
<body>

<h2>JavaScript 对象</h2>
	
	<ul>
		<p id="demo">muxiu</p>
		<p id="demo1">muxiu</p>
		<p id="demo2">muxiu</p>

		<button onclick="myfunction(this)">点我后就变帅变靓</button>
	</ul>

	
<script>
function myfunction(obj){
	document.getElementById("demo").innerHTML =  obj;
	
	document.getElementById("demo1").innerHTML =  obj.parentNode;
	
	document.getElementById("demo2").innerHTML =  obj.parentNode.querySelector("p");
	
}
</script>
	
</body>
</html>

运行结果:
在这里插入图片描述

this 关键字详解

二、在线代码测试部分this 关键字用来获取 button 标签对象,button对象的父节点是 ul 标签,然后获取 ul 标签的第一个标签。

三、js 方法解析:

标签,也叫元素

1、理解 HTMLcollection 对象 和 Nodelist 对象的不同之处

首先,如果要活用获取到的HTML对象,那么就需要理解HTML对象有两种类型的对象,一个是HTMLcollection对象,一个是 Nodelist 对象,这两种对象,非常非常重要,因为我们在使用了不同的方法,获取到的对象,有可能也是不同类型的对象,所以就导致了,我们要使用不同的方法来处理,当然这两种类型的对象,也有部分相似,方法和属性也是有相同类似的,但是但是有一点要注意,要牢记它们不同的对象处理方法,要不然使用了 HTMLcollection对象的处理方法去处理 Nodelist 对象,那么报错常伴如风。
其中 HTMLCollection是比较HTML发展早期的对象模型,只能包含HTML元素,而NodeList是比较新的模型,相比HTMLCollection更加完善,不光有HTML元素,还有text节点和comment。
HTMLCollection 早期就有的接口如

document.getElementsByClassName()

document.getElementsByTagName()

NodeList 比较新的接口如

document.querySelectorAll()

关于NodeList,HTMLCollection和Array的关系,就是长得像,有个别相似的功能,但是是完全不一样的东西。

2、HTMLCollection 对象

MDN上是这么介绍HTMLCollection的:

Note: This interface is called HTMLCollection for historical reasons(before the modern DOM, collections implementing this interface could only have HTML elements as their items).

翻译一下就是:
之所以叫它HTMLCollection是因为某些历史原因,在新一代DOM出现之前,实现HTMLCollection这个接口的集合只包含HTML元素,所以命名为HTMLCollection。

HTMLCollection 对象类似包含 HTML 元素的一个数组。

注意:

  1. HTMLCollection 不是一个数组!
  2. HTMLCollection 看起来可能是一个数组,但其实不是。
  3. 你可以像数组一样,使用索引来获取元素。
  4. HTMLCollection 无法使用数组的方法: valueOf(), pop(), push(), 或 join()。

3、NodeList 对象

大部分浏览器的querySelectorAll()返回 NodeList 对象。

注意

  1. 节点列表不是一个数组!
  2. 节点列表看起来可能是一个数组,但其实不是。你可以像数组一样,使用索引来获取元素。
  3. 节点列表无法使用JavaScript数组的方法: valueOf(), pop(), push(), 或 join()

HTMLCollection 与 NodeList 的区别

  1. HTMLCollection是 HTML 元素的集合。(仅包含元素)
  2. NodeList 是一个文档节点的集合
  3. NodeList 与 HTMLCollection 有很多类似的地方。
  4. NodeList 与 HTMLCollection 都与数组对象有点类似,可以使用索引 (0, 1, 2, 3, 4, …) 来获取元素。
  5. NodeList 与 HTMLCollection 都有 length 属性。
  6. HTMLCollection 元素可以通过 nameid 或索引来获取。
  7. NodeList 只能通过索引来获取。
  8. 只有 NodeList 对象有包含属性节点和文本节点。

4、返回 HTMLCollection 对象的方法

获取HTMLCollection 对象元素数组的方法,如 getElementsByClassName()getElementsByTagName()

特别特别注意,虽然说是数组,但本质上并不是数组类型的数据,没法调用 JavaScript 数组方法。

语法:(特别需要提到一点是,这里的开头是 document ,但是一般来说,我们需要理解 节点的概念,这里的 document 代表了文档节点,即根节点,这里笔者是这样理解的,有错的地方请留言,所以只要获取了某个元素对象了,那么就可以以这个元素对象,作为一个根节点,继续 .getElementById .getElementsByClassName().getElementsByTagName()


document.getElementById()
// 本质是 element.getElementById()
document.getElementsByClassName()
// 本质是 element.getElementsByClassName()
document.getElementsByTagName()
// 本质是 element.getElementsByTagName()

在线测试代码:

在线测试网站链接:菜鸟教程在线测试链接

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="div1">
        div1
        <div class="div2">
            div2
            <div class="div3">
                div3
            </div>
        </div>
    </div>


<script>
var parent = document.getElementById('div1');
console.log(parent);

parent = document.getElementsByClassName('div2');
console.log(parent);

parent = document.getElementsByTagName('div');
console.log(parent);
</script>

</body>
</html>

运行结果:(点击上面的在线测试网站链接,把代码复制进去,点击运行,然后再按键盘 F12,查看Console 控制台,可以看到结果)

在这里插入图片描述
可以看到只有 getElementsByClassNamegetElementsByTagName这两个方法返回的时 HTMLCollection对象,而getElementById并不是一个HTMLCollection对象,而是返回了一个HTML元素对象。

一个非常奇妙的一点是 getElementsByName(),返回的竟然不是 HTMLCollection 对象,如下所示:(先埋坑,后面讲
在这里插入图片描述

总结

仅仅返回一个元素对象的方法,有document.getElementByIddocument.documentElementdocument.body

测试代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
	<style>
		.display{
			display:none;
		}
	</style>
</head>
<body>
   <ul id="menu">
            <li>
                <a href="#" >菜单选项</a>
                <ul class="display">
                    <li><a href="#" >选项1</a></li>
                    <li><a href="#" >选项2</a></li>
                </ul>
            </li>
	</ul>


<script>
var parent = document.getElementById('menu');
console.log(parent);
parent = document.body;
	console.log(parent);

parent = document.documentElement; 
	console.log(parent);
</script>

控制台结果:

在这里插入图片描述
而只有getElementsByClassName()getElementsByTagName() 才能返回 HTMLCollection 的元素对象数组。

测试 HTMLCollection 对象可以使用的方法

测试 getElementById

  • innerHTML - 节点(元素)的文本值
  • parentNode - 节点(元素)的父节点
  • childNodes - 节点(元素)的子节点
  • attributes - 节点(元素)的属性节点

在线测试代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
	<style>
		.display{
			display:none;
		}
	</style>
</head>
<body>
   <ul id="menu">
            <li>
                <a href="#" >菜单选项</a>
                <ul class="display">
                    <li><a href="#" >选项1</a></li>
                    <li><a href="#" >选项2</a></li>
                </ul>
            </li>
	</ul>


<script>
var parent = document.getElementById('menu').innerHTML ;
console.log(parent);

var parent = document.getElementById('menu').parentNode  ;
console.log(parent);
	
var parent = document.getElementById('menu').childNodes  ;
console.log(parent);
	
var parent = document.getElementById('menu').attributes   ;
console.log(parent);
</script>

</body>
</html>

控制台结果:
在这里插入图片描述

测试 getElementsByClassName()

  • innerHTML - 节点(元素)的文本值
  • parentNode - 节点(元素)的父节点
  • childNodes - 节点(元素)的子节点
  • attributes - 节点(元素)的属性节点

在线测试代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
	<style>
		.display{
			display:none;
		}
	</style>
</head>
<body>
   <ul class="menu">
            <li>
                <a href="#" >菜单选项</a>
                <ul class="display">
                    <li><a href="#" >选项1</a></li>
                    <li><a href="#" >选项2</a></li>
                </ul>
            </li>
	</ul>


<script>
var parent = document.getElementsByClassName('menu').innerHTML ;
console.log(parent);

var parent = document.getElementsByClassName('menu').parentNode  ;
console.log(parent);
	
var parent = document.getElementsByClassName('menu').childNodes  ;
console.log(parent);
	
var parent = document.getElementsByClassName('menu').attributes   ;
console.log(parent);
</script>

</body>
</html>

控制台结果:

在这里插入图片描述
可以看到,是没有结果的。

测试 getElementsByTagName

在线测试代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
	<style>
		.display{
			display:none;
		}
	</style>
</head>
<body>
   <ul class="menu">
            <li>
                <a href="#" >菜单选项</a>
                <ul class="display">
                    <li><a href="#" >选项1</a></li>
                    <li><a href="#" >选项2</a></li>
                </ul>
            </li>
	</ul>


<script>
var parent = document.getElementsByTagName('div').innerHTML ;
console.log(parent);

var parent = document.getElementsByTagName('div').parentNode  ;
console.log(parent);
	
var parent = document.getElementsByTagName('div').childNodes  ;
console.log(parent);
	
var parent = document.getElementsByTagName('div').attributes   ;
console.log(parent);
</script>

</body>
</html>

控制台结果:
在这里插入图片描述

总结

HTMLCollection 对象,其实是一个比较麻烦的数据,常用 元素对象,来获取 HTML DOM 元素对象,这样就可以用参考链接内的所有方法了。之前可能有点混乱,现在理顺了逻辑,总之,如果使用的是 get 开头的方法,是没法用 CSS选择器的方法,去获取 HTML DOM 对象。

除非是

element.querySelector():返回匹配指定 CSS 选择器元素的第一个子元素
document.querySelectorAll() : 返回匹配指定 CSS 选择器元素的所有子元素节点列表

之前是混合了 CSS选择器,弄乱了逻辑,现在清楚了只有这两个方法,才能利用 CSS选择器的方法,查找想要的元素对象,并进行处理。

个人特别理解

elementgetElementById 方法返回值。

getElementsByClassNamegetElementByTagNmae方法,可以用数组的方式,for 循环执行
例如:

document.getElementsByClassName("example")[0];

插入 js 代码,最好最好是在 HTML 文件内 body 标签的最后,否则有可能会出现
document.getElementById()获取值打印为null?

这是由于加载顺序问题,html文档是从上往下加载,而不会全部加载后再执行js代码,因此导致get不到节点的信息

解决方案

  1. 在body标签下引入js文件
  2. 将js代码加一个onload函数

参考链接:

HTML DOM 元素对象

document.getElementById()获取值打印为null?解决问题

关于灵活运用 HTMLCollection 对象方法应对复杂情况的代码测试

这里要提一句,没法用 CSS 选择器那样去调用,一开始,我也是把它们弄混了,后来发现,异想天开。

下面是之前提到过的,要理解根节点的概念,只有下一级的标签元素对象,就可以使用无限个 .firstElementNode的方法,去获取下一级的标签元素对象,而 HTML DOM 就是这么挠头,因为是递归的排序,所以有时候在找指定标签对象时,想要获取同级的元素对象,会挺麻烦的,这就得靠 兄弟节点方法了,这是笔者突然间灵感迸发的,请随意。

代码测试1:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
	<style>
		.display{
			display:none;
		}
	</style>
</head>
<body>
   <ul id="menu">
            <li>
                <a href="#" >菜单选项</a>
                <ul class="display">
                    <li><a href="#" >选项1</a></li>
                    <li><a href="#" >选项2</a></li>
                </ul>
            </li>
	</ul>


<script>
var parent = document.getElementById('menu').getElementsByClassName('display');
console.log(parent);


</script>

</body>
</html>

控制台结果:

在这里插入图片描述

代码测试2:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
	<style>
		.display{
			display:none;
		}
	</style>
</head>
<body>
   <ul id="menu">
            <li>
                <a href="#" >菜单选项</a>
                <ul class="display">
                    <li><a href="#" >选项1</a></li>
                    <li><a href="#" >选项2</a></li>
                </ul>
            </li>
	</ul>


<script>
var parent = document.getElementById('menu').getElementsByTagName('a');
console.log(parent);


</script>

</body>
</html>

控制台结果:

在这里插入图片描述

代码测试3:(菜单栏隐藏测试)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
	<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>

	<style>
		.display{
			display:none;
		}
	</style>
</head>
<body>
	<div id="menu">
   		<ul>
            <li>
                <a href="#" >菜单选项</a>
                <ul>
                    <li><a href="#" >选项1</a></li>
                    <li><a href="#" >选项2</a></li>
                </ul>
            </li>
	   <li>
                <a href="#" >菜单选项1</a>
                <ul>
                    <li><a href="#" >选项1</a></li>
                    <li><a href="#" >选项2</a></li>
                </ul>
            </li>
		</ul>
	</div>

<script>
		for(var i=1;i<3;i++){
			  document.getElementById('menu').getElementsByTagName('ul')[i].classList.toggle("display");

		}
</script>

</body>
</html>

原图:
在这里插入图片描述

在这里插入图片描述

效果图:

在这里插入图片描述
按数组来查找标签、类对象,是以递归方式查找的,递归查找到了,就当做下一个下标的元素,而不是按照查找子代选择器那样,查找对象的。

参考链接:

HTML DOM 方法

5、返回 NodeList 对象的方法

parentNode

parentNode 获取父节点标签对象的方法

querySelector()

语法:

document.querySelector(CSS selectors)

querySelector() 获取指定标签的第一个子节点(标签/元素)对象

特别特别注意:是 document 开头的

querySelectorAll()

语法:

elementList = document.querySelectorAll(selectors);

特别特别注意:是 document 开头的

有趣的测试, HTML 语言被覆盖

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Muxiu Test</title>
</head>
<body>

<h2>JavaScript 对象</h2>
	
	<ul>
		<p id="demo">muxiu0
            <li>
<!-- li 标签不和 ul 标签父子关系,也没问题,可以单独使用,类似 p 标签,应该是所有的标签都是这种情况 -->
            </li>
        </p>
        
		<p id="demo1">muxiu1
            <p id="demo3">muxiu3</p>
        </p>

		<p id="demo2">muxiu2</p>
        <li>
<!-- 这里被 li 截断了,但也没问题,每一个 li 标签 都会显示一个黑点,这需要用 css style 样式配置消失 -->
        </li>
		<button onclick="myfunction(this)">点我后就变帅变靓</button>
        
	</ul>

	
<script>
function myfunction(obj){
    // 按钮对象
	document.getElementById("demo").innerHTML =  obj;
	// 按钮对象的父节点
	document.getElementById("demo1").innerHTML =  obj.parentNode;
	// 按钮对象的父节点的第一个标签对象
	document.getElementById("demo2").innerHTML =  obj.parentNode.querySelector("p") + "id 为 demo2 的 p 标签对象";
    //  
    // document.getElementById("demo1").firstElementChild.innerHTML = "找到了 id 为 demo1 的标签对象,然后利用每一个对象都默认自带的 innerHTML 属性";

	document.getElementById("demo3").innerHTML = document.getElementById("demo1").firstElementChild;
}
</script>
	
</body>
</html>

初始图:
在这里插入图片描述

结果图:
在这里插入图片描述
很显然 HTML 代码内的 p 标签的元素内容没 innerHTML 给弄没了,所以这个 js 代码毫无作用,如下所示。

在这里插入图片描述
毫无作用
在这里插入图片描述

有趣的测试 1 - 获取子节点 - 有趣的 p 标签

测试代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Muxiu Test</title>
</head>
<body>

<h2>JavaScript 对象</h2>
	
	<ul>
		<p id="demo">muxiu0
            <li>
<!-- li 标签不和 ul 标签父子关系,也没问题,可以单独使用,类似 p 标签,应该是所有的标签都是这种情况 -->
            </li>
        </p>
        
		<p id="demo1">muxiu1</p>

		<p id="demo2">muxiu2</p>

		<p id="demo3">muxiu3</p>

		<p id="demo4">
			<p id="demo5">muxiu4</p>
		</p>

        <li>
<!-- 这里被 li 截断了,但也没问题,每一个 li 标签 都会显示一个黑点,这需要用 css style 样式配置消失 -->
        </li>
		<button onclick="myfunction(this)">点我后就变帅变靓</button>
        
	</ul>

	
<script>
function myfunction(obj){
    // 按钮对象
	document.getElementById("demo").innerHTML =  obj;
	// 按钮对象的父节点
	document.getElementById("demo1").innerHTML =  obj.parentNode;
	// 按钮对象的父节点的第一个标签对象
	document.getElementById("demo2").innerHTML =  obj.parentNode.querySelector("p") + "id 为 demo2 的 p 标签对象";
    //  
    // document.getElementById("demo1").firstElementChild.innerHTML = "找到了 id 为 demo1 的标签对象,然后利用每一个对象都默认自带的 innerHTML 属性";
	// 获取子节点
	document.getElementById("demo3").innerHTML = document.getElementById("demo4").children[0];

	document.getElementById("demo5").innerHTML = "demo5";
}
</script>
	
</body>
</html>

初始图:
在这里插入图片描述
结果图:
在这里插入图片描述
可以看到一个 undefined ,有点不懂,先埋坑。

有趣的测试 2 - 获取子节点

测试代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Muxiu Test</title>
</head>
<body>

<h2>JavaScript 对象</h2>
	
	<ul>
		<p id="demo">muxiu0
            <li>
<!-- li 标签不和 ul 标签父子关系,也没问题,可以单独使用,类似 p 标签,应该是所有的标签都是这种情况 -->
            </li>
        </p>
        
		<p id="demo1">muxiu1</p>

		<p id="demo2">muxiu2</p>

		<p id="demo3">muxiu3</p>

		<p id="demo4">
			<p id="demo5">muxiu4</p>
		</p>

        <li>
<!-- 这里被 li 截断了,但也没问题,每一个 li 标签 都会显示一个黑点,这需要用 css style 样式配置消失 -->
        </li>
		<button onclick="myfunction(this)">点我后就变帅变靓</button>
        
	</ul>

	
<script>
function myfunction(obj){
    // 按钮对象
	document.getElementById("demo").innerHTML =  obj;
	// 按钮对象的父节点
	document.getElementById("demo1").innerHTML =  obj.parentNode;
	// 按钮对象的父节点的第一个标签对象
	document.getElementById("demo2").innerHTML =  obj.parentNode.querySelector("p") + "id 为 demo2 的 p 标签对象";
    //  
    // document.getElementById("demo1").firstElementChild.innerHTML = "找到了 id 为 demo1 的标签对象,然后利用每一个对象都默认自带的 innerHTML 属性";

	// 获取子节点
	document.getElementById("demo3").innerHTML = document.getElementById("demo4").firstElementChild;

	document.getElementById("demo5").innerHTML = "demo5";
}
</script>
	
</body>
</html>

初始图:
在这里插入图片描述
结果图:
在这里插入图片描述
子节点 demo3 消失了,可以推理出 iddemo4 p 标签嵌套有问题。

有趣的测试 3 - 获取子节点

测试代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Muxiu Test</title>
</head>
<body>

<h2>JavaScript 对象</h2>
	
	<ul>
        <li id="demo1">
			<p id="demo2">muxiu1</p>

		</li>
		
		<p id="demo3">
			<p id="demo4">muxiu</p>
		</p>

		<button onclick="myfunction(this)">点我后就变帅变靓</button>
        
	</ul>

	
<script>
function myfunction(obj){
    

	// 获取子节点
	document.getElementById("demo2").innerHTML = document.getElementById("demo1").children[0];

	document.getElementById("demo4").innerHTML = document.getElementById("demo3").children[0];
}
</script>
	
</body>
</html>

初始图:
在这里插入图片描述
结果图:
在这里插入图片描述
从结果图,推理知道,同种标签的嵌套的确有可能出问题

有趣的测试 4 - 获取子节点

测试代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Muxiu Test</title>
</head>
<body>

<h2>JavaScript 对象</h2>
	
	<ul>
        <li id="demo1">
			<p id="demo2">muxiu1</p>

		</li>
		
		<p id="demo3">
			<p id="demo4">muxiu2</p>
			<a id="demo5">muxiu3</a>
		</p>

		<button onclick="myfunction(this)">点我后就变帅变靓</button>
        
	</ul>

	
<script>
function myfunction(obj){
    

	// 获取子节点
	document.getElementById("demo2").innerHTML = document.getElementById("demo1").children[0];

	document.getElementById("demo4").innerHTML = document.getElementById("demo3").children[0];

	document.getElementById("demo5").innerHTML = document.getElementById("demo3").children[1];
}
</script>
	
</body>
</html>

初始图:
在这里插入图片描述
结果图:
在这里插入图片描述
这个测试是补充测试,看看加了其他标签在里面,会不会有所不同,看来结果,是一样的,出问题了。

参考链接

querySelector()方法的使用

js 获取子节点的多种方式

详解NodeList 和 HTMLCollection 和 Array

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值