《JavaScript Dom 编程艺术》读书笔记-第7章
动态创建标记~内容包括:
1. 传统技术:document.write 和innerHTML
2. 深入剖析DOM方法:createElemen、createTextNode、appendChild和innerBefore
核心在于JavaScript也可以用来改变网页的结构和内容。
传统方法:document.write。违背了行为应该与表现分离。
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Test</title> </head> <body> <script>document.write("hello world")</script> </body> </html>
以插入的字符串为参数,将一个<p>,字符串和</p>标签拼接到一起。
function insertParagraph(text){ var str="<p>"; str+=text; str+="</p>"; document.write(str); }
在HTML文档中插入:
<script src="example.js"></script> <script>insertParagraph("hello world")</script>
想这样把JS与HTML混杂起来很不好。只要有可能,就应该用外部CSS文件代替<font>标签去设定和管理页面的样式,最好用外部JavaScript文件去控制网页行为。应该避免在<body>部分乱用<script>标签,避免使用document.write方法。
innerHTML
先如今的浏览器几乎都支持innerHTML,这个属性并不是W3C DOM标准的组成部分,但现在已经包含到HTML5规范中。
innerHTML属性可以用来读写某个给定元素里的HTML内容。
<div> <p>this is <em>my</em> content</p> </div>
window.onload=function(){ var testdiv=document.getElementById("testdiv"); alert(testdiv.innerHTML);//输出<p>this is <em>my</em> content</p>
}
innerHTML属性毫无细节可言。一旦使用innerHTML,它的全部内容都会被替换。
window.onload=function(){ var testdiv=document.getElementById("testdiv"); testdiv.innerHTML="<p>this is <em>my</em> content</p>"; }
要想获得细节,就必须使用DOM方法和属性。在任何时候,标准的DOM都可以用来代替innerHTML。
DOM方法
在DOM看来一个文档就是一颗节点树。如果你想在节点树上添加内容,就必须插入新的节点。
<div id="testdiv"> </div>
createElement:
var para=document.createElment<"p">;
appendChild:
var testdiv=document.getElementById("testdiv"); testdiv.appendChild=para;
createTextNode
window.onload=function(){
var para=document.createElement("p");
var testdiv=document.getElementById("testdiv");
testdiv.appendChild(para);
var txt=document.createTextNode("hello world");
para.appendChild(txt);
}
一个更复杂的组合。现在想显示如下内容:
<p>this is <em>my</em> content</p>
JS代码如下:
window.onload=function(){ var para=document.createElement("p"); var testdiv=document.getElementById("testdiv"); testdiv.appendChild(para); var txt=document.createTextNode("this is"); para.appendChild(txt); var emph=document.createElement("em"); var txt2=document.createTextNode("my"); emph.appendChild(txt2); para.appendChild(emph); var txt3=document.createTextNode(" content"); para.appendChild(txt3);
}
重回图片库
图片库中的placeholder和描述是只为了图片显示而存在的,所以此处我们将用DOM来创建它们。
var placeholder=document.createElement("img");//创建图像节点 placeholder.setAttribute("src",image/1.jpg); placeholder.setAttribute("id",placehold); placeholder.setAttribute("alt",my image gallery); var describe=document.createElement("p");//创建描述节点 describe.setAttribute("id",description); var txt=document.createTextNode("this is a description"); describe.appendChild(txt); document.getElementsByTagName("body")[0].appendChild(placeholder);//插入至BODY元素 document.getElementsByTagName("body")[0].appendChild(describe);
在已有元素前插入一个新元素:
parentElement.insertBefore(newElement,targetElement);
var gallery=document.getElementById("imagegallery");//等同于上面JS代码的后两行 gallery.parentNode.insertBefore(placeholder,gallery); gallery.parentNode.insertBefore(describe,gallery);
在已有元素后插入一个新元素:
DOM本身没有提供insertAfter的方法,但可以自己写一个。
function insertAfter(newElement,targetElement){ var parent=targetElement.parentNode; if (parent.lastChild==targetElement) { parent.appendChild(newElement); }else { parent.insertBefore(newElement,targetElement.nextSibling); } }
Ajax:异步加载网页的技术。对页面的请求以异步方式发送到服务器。服务器不会用整个页面来响应请求,他会在后台处理请求,与此同时用户还能继续浏览网页并与页面交互。JS脚本按需加载和创建网页内容,而不会打断用户的浏览体验。Ajax依赖于JavaScript。
技术的核心是XMLHttpRequest对象。(充当浏览器中的脚本【即客户端】与服务器之间的中间人角色)。
例子:
HTML文档
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Ajax</title> </head> <body> <div id="new"></div> <script src="addLoadEvent.js"></script> <script src="getHTTPObject.js"></script> <script src="getNewContent.js"></script> </body> </html>
三个JS文件:
function addLoadEvent(func){ var oldload=window.onload; //alert(typeof oldload) if (typeof oldload !='function') { window.onload=func;//为什么此处window.onload不能换为oldload }else{ window.onload=function(){ oldload(); func(); } } }
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(); }
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~~~") } } addLoadEvent(getNewContent)
使用XMLHttpRequest对象发送的请求只能访问与其所在的HTML处于同一个域中的数据,不能向其他域发送请求。有些浏览器会限制Ajax的协议。比如在chrome中,如果使用file://协议从之间的硬盘中加载example.txt文件,就会看到Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https. 的错误消息。
异步请求容易被忽略的问题是异步性。脚本发送XMLHttpRequest请求之后,仍然会继续执行,不会等待响应返回。
渐进增强与Ajax.
一开始基于老式的页面刷新机制构建的,可以再既有框架的基础上,用Ajax拦住发送到服务器的请求,并将请求交给XMLHttpRequest对象处理。
构建Ajax网站最好的方法,先构建一个常规的网站,然后Hijax(渐进增强的使用Ajax)它。
小结:
createElement
createTextNode
appendChild
insertBefore.