《JavaScript DOM 编程艺术》读书笔记

事件处理函数

在预定事件发生时让预先安排好的JavaScript代码开始执行,即“触发一个动作”。
例如:onclick,onmouseover,onmouseout等等。

语法:event = "JavaScript statement(s)", JavaScript代码是包含在双引号中的,可以把任意数量的JavaScript语句放在这对引号之间,分号隔开即可。

机制:给某个元素添加事件处理函数后,一旦发生预定事件,相应的JavaScript代码就执行,执行后可以返回一个结果,这个结果被传递回事件处理函数

利用这个机制,我们可以让动作没有触发,但是却能执行触发之后的JavaScript代码。比如书中的“JavaScript美术馆例子”:onclick事件中,点击链接执行一段预定代码,在代码后加上"return false;",那么代码依旧被执行,但是页面却不会跳转,因为返回false给事件处理函数,认为“这个链接没有被点击”。代码如下。

<body>
	<h1>Snapshots</h1>
	<ul>
		<li><a href="F:\壁纸\973279.jpg" onclick="showPic(this); return false;">Aquaman</a></li>
		<li><a href="F:\壁纸\923047.jpg" onclick="showPic(this); return false;">Forest</a></li>
		<li><a href="F:\壁纸\486147.jpg" onclick="showPic(this); return false;">Boat</a></li>
		<li><a href="F:\壁纸\340480.jpg" onclick="showPic(this); return false;">Cat</a></li>
	</ul>
	<img src="F:\壁纸\973279.jpg" id="placeholder">
</body>

getElementsByTagName()方法

  • 返回对象数组:数组每个元素都是一个对象,含有属性方法
  • 利用length属性:getElementsByTagName().length得知数组元素个数
  • 通配符*的使用:某个文档的总元素节点个数:document.getElementsByTagName(“*”)
  • 具体元素包含元素个数:同理可以联合getElementById()或者其他DOM选取元素的方法,得知某个具体元素包含多少元素节点.

例子:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<div id="first">
		<span></span>
		<span></span>
		<span></span>
		<span></span>
	</div>
	<div id="second">
		<ul>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<ul>
			<li></li>
			<li></li>
			<li></li>
		</ul>
	</div>
	<script type="text/javascript">
		//javascript here
	</script>
</body>
</html>
	var total = document.getElementsByTagName("*");
	console.log("the number of nodes: " + total.length);
	//28 整个文档的所有节点,包括根节点html
	var div$first =document.getElementById("first");
	var total = div$first.getElementsByTagName("*");
	console.log(total.length);
	//4 #first节点包含的元素个数,不包括#first节点自己

childNodes

  • 返回对象数组:数组包含给定元素节点全体子元素
  • 语法:element.childNodes
  • 返回所有类型的节点:包括元素节点属性节点文本节点
  • 快速选择body元素:document.body,代替document.getElementsByTagName("body")[0]

事实上,文档里几乎所有东西都是一个节点,甚至空格和换行符都被解释为节点,而它们都包含在childeNodes返回的数组当中,所以childNodes返回的结果可能和我们预想的不一样。

使用nodeType属性区分文档里的各个节点。

nodeType

nodeType属性总共有12种可取值,但仅有3中有使用价值:

  • 元素节点返回1
  • 属性节点返回2
  • 文本节点返回3

nodeValue与innerHTML的区别

  • nodeValue 是节点的值,其中属性节点文本节点是有值的,而元素节点没有值
  • innerHTML 以字符串形式返回该节点的所有子节点及其值

例子:

<p id="example" title="texts">
  这是一段文本
  <span></span>
</p>
var p = document.getElementById("example");
console.log(p.nodeValue); //null p是元素节点,没有节点值
console.log(p.innerHTML); //p标签内部的所有子节点和值

这里又会牵涉到innerHTML和document.write()的区别:

  • innerHTML是在元素中添加HTML文档的内容,只改变选中的元素内部,不会覆盖整个文档
  • document.write()是写进整个文档,覆盖原来整个文档的内容

把多个JavaScript函数绑定到onload上

有时候函数func1()会对DOM文档树进行操作,如果DOM不完整,则函数不能正常执行,必须要让函数在网页加载完成之后才能执行,而网页加载完毕时会触发一个onload事件

window.onload = func1;即可解决问题,不过如果有多个函数func2()、func3()…
window.onload = func1; window.onload = func2;func2将会取代func1,

因为每个事件处理函数只能绑定一条指令。

于是可以创建一个匿名函数来包含这些函数:

window.onload = function() {
	func1();
	func2();
}

也可以使用更加通用的方法——addLoadEvent(),这是个自编的函数:

function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function')
		window.onload = func;
	else {
		window.onload = function() {
			oldonload();
			func();
		}
	}
}

相当于把那些将在页面加载完毕时执行的函数创建为一个队列,把刚刚那两个函数加入到队列里,即

addLoadEvent(func1);
addLoadEvent(func2); //不加(),因为不是调用,而是引用这个函数名

DOM Core 和 HTML-DOM

获取和设置元素属性的时候,我发现,有些属性可以直接使用ele.propertyname的方式获取和设置,有些则不行,要通过getAttribute()和setAttribute()进行操作,现在可以对这个进行解释了。

诸如getElementById()/getElementsByTagName()/setAttribute()/getAttribute()等方法都是DOM Core的组成部分。它们并不专属于JavaScript,支持DOM的任何一种程序设计语言都可以使用它们。


而在使用JavaScript和DOM编写脚本时,还有许多属性可以选用,这些属性专属于HTML-DOM,也就是之前讲的简化书写方式,诸如document.body/document.forms/document.images/element.src等等。


DOM 操作节点

一个文档就是一个DOM节点树,在节点树上增加内容,就必须插入新的节点,而对DOM节点树的操作是以动态的方式创建HTML内容——并不是真的“物理上”创建HTML内容,而是修改DOM节点树

关于节点,回顾有三种:元素节点、属性节点、文本节点。

创建元素节点:createElement()

  • 创建一个元素节点document.creatElement("p");

创建文本节点:createTextNode()

  • 创建一个文本节点document.creatTextNode(text);

插入到DOM节点树中:appendChild()

  • 把新元素插入节点树:parent.appendChild(child);
    例如:
    var para = document.creatElement("p");
    var target = document.getElementById("target");
    target.appendChild(para);
    
    和下面这种不赋值变量引用是等价的:
    document.getElementById("target").appendChild(document.creatElement("p"));
    
    可知使用一些变量引用父节点和子节点更加容易阅读和理解。

如何设置属性节点?

  1. setAttribute()
    直接在DOM节点添加属性,用法比较简单:
    element.setAttribute(attributename,attributevalue)

    例子:

    <p >
        <span>1</span>,
        <span>2</span>
        <span>3</span>
        <span>4</span>
        <span>5</span>
    </p>
    

    在p元素节点添加title属性:

    var p=document.getElementsByTagName('p')[0];
    p.setAttribute('title','one to five');
    
  2. creatAttribute()
    效果一样,但是用法复杂些:element.setAttributeNode(attributenode)

    例子:

    var ti=document.createAttribute('title');//创建独立的属性节点
    ti.nodeValue='one to five';//设置属性节点值 ti.value也行
    var p=document.getElementsByTagName('p')[0];
    p.setAttributeNode(ti)//追加的设置属性节点
    

insertBefore()方法

DOM提供的方法,将一个元素插入到一个现有元素前面,调用时需要知道三个节点:

  • 父节点
  • 新节点
  • 目标节点

语法:parentElement.insertBefore(newElement, targetElement);

例子:

var gallery = document.getElementById("imagegallery");
gallery.parentNode.insertBefore(placeholder, gallery);

其中parentNode属性返回父元素。

insertAfter()方法

DOM本身没有提供insertAfter()方法,但是我们可以自己写一个:

function insertAfter(newElement, targetElement) {
	var parent = targetElement.parentNode;
	if(parent.lastChild == targetElement) {
		parent.appendChild(newElement);
	}
	else {
		parent.insertBefore(newElement, targetElement.nextSibling);
	}
}

其中,nextSibling属性返回相邻下一个兄弟节点,lastChild返回最后一个孩子节点,同理firstChild返回第一个孩子节点。

cloneNode()

var node=document.getElementById("myList2").lastChild.cloneNode(true);
document.getElementById("myList1").appendChild(node);

参数true:
可选。该方法将复制并返回调用它的节点的副本。如果传递给它的参数是 true,它还将递归复制当前节点的所有子孙节点。否则,它只复制当前节点。


className和classList

  1. className 属性设置或返回元素的 class 属性。还可以添加class。返回值为字符串
    例如:element.className += “test1 test2”;

  2. classList 属性返回元素的类名,作为 DOMTokenList 对象

    该属性用于在元素中添加,移除及切换 CSS 类。

    classList 属性是只读的,但可以使用 add()remove() 方法修改它。

    例如:element.classList.add(“class1”, “class2”, “class3”);

<body>
	<div class="haha look another"></div>
	<script type="text/javascript">
		var div = document.getElementsByTagName("div")[0];
		console.log(div.classList);
	</script>
</body>

结果为:



【待更新…】

posted @ 2019-05-13 17:23  绣花  阅读(111)  评论(0编辑  收藏  举报