0%

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

动态创建标记

DOM方法

createElement

目标:将一段文本插入如下testdiv元素

1
2
<div id="testdiv">
</div>
  1. 创建一个新的元素;
  2. 把这个新元素插入节点树。
1
2
3
var para = document.createElement('p'); // 文档碎片
var testdiv = document.getElementById("testdiv");
testdiv.appendChild(para);

createTextNode

注意createElementcreateTextNode的区别。

创建文本节点:

1
2
3
document.createTextNode("Hello World");
var txt = document.createTextNode("Hello World");
para.appendChild(txt);

例子

插入一个简单的元素

1
<p>This is <em>my</em> content.</p>

节点树:

代码:

1
2
3
4
5
6
7
8
9
10
var para = document.createElement('p');
var txt1 = document.createTextNode("This is ");
var em = document.createElement('em');
var em_txt = document.createTextNode("my");
var txt2 = document.createTextNode(" content.");
para.appendChild(txt1);
em.appendChild(em_txt);
para.appendChild(txt3);
var testdiv = document.getElementById("testdiv");
testdiv.appendChild(para);

在已有元素前插入一个新元素

DOM提供了名为insertBefore()方法,这个方法将把一个新元素插入到一个现有元素的前面。

1
parentElement.insertBefore(newElement,targetElement);
  1. 新元素:你想插入的元素(newElement)
  2. 目标元素:你想把这个新元素插入到哪个元素(targetElement)之前
  3. 父元素:目标元素的父元素(parentElement)

我们可以通过targetEleent元素的parentNode来找到parentElement

在现有方法后插入一个新元素

编写insertAfter函数

实用已知的方法来编写一个insertAfter函数:

1
2
3
4
5
6
7
8
function insertAfter(newElement, targetElement) {
var parent = targetElement.parentNode;
if (parent.lastChild == targetElement) {
parent.appendChild(newElement);
} else {
parent.insertBefore(newElement,targetElement.nextSibling);
}
}

Ajax

实用Ajax可以做到只更新页面中的一小部分。其他内容——标志、导航、头部、脚部,都不用重新加载。用户仍然像往常一样点击链接,但这一次,已经加载的页面中只有一小部分区域会更新,而不必再次加载整个页面了。

Ajax的主要优势就是对页面的请求以异步方式发送到服务器。而服务器不会用整个页面来响应请求,它会在后台处理请求,与此同时用户还能继续浏览页面并与页面交互。你的脚本则可以按需加载和创建页面内容,而不会打断用户的浏览体验。

Ajax的核心是XMLHttpRequest对象。JS可以通过这个对象发送请求,然后自己处理响应。不同浏览器实现XMLHttpRequest的方式不太一样,为了保证跨浏览器,不得不为同样的事情写不同的分支。

这是我们的html页面:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Ajax</title>
</head>
<body>
<div id="new"></div>
<script src="scripts/addLoadEvent.js"></script>
<script src="scripts/getHttpObject.js"></script>
<script src="scripts/getNewContent.js"></script>
</body>
</html>

为了兼容所有浏览器(包括IE),getHttpObject.js中的getHTTPObject需要这么写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function getHTTPObject() {
if (typeof XMLHttpRequest == "undefined") {
XMLHttpRequest = function () {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
catch (e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
catch (e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP"); }
catch (e) {}
return false;
}
return new XMLHttpRequest();
}
}

现在我们来写一个Ajax的HTTP请求。XMLHttpReuqest的open方法可以用来指定服务器上将要访问的文件,指定请求类型:GET,POST或SEND。这个方法的第三个参数用于指定亲贵是否以异步的方式就发送和处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function getNewContent() {
var request = getHTTPObject();
if (request) {
request.open("GET", "example.txt", true);
request.onreadystatechange = function() {
if (request.readyState == 4) {
var para = document.createElement("p");
var txt = document.createTextNode(request.responseText);
para.appendChild(txt);
document.getElementById('new').appendChild(para);
}
}
request.send(null);
} else {
alert("Sorry, your browser does not support XMLHttpRequest");
}
}

addLoadEvent(getNewContent);

onreadystatechange是一个事件处理函数,它会在服务器给XMLHttpRequest对象送回响应的时候被触发执行。在这个处理函数中,可以更具服务区的具体响应做出相应处理。

在指定了请求的目标,也明确了如何处理响应后,就可以用send方法来发送请求了:request.send(null);

服务器在像XMLHttpRequest对象时,该对象有许多属性可用,浏览器会在不同阶段更新readyState属性的值,它有5个可能的值:

  • 0表示未初始化
  • 1表示正在加载
  • 2表示加载完毕
  • 3表示正在交互
  • 4表示完成

只要readState属性的值编程了4,就可以访问服务器发送回来的数据了。返回的数据主要有两个属性。一个是responseText,用于保存文本字符串形式的数据;另一个是responseXML用于保存Content-Type头部中指定为"text/xml"的数据,其实是一个DocumentFragment(文档碎片)对象。

异步请求有一个容易被忽略的问题就是异步性,就是脚本在发送XMLHttpRequest亲求后,仍然会继续执行,不会等待响应返回。

Hijax

拦截用户操作触发的默认请求,然后使用Ajax操作。在做到平稳退化的基础之上利用Ajax渐进增强。