考虑下面的代码:
<div id="testdiv"> 空白也是节点 <p>This is <em>my</em> content.</p> </div>
This is how the Document Object Model sees the markup inside “testdiv”, as shown in
Figure 7-1:Dom是这么看的:
笔记:其实这幅图有错误,一个元素的属性节点不是此元素的子节点。 看下面的代码:
var test=document.getElementById("testdiv"); document.writeln(test.childNodes.length); document.writeln(test.childNodes[0]); document.writeln(test.childNodes[1]); document.writeln(test.childNodes[2]);
会输出:3 [object Text] [object HTMLParagraphElement] [object Text]。请参看:http://www.quirksmode.org/dom/intro.html
但是innerHTML不是这么看的。
The innerHTML property takes a much simpler view. This is how it sees the markup inside
“testdiv”
window.onload = function() {
var testdiv = document.getElementById("testdiv");
alert(testdiv.innerHTML);
}
输出:<p>This is <em>my</em> content.</p>
The innerHTML property can be quite useful when you want a quick and easy way to insert
a chunk of HTML into a document. Unfortunately, innerHTML doesn’t return any references
to the content you insert. If you want to manipulate the inserted content, you’ll
need the precision offered by DOM methods.
innerHTML compares favorably to document.write. Using innerHTML, you can keep your
JavaScript separate from your markup. There’s no need to insert <script> tags into the
<body> of your document.
我们可以用innerHTML插入元素,也可以用下面的方法 插入元素:
<body> <script> document.write("<p>This is inserted.</p>"); </script> </body>
但这两种方法都不好。
DOM methods
The DOM is a two-way street. You can query the contents of a document, but you can also
update the contents of a document. If you change the DOM tree, you will change the document
as viewed in a browser.
You haven’t physically changed the document. If you open up the document in a text editor instead of a browser, you won’t see a changed attribute. The changes to the document can only be seen when a browser renders the document. This is because the browser is really displaying the DOM tree. As far as the browser is concerned, the DOM tree is the document.
使用dom方法事实上我们并没有改变元素。
Once you understand this, the idea of creating markup on the fly isn’t quite so strange. You aren’t really creating markup, you’re updating the Document Object Model. The key to doing this is to think in the same terms as the DOM. According to the Document Object Model, a document is a tree of nodes. If you want add
to this tree, you need to insert new nodes. If you want to add markup to a document, you need to insert element nodes。
createElement
<div id="testdiv"> </div>
I want to insert a paragraph into “testdiv”. To use the language of the DOM, I want to add
a p element node as a child node of the div element node (which already has one child
node: an id attribute node with the value “testdiv”).
This is a two-step process:
1. Create the new element.
2. Insert the element into the node tree.
You can achieve the first step by using a DOM method called createElement.
This is the syntax:
document.createElement(nodeName)
This statement will create a paragraph element:
document.createElement("p");
By itself, this method won’t prove very useful. You will want to insert the newly created
element node into the document. To do this, you’ll need to be able to refer to the newly
created node. Whenever you use createElement, it’s a good idea to assign the newly created
element to a variable:为新创建的元素赋给变量。
var para = document.createElement("p");
The variable para now contains a reference to the p element you’ve just created.
Right now, this newly created paragraph element is floating in JavaScript limbo监狱. The element
exists, but it isn’t part of the DOM node tree. This is a DocumentFragment. It isn’t
displayed in the browser. Nonetheless, it has DOM properties, just like any other node.
The homeless paragraph element has a nodeType value and a nodeName value. You can test
this for yourself by putting this into example.js:
window.onload = function() { var para = document.createElement("p"); var info = "nodeName: "; info+= para.nodeName; info+= " nodeType: "; info+= para.nodeType; alert(info); }
The node exists. It has the nodeName property with the value “P”. It also has a nodeType
property with the value 1, which means it’s an element node. But this node is not connected
to the node tree of the document, test.html.
使用appendChild 插入:
parent.appendChild(child)
最终代码如下:
var para = document.createElement("p"); var testdiv = document.getElementById("testdiv"); testdiv.appendChild(para);
You have now created an element node and inserted it into the node tree of the document.
The node you have created is an empty paragraph element. If you want to put some text
into that paragraph, you can’t use createElement. That only works for creating element
nodes. You need to create a text node. You can do this using a method called
createTextNode.
语法:
document.createTextNode(text)
Again, it’s a good idea to assign a variable to contain the newly created node:
var txt = document.createTextNode("Hello world");
The variable txt contains a reference to the newly created text node. This node is floating
free in JavaScript. It hasn’t been tethered to the node tree of a document.
You can use appendChild to make the text the child node of an existing element. You could
insert the text into the paragraph element you created. The variable para is a reference to
the paragraph element. The variable txt is a reference to the newly created text node:
para.appendChild(txt);
In this example, nodes were created and appended in this order:
1. Create a paragraph element node.
2. Append this paragraph to an element node in the document.
3. Create a text node.
4. Append this text node to the paragraph.
You can also use appendChild to join nodes that aren’t yet part of the document tree. That
means you could rewrite the steps in this order:
1. Create a paragraph element node.
2. Create a text node.
3. Append this text node to the paragraph.
4. Append this paragraph to an element node in the document.
想要用dom方法插入如下markup:
<p>This is <em>my</em> content.</p>
elementNode.setAttribute(name,value)
如果此属性不存在,将创建。
如果属性不存在,则 setAttribute() 可创建一个新的属性, addAtribute() 这个方法是不存在的。
insertBefore
insertBefore() 方法用于在指定的子节点之前插入节点。
You must specify three things:
1. the new element you want to insert,
2. the target element before which you want to insert it,
3. the parent of both elements.
Here’s the syntax:
parentElement.insertBefore(newElement,targetElement)
如果 insertBefore() 的第二个参数是 null,新节点将添加到最后一个已有的子节点之后。
x.insertBefore(newNode,null) 和 x.appendChild(newNode) 都可以向 x 追加一个新的子节点。
You can also use the insertBefore method to insert/move an existing element.
<!DOCTYPE html> <html> <body> <ul id="myList1"><li>Coffee</li><li>Tea</li></ul> <ul id="myList2"><li>Water</li><li>Milk</li></ul> <p id="demo">Click the button to move an item from one list to another</p> <button onclick="myFunction()">Try it</button> <script> function myFunction() { var node=document.getElementById("myList2").lastChild; var list=document.getElementById("myList1"); list.insertBefore(node,list.childNodes[0]); } </script> </body> </html>
点击按钮后,mylist2的后一个li会跑到第一个mylist1里。演示:http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_node_insertbefore2
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>Image Gallery</title> <script> function showPic(whichpic) { var source = whichpic.getAttribute("href"); var text = whichpic.getAttribute("title"); var description=document.getElementById("description"); description.firstChild.nodeValue=text; var placeholder = document.getElementById("placeholder"); placeholder.setAttribute("src",source); } </script> <style type="text/css"> body{ 750px; margin:0 auto; padding:0; background:#9F9; } ul{ background:#FF6; padding:20px; } li{ display:inline; padding:10px; margin:10px; } img{ text-align:center; padding:10px; margin:10px; border:5px solid red; background:blue; } </style> </head> <body> <h1>Snapshots</h1> <ul> <li> <a href="images/fireworks.jpg" title="A fireworks display" onClick="showPic(this); return false; ">Fireworks</a> </li> <li> <a href="images/coffee.jpg" title="A cup of black coffee">Coffee</a> </li> <li> <a href="images/rose.jpg" title="A red, red rose">Rose</a> </li> <li> <a href="images/bigben.jpg" title="The famous clock">Big Ben</a> </li> </ul> <img id="placeholder" src="images/placeholder.gif" alt="placeholder" /> <p id="description">Choose an image.</p> </body> </html>
我们想动态创建:
<img id="placeholder" src="images/placeholder.gif" alt="placeholder" />
<p id="description">Choose an image.</p>
元素,代码如下:
function preparePlaceholder(){ var placeholder=document.createElement("img"); placeholder.setAttribute("id","placeholder"); placeholder.setAttribute("src","imags/placeholder.gif"); placeholder.setAttribute("alt","my image gallery"); var description=document.createElement("p"); description.setAttribute("id","description"); var txt=document.createTextNode("Choose an images"); description.appendChild(txt); document.body.appendChild(placeholder); document.body.appendChild(description); }
document.body.appendChild(placeholder); 等于:
document.getElementsByTagName("body")[0].appendChild(placeholder);
Although the DOM hasn’t provided a method 方法called insertAfter, it has provided all the
tools you need to insert a node after another node. You can use existing DOM methods
and properties to create a function called insertAfter.
我们可以自己创建insertAfter(本来dom没有这个方法)函数:
function insertAfter(newElement,targetElement) { var parent = targetElement.parentNode; if (parent.lastChild == targetElement) { parent.appendChild(newElement); } else { parent.insertBefore(newElement,targetElement.nextSibling); } }