第七章 动态创建标记
在web浏览器中往文档添加标记,先回顾下过去使用的技术:
<body> <script type="text/javascript"> document.write("<p>This is inserted.</p>"); </script> </body>
document.write:缺点就是违背了"行为与表现分离的原则",即使把这句语句挪到外部,还是需要在<body>里边添加<script>标签才可以调用
-->script标签后面的<p>很容易被误任务<p>标签,在script标签后面有p标签是违法的
-->MIME类型的application/xhtml+xml和document.write不兼容
innerHTML可以读取,也可以写入,但是他无法区分"插入一段元素"和"替换一段元素",一旦使用了,原本的内容全部被取代
<body>
<div id="testdiv">
</div>
</body>
var testdiv = document.getElementById("testdiv");
testdiv.innerHTML="<p>I inserted <em>this</em> content.</p>"; //将会在网站上显示出I inserted this content.
-->类似document.write,也是HTML专有属性,MIME类型的application/xhtml+xml和document.write不兼容
createElement:创建元素节点,只创建会出现一个文档碎片(document fragment),它是游荡在JavaScript世界里的一个孤儿。但是它已经有nodeType和nodeName属性 document.createElement("p");
appendChild:将新建节点插入文档节点最简单的方法就是让他成为文档某个节点的子节点。
createTextNode:创建文本节点
insertBefore : 在已有元素前插入一个新元素
DOM没有提供insertAfter,不过可以编写一个
function insetAfter(newElement,targetElement) { var parent = targetElement.parentNode; if(parent.lastChild == targetElement) //目标元素是不是parent的最后一个元素,是就在后面追加 { parent.appendChild(newElement); } else //如果不是,就在newElement插在目标元素之后,目标元素的兄弟元素之前 { parent.insertBefore(newElement,targetElement.nextSibling); //下一个兄弟元素就是 : targetElement.nextSibling } }
本章JS部分代码:
function preparePlaceholder(){ var body_para = document.getElementById("imagegallery"); var placeholder = document.createElement("img"); placeholder.setAttribute("id","placeholder"); placeholder.setAttribute("src","images/placeholder.gif"); placeholder.setAttribute("alt","my image gallery"); var p_elem = document.createElement("p"); p_elem.setAttribute("id","description"); var txt = document.createTextNode("Choose an image"); p_elem.appendChild(txt); /* document.body.appendChild(placeholder); document.body.appendChild(p_elem); */ /* body_para.parentNode.insertBefore(placeholder,body_para); body_para.parentNode.insertBefore(p_elem,body_para); */ insetAfter(placeholder,body_para); insetAfter(p_elem,placeholder); }
第八章 充实文档内容
function displayAbbreviation() { if (!document.getElementsByTagName || !document.createElement || !document.createTextNode) return false; var des = new Array(); var abbrevitation = document.getElementsByTagName("abbr"); //遍历所有的abbr for(var i = 0; i < abbrevitation.length; i++) { /*IE6之前的浏览器不支持abbr,在统计abbr的子节点时总返回错误的值0(由于当年的浏览器战争)*/ if(abbrevitation[i].childNodes.length < 1) continue; var definition = abbrevitation[i].getAttribute("title"); //将所有的abbr的title取出 是字符串 var keys = abbrevitation[i].lastChild.nodeValue; //将所有的abbr所包含的文本节点的内容取出 des[keys] = definition; //定义关联数组 循环可以用 for(keys in des) } var dlist = document.createElement("dl"); for(keys in des) { var definition = des[keys]; var dtitle = document.createElement("dt"); var dt_txt = document.createTextNode(keys); dtitle.appendChild(dt_txt); var ddesc = document.createElement("dd"); var dd_txt = document.createTextNode(definition); ddesc.appendChild(dd_txt); dlist.appendChild(dtitle); dlist.appendChild(ddesc); } if(dlist.childNodes.length < 1) return false; //创建一个二级标题 var h2_header = document.createElement("h2"); var h2_header_txt = document.createTextNode("Abbreviations"); h2_header.appendChild(h2_header_txt); document.body.appendChild(h2_header); document.body.appendChild(dlist); }
function displayCitations() { if (!document.getElementsByTagName || !document.createElement || !document.createTextNode) return false; var quotes = document.getElementsByTagName("blockquote"); for(var i = 0; i < quotes.length; i++) { //如果没有cite属性,继续 if(!quotes[i].getAttribute("cite")) continue; var url = quotes[i].getAttribute("cite"); console.log(url); //取得引用中所有的元素节点,在最后追加新添的元素 var quotes_child = quotes[i].getElementsByTagName("*"); if(quotes_child.length < 1) continue; //取得引用中最后一个元素节点,为何不直接用lastChild属性
/*
<blockquote cite="http://www.w3.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和/blcokquote之间有一个回车键,这个回车键可能会被认为最后一个节点,是一个文本节点.当然我们也可以检查nodeType的值
*/ var last_elem = quotes_child[quotes_child.length - 1]; var link = document.createElement("a"); link.setAttribute("href",url); var link_txt = document.createTextNode("source"); link.appendChild(link_txt); //sup元素,在浏览器中呈现出上标的效果!!! var superscript = document.createElement("sup"); superscript.appendChild(link); last_elem.appendChild(superscript); } }
第九章 CSS-DOM
我们在浏览器看到的网页其实有三部分构成:
结构层(structural layer) 有XHTML或者HTML等标记语言创建
表示层(presentation layer) 由CSS负责创建
行为层(behavior layer) 负责内容应该如何响应事件这一动作,这主要室友javascript和DOM负责。
不过这三种技术存在重叠。CSS利用伪类进入DOM领地,DOM可以使用DOM样式给元素设定样式。在外部声明的CSS样式不会进入DOM style,在head部分声明的也一样。
<thead>标签定义表格的表头 <tbody>对表格中主体内容进行分组 <tfoot>对表格中的表注(页脚)进行分组 <thead>要与<tbody>或者<tfoot>搭配使用
function highlightRows() { var tables = document.getElementsByTagName("table"); for(var i = 0; i < tables.length; i++) { var odd = false; var rows = tables[i].getElementsByTagName("tr"); for(var j = 0; j < rows.length; j++) { if(odd == true) { rows[j].style.backgroundColor = "#ffc"; odd = false; } else odd = true; /*鼠标移动到行时粗体显示字体 CSS的tr:hover也可以做到*/ rows[j].onmouseover = function () { this.style.fontWeight = "bold"; } rows[j].onmouseout = function () { this.style.fontWeight = "normal"; } } } }
className属性:上面这段函数,让行为层去干表示层的活儿,不是明智的选择。可以在js里边增加class属性比如class = "intro" 具体的然后在css中设定.intro{...}
function addClass(element,value){ if(!element.className) //通过classname属性设定元素的class属性是,会替换而不是追加 所以我们需要判断下 这个元素原先有没有class属性 没有直接替换 有就需要追加 element.className = value; else { newClassName = element.className; newClassName += " "; newClassName += value; element.className = newClassName; } }
本章主要是JS入侵CSS的领地,这么做主要是由于1:CSS无法让我们找到想要处理的目标元素 2:CSS寻找目标的方法还未得到广泛支持
另外JS能够定时重复执行一组操作,不断地改变样式,可以达到CSS做不到的效果。