JavaScript DOM编程艺术 读书笔记
2. JavaScript语法
3. DOM(document、object、model )
有3种DOM方法可获取元素节点,分别是通过元素ID、通过标签名字和通过类名字来获取。
1) getElementById(id)
2) getElementByTagName(tag):返回一个对象数组,每个对象分别对应着文档里有着给定标签的一个元素。
3) getElementByClassName(class):HTML5 DOM,某些DOM实现里可能还没有;返回一个具有相同类名的元素的数组。
function getElementsByClassName(node, classname){ if(node.getElementsByClassName){ return node.getElementsByClassName(classname); } else { var result = new array(); var elements = getElementsByTagName("*"); for(var i=0; i<elements.length; i++){ if(elements[i].clsssName.indexOf(classname) != -1){ result[result.length] = elements[i]; } } return false; } }
4. 案例研究:JavaScript图片库
childNodes属性获取任何一个元素的所有子元素,它是一个包含这个元素全部子元素的数组:element.childNodes。通过element.childNodes.length获取element元素包含的元素的个数。由childNodes属性返回的数组包含所有类型的节点,而不仅仅是元素节点。事实上,文档里几乎每一样东西都是一个节点,甚至连空格和换行符都会被解释为节点,而它们也全都包含在childNodes属性所返回的数组当中。
nodeType属性可以查看到节点类型,但其返回值是一个数字而不是“element”或“attribute”那样的英文字符串。nodeType属性共有12种可取值,但其中仅有3种具有实用价值:
1)元素节点的nodeType属性值是1;
2)属性节点的nodeType属性值是2;
3)文本节点的nodeType属性值是3;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
body {font-family:"Helvetica","Arial",serif; color:#333; background-color:#ccc; margin:1em 10%;} h1 {color:#333; background-color:transparent;} a {color:#c60; background-color:transparent; font-weight:bold; text-decoration:none;} ul {padding:0;} li {float:left; padding:1em; list-style:none;} img {display:block; clear:both;}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Image Gallery</title> <link rel="stylesheet" href="../css/layout.css" media="screen" /> </head> <body> <h1>Snapshots</h1> <ul> <li><a href="../images/1.jpg" onclick="showPic(this);return false;" title="A firework display">Fireworks</a></li> <li><a href="../images/2.jpg" onclick="showPic(this);return false;" title="A cup of black coffee">Coffee</a></li> <li><a href="../images/3.jpg" onclick="showPic(this);return false;" title="A red,red rose">Rose</a></li> <li><a href="../images/4.jpg" onclick="showPic(this);return false;" title="The famous clock">Big Ben</a></li> </ul> <img id="placeholder" src="../images/5.jpg" alt="my image gallery" /> <p id="description">Choose an image.</p> <script type="text/javascript" src="../js/showPic.js"></script> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function showPic(whichpic){ //图片切换 var source = whichpic.getAttribute("href"); var placeholder = document.getElementById("placeholder"); placeholder.setAttribute("src",source); //文本切换 var text = whichpic.getAttribute("title"); var description = document.getElementById("description"); description.firstChild.nodeValue = text; } function countBodyChildren(){ var body_element = document.getElementsByTagName("body")[0]; //alert(body_element.childNodes.length); //子节点个数 //alert(body_element.nodeType); //节点类型 } window.onload = countBodyChildren();
5. 最佳实践
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
window.onload = prepareLinks; function prepareLinks(){ if(!document.getElementsByTagName) return false; //向后兼容性 var links = document.getElementsByTagName("a"); for(var i=0;i<links.length;i++){ if(links[i].getAttribute("class") == "popup"){ links[i].onclick = function(){ popUp(this.getAttribute("href")); return false; } } } } function popUp(winURL){ window.open(winURL,'popup','width=320,height=480'); }
6. 案例研究:图片库改进版
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Image Gallery</title> <link rel="stylesheet" href="../css/layout.css" media="screen" /> </head> <body> <h1>Snapshots</h1> <ul id="imagegallery"> <li> <a href="../images/1.jpg" title="A firework display"> <img src="../images/1.jpg" alt="Fireworks" /> </a> </li> <li> <a href="../images/2.jpg" title="A cup of black coffee"> <img src="../images/2.jpg" alt="Coffee" /> </a> </li> <li> <a href="../images/3.jpg" title="A red,red rose"> <img src="../images/3.jpg" alt="Rose" /> </a> </li> <li> <a href="../images/4.jpg" title="The famous clock"> <img src="../images/4.jpg" alt="Big Ben" /> </a> </li> </ul> <img id="placeholder" src="../images/5.jpg" alt="my image gallery" /> <p id="description">Choose an image.</p> <script type="text/javascript" src="../js/showPic.js"></script> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
body {font-family:"Helvetica","Arial",serif; color:#333; background-color:#ccc; margin:1em 10%;} h1 {color:#333; background-color:transparent;} a {color:#c60; background-color:transparent; font-weight:bold; text-decoration:none;} ul {padding:0;} li {float:left; padding:1em; list-style:none;} #imagegallery {list-style:none;} #imagegallery li {display:inline;} #imagegallery li a img {border:0; width:80px; height:80px;} img {display:block; clear:both;} #imagegallery {list-style:none;}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function showPic(whichpic){ if(!document.getElementById("placeholder")) return false; //图片切换 var source = whichpic.getAttribute("href"); var placeholder = document.getElementById("placeholder"); if(placeholder.nodeName != "IMG") return false; placeholder.setAttribute("src",source); //文本切换 if(document.getElementById("description")){ var text = whichpic.getAttribute("title") ? whichpic.getAttribute("title") : ""; var description = document.getElementById("description"); if(description.firstChild.nodeType == 3) { description.firstChild.nodeValue = text; } } return true; } function prepareGallery(){ if(!document.getElementsByTagName || !document.getElementById) return false; if(!document.getElementById("imagegallery")) return false; var gallery = document.getElementById("imagegallery"); var links = gallery.getElementsByTagName("a"); for(var i=0;i<links.length;i++){ links[i].onclick = function(){ return showPic(this) ? false : true; } } } function addLoadEvent(func){ var oldonload = window.onload; if(typeof window.onload != 'function'){ window.onload = func; } else { window.onload = function(){ oldonload(); func(); } } } addLoadEvent(prepareGallery);
7 动态创建标记
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function insertParamgraph(text){ var str="<p>"; str += text; str += "</p>"; document.write(str); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var testdiv = document.getElementById("testdiv"); testdiv.appendChild(param);//把这个p元素节点追加到文档中的一个元素节点
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var txt = document.createTextNode("Hello World"); //创建一个文本节点 para.appendChild(txt); //把这个文本节点追加到刚创建的那个p元素节点上
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var gallery = document.getElementById("imagegallery"); gallery.parentNode.insertBefore(placeholder, gallery);
7.3 图片改进效果
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Image Gallery</title> <link rel="stylesheet" href="../css/layout.css" media="screen" /> </head> <body> <h1>Snapshots</h1> <ul id="imagegallery"> <li> <a href="../images/1.jpg" title="A firework display"> <img src="../images/1.jpg" alt="Fireworks" /> </a> </li> <li> <a href="../images/2.jpg" title="A cup of black coffee"> <img src="../images/2.jpg" alt="Coffee" /> </a> </li> <li> <a href="../images/3.jpg" title="A red,red rose"> <img src="../images/3.jpg" alt="Rose" /> </a> </li> <li> <a href="../images/4.jpg" title="The famous clock"> <img src="../images/4.jpg" alt="Big Ben" /> </a> </li> </ul> <script type="text/javascript" src="../js/showPic.js"></script> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function showPic(whichpic){ if(!document.getElementById("placeholder")) return false; //图片切换 var source = whichpic.getAttribute("href"); var placeholder = document.getElementById("placeholder"); if(placeholder.nodeName != "IMG") return false; placeholder.setAttribute("src",source); //文本切换 if(document.getElementById("description")){ var text = whichpic.getAttribute("title") ? whichpic.getAttribute("title") : ""; var description = document.getElementById("description"); if(description.firstChild.nodeType == 3) { description.firstChild.nodeValue = text; } } return true; } function prepareGallery(){ if(!document.getElementsByTagName || !document.getElementById) return false; if(!document.getElementById("imagegallery")) return false; var gallery = document.getElementById("imagegallery"); var links = gallery.getElementsByTagName("a"); for(var i=0;i<links.length;i++){ links[i].onclick = function(){ return showPic(this) ? false : true; } } } function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if(parent.lastChild == targetElement) { parent.appendChild(newElement); } else { parent.insertBefore(newElement, targetElement.nextSibling); } } function preparePlaceholder(){ if(!document.createElement) return false; if(!document.createTextNode) return false; if(!document.getElementById) return false; if(!document.getElementById("imagegallery")) return false; var placeholder = document.createElement("img"); placeholder.setAttribute("id","placeholder"); placeholder.setAttribute("src","../images/5.jpg"); placeholder.setAttribute("alt","my image gallery"); var description = document.createElement("p"); description.setAttribute("id","description"); var desctext = document.createTextNode("Choose an image"); description.appendChild(desctext); var gallery = document.getElementById("imagegallery"); insertAfter(placeholder, gallery); insertAfter(description,placeholder); } function addLoadEvent(func){ var oldonload = window.onload; if(typeof window.onload != 'function'){ window.onload = func; } else { window.onload = function(){ oldonload(); func(); } } } addLoadEvent(preparePlaceholder); addLoadEvent(prepareGallery);
7.4 Ajax技术
DEOM之html代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Ajax</title> <link rel="stylesheet" href="../css/layout.css" media="screen" /> </head> <body> <div id="new"></div> <script type="text/javascript" src="../js/addLoadEvent.js"></script> <script type="text/javascript" src="../js/getHTTPObject.js"></script> <script type="text/javascript" src="../js/getNewContent.js"></script> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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(); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function getNewContent() { var request = getHTTPObject(); if(request) { request.open("GET", "../views/example.txt", true); //发起一个GET请求,请求的是example.txt的内容 request.onreadystatechange = function() { //响应处理函数 if(request.readyState == 4) { alert("Response Received"); var para = document.createElement("p"); var txt = document.createTextNode(request.responseText); para.appendChild(txt); document.getElementById("new").appendChild(para); } }; request.send(null); //发送请求 } else { //若浏览器不支持XMLHttpRequest对象 alert("Sorry, your browser doesn\'t support XMLHttpRequest"); } alert("Function Done"); } addLoadEvent(getNewContent);
8 充实文档内容
8.4 为文档创建缩略语列表的函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Ajax</title> <link rel="stylesheet" media="screen" href="../css/typegraphy.css" /> </head> <body> <h1>What is the document object model?</h1> <p> The <abbr title="World Wide Web Consortium">W3C</abbr> defines the <abbr title="Document Object Model">DOM</abbr> as: </p> <blockquote cite="http://www.w3c.org/DOM/"> <p> A platform- and language-neutral interface that will allow programs and scripts to dynamically access and update the content, structure and style of documents. </p> </blockquote> <p> It is an <abbr title="Application Programing Interface">API</abbr> that can be used to navigate <abbr title="HyperText Markup Language">HTML</abbr> and <abbr title="Extensible Markup Language">XML</abbr> documents. </p> <script src="../js/addLoadEvent.js"></script> <script src="../js/displayAbbreviations.js"></script> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function displayAbbreviations(){ //兼容性检测 if(!document.getElementsByTagName) return false; if(!document.createElement) return false; if(!document.createTextNode) return false; //取得所有缩略词 var abbreviations = document.getElementsByTagName("abbr"); if(abbreviations.length < 1) return false; //遍历缩略词 var defs = new Array(); for(var i=0;i<abbreviations.length;i++){ var current_abbr = abbreviations[i]; if(current_abbr.childNodes.length < 1) continue; var definition = current_abbr.getAttribute("title"); var key = current_abbr.lastChild.nodeValue; defs[key] = definition; } //创建定义列表 var dlist = document.createElement("dl"); for(key in defs){ var definition = defs[key]; //创建定义标题 var dtitle = document.createElement("dt"); var dtitle_text = document.createTextNode(key); dtitle.appendChild(dtitle_text); var ddesc = document.createElement("dd"); var ddesc_text = document.createTextNode(definition); ddesc.appendChild(ddesc_text); //把他们添加到定义列表 dlist.appendChild(dtitle); dlist.appendChild(ddesc); } if(dlist.childNodes.length < 1) return false; //创建标题 var header = document.createElement("h2"); var header_text = document.createTextNode("Abbreviations"); header.appendChild(header_text); //把标题添加到页面主题 document.body.appendChild(header); //把定义列表添加到页面主题 document.body.appendChild(dlist); } addLoadEvent(displayAbbreviations);
8.5 显示文献来源链接表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function displayCitations(){ var quotes = document.getElementsByTagName("blockquote"); for(var i=0;i<quotes.length;i++){ if(!quotes[i].getAttribute("cite")) { continue; } var url = quotes[i].getAttribute("cite"); var quoteChildren = quotes[i].getElementsByTagName("*"); if(quoteChildren.length < 1) continue; var elem = quoteChildren[quoteChildren.length-1]; var link = document.createElement("a"); var link_text = document.createTextNode("source"); links.appendChild(link_text); links.setAttribute("href",url); var superscript = document.createElement("sup"); superscript.appendChild(links); elem.appendChild(superscript); } }
8.6 显示“快捷键清单”
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function displayAccessKeys(){ if(!document.getElementsByTagName || !document.createElement || !document.createTextNode) return false; //取得文档中的所有链接 var links = document.getElementsByTagName("a"); //创建一个数组,保存访问键 var akeys = new Array(); for(var i=0;i<links.length;i++){ var current_link = links[i]; //如果没有accesskey属性,继续循环 if(!current_link.getAttribute("accesskey")) continue; //获取accesskey的值 var key = current_link.getAttribute("accesskey"); //获取文本链接 var text = current_link.lastChild.nodeValue; akeys[key] = text; } //创建列表 var list = document.createElement("ul"); //遍历访问键 for(key in akeys) { var text = akeys[key]; //创建放到列表项中的字符串 var str = key + ":" + text; //创建列表项 var item = document.createElement("li"); var item_text = document.createTextNode(str); item.appendChild(item_text); //把列表项添加到列表 list.appendChild(item); } //创建标题 var header = document.createElement("h3"); var header_text = document.createTextNode("Accesskeys"); header.appendChild(header_text); //把标题添加到页面主体 document.body.appendChild(header); //把列表添加到页面主体 document.body.appendChild(list); } addLoadEvent(displayAccessKeys);
9 CSS-DOM
文档的每个元素节点都有一个属性style。style属性包含着元素的样式,查询这个属性将返回一个对象而不是一个简单的字符串。样式都存放在这个style对象的属性里:element.style.property。不仅文档里的每个元素都是一个对象,每个元素都有一个style属性,它们也是一个对象。
当需要引用一个中间带减号的CSS属性时,DOM要求你用驼峰命名法。例如CSS属性font-family变为DOM属性fontFamily。且不管CSS样式属性的名字里有多少个连字符,DOM一律采用驼峰命名法表示它们。
style对象只包含在HTML代码里用style属性声明的样式。在外部样式表和文档的<head>部分里声明的样式不会进入style对象。然而,style对象的各个属性都是可读写的,不仅可以通过某个元素的style属性去获取样式,还可以通过它去更新样式。虽然不应该利用DOM去创建重要的内容,但可以利用DOM对文档的样式做一些小增强。
还可以用element.className = value来设置样式。
10 用javascript实现动画效果
JavaScript函数setTimeout能够让某个函数在经过一段预定的时间之后才开始执行。该函数带有两个参数:第一个参数通常是一个字符串,其内容是将要执行的那个函数的名字;第二个参数是一个数值,它以毫秒为单位设定了需要经过多长时间后才开始执行第一个参数所给出的参数:setTimeout("function", interval); 在绝大多数时候,把这个函数调用赋值给一个变量将是个好主意:variable = setTimeout("function", interval);
如果想取消某个正在排队等待执行的函数,就必须事先像上面这样把setTimeout函数的返回值赋值给一个变量。可以使用clearTimeout函数来取消”等待执行“队列里的某个函数。这个函数需要一个参数---保存着某个setTimeout函数调用返回值的变量。
JavaScript允许我们为元素创建属性:element.property = value; 这很像是在创建一个变量,但区别是这个变量专属于某个特定的元素。
HTML代码:
<p id="message">Hello World!</p>
JS代码:
function moveElement(elementID, final_x, final_y, interval) { if(!document.getElementsByTagName || !document.createElement || !document.createTextNode) return false; if(!document.getElementById(elementID)) return false; var elem = document.getElementById(elementID); if(elem.movement){ clearTimeout(elem.movement); } if(!elem.style.left) elem.style.left = "0px"; if(!elem.style.top) elem.style.top = "0px"; var xpos = parseInt(elem.style.left); var ypos = parseInt(elem.style.top); var dist = 0; if(xpos == final_x && ypos == final_y) { return true; } if(xpos < final_x){ dist = Math.ceil((final_x - xpos)/10); xpos = xpos + dist; } if(xpos > final_x) { dist = Math.ceil((xpos - final_x)/10); xpos = xpos - dist; } if(ypos < final_y){ dist = Math.ceil((final_y - ypos)/10); ypos = ypos + dist; } if(ypos > final_y){ dist = Math.ceil((ypos - final_y)/10); ypos = ypos - dist; } elem.style.left = xpos + "px"; elem.style.top = ypos + "px"; var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")"; elem.movement = setTimeout(repeat, interval); }
12 一些整理
12.1 form对象
文档中的每个表单元素都是一个form对象,每个form对象都有一个element.length属性。这个属性返回表番中的包含的表单元素的个数:form.elements.length。这个返回值与childNodes.length不一样,后者返回的是元素中包含的所有节点的个数。而form对象的elements.length属性只关心那些表单的元素,如input、textarea等等。
相应的,表单中的所有字段都保存在form对象的elements属性中。也就是说,form.elements是一个包含所有表单元素的数组。同样,这个属性与childNodes属性也不一样,后者也是一个数组。childNodes数组返回的是所有节点,而elements数组则只返回input、select、textarea以及其他表单字段。
elements数组中的每个表单元素都有自己的一组属性。比如:value属性中保存的就是表单元素的当前值:element.value,等价于element.getAttribute("value");