目录javascript
动态脚本css
使用<script>元素能够向页面中插入JavaScript代码的两种方式:经过src特性包含外部文件;使用这个元素自己来包含代码
动态脚本指的是页面加载时不存在,在未来某一刻须要经过修改DOM动态添加脚本。跟操做HTML元素同样,建立动态脚本也有两种方式:插入外部文件和直接插入JS代码。
(1)插入外部文件java
//动态建立<script type="text/javascript" src="test.js"></script> var script = document.createElement("script"); script.type = "text/javascript"; script.src= "test.js"; document.body.appendChild(script);//这句放哪均可以
在执行最后一行代码把<script>元素添加到页面中以前,是不会下载外部文件的。整个过程能够用函数封装:chrome
function loadScript(url){ var script = document.createElement('script'); script.type= "text/javascript"; script.src = url; document.body.appendChild(script); } loadScript("test.js");
加载完成后就能够在页面中其余地方使用这个脚本了。怎么知道脚本何时加载(从服务器请求下载过来了)完成了呢,有一些事件能够探知,但要取决于浏览器,支持的浏览器少的可怜。
<script>(在<=IE10和Opera)和<link>(仅<=IE10)元素会触发readystatechange事件(继承自HTMLElement.prototype.onreadystatechange),能够用来肯定外部JavaScript和Css文件是否已经加载完成。当把动态建立的元素添加到页面中浏览器开始下载外部资源,当元素的readyState属性不管等于“loaded”仍是“complete”都表示资源已经可用。下面给出一段加载外部JavaScript文件代码(限在<=IE10且支持addEventListener中运行)。浏览器
window.onload = function(e){ var script = document.createElement('script'); script.addEventListener('readystatechange', function(e){ if(e.target.readyState == 'loaded' || e.target.readyState == 'complete'){ e.target.removeEventListener('readystatechange', arguments.callee, false); alert('Script loaded'); } }); script.src = 'example.js'; document.body.appendChild(script); }
此时获取<script src="example.js">的readyState的值为“loaded”,与此同时就能够执行已经加载完的外部文件‘example.js’中的函数了。
(2)行内直接插入JS代码(在除了<=IE8以外浏览器可运行)服务器
var script = document.createElement('script'); script.type = 'text/javascript'; script.appendChild(document.createTextNode("function sayHi(){alert('hi')}")); document.body.appendChild(script);
由于<=IE8将<script>视为一个特殊的元素,不容许DOM访问其子节点,不过可使用<script>元素text属性(继承自HTMLScriptElement.prototype)来指定JavaScript代码。app
//针对<=IE8和Safari3及以后版本 var script = document.createElement('script'); script.type = 'text/javascript'; script.text = "function sayHi(){alert('hi')}"; document.body.appendChild(script);
兼容全部浏览器的代码异步
function loadScriptString(code){ var script = document.createElement('script'); script.type = "text/javascript"; try{ //除过<=IE8和Safari3及以后版本 script.appendChild(document.createTextNode(code)); }catch(e){ script.text = code; } document.body.appendChild(script); }
实际上这样执行代码与在全局做用域中把相同的字符串传递给eval()是同样的。
函数
动态样式测试
可以把CSS样式包含到HTML页面中的元素有<link>和<style>
(1).动态样式是指在页面刚加载时不存在的样式,动态样式是在页面加载完后动态添加到页面中的。
function loadStyles(url){ var link = document.createElement("link"); link.rel = "stylesheet"; link.type = "text/css"; link.href = url; var head = document.getElementsByTagName('head')[0]; head.appendChild(link); }
加载外部样式文件的过程是异步的,即加载样式与执行JavaScript代码的过程没有固定次序。在<=IE10且支持addEventListener的IE中能够利用几种事件来检测样式是否加载完成
window.onload = function(e){ var link = document.createElement('link'); link.type = "text/css"; link.rel = "stylesheet"; link.addEventListener('readystatechange', function(e){ if(e.target.readyState == 'loaded' || e.target.readyState == 'complete'){ e.target.removeEventListener('readystatechange', arguments.callee, false); alert('css loaded'); } }); link.href ="example.css"; document.getElementsByTagName('head')[0].appendChild(link); }
此时获取<link href="example.css">的readyState的值为“complete”。
(2).使用<style>元素来包含嵌入式CSS
var style = document.createElement('style'); style.type = "text/css"; style.appendChild(document.createTextNode("body{background-color: red}")); var head = document.getElementsByTagName('head')[0]; head.appendChild(style);
一样<=IE8将<style>视为一个特殊的,与<script>相似的节点不容许访问其子节点。解决这个问题就是访问元素的styleSheet属性(继承自HTMLStyleElement.prototype),注意这个属性只在<=IE10有,其余浏览器(chrome和FF)经测试尚未,这个属性指向一个CSSStyleSheet类型的一个实例。这个实例属性又继承了CSSStyleSheet.prototype的cssText属性,该属性值能够接受CSS代码。下图测试结果为IE10仿真。
兼容全部浏览器代码
function loadStyleString(css){ var style = document.createElement('style'); style.type = "text/css"; try{ style.appendChild(document.createTextNode(css)); }catch(e){ style.styleSheet.cssText = css; } var head = document.getElementsByTagName("head")[0]; head.appendChild(style); }
注意经cssText设置以后,再经过style.styleSheet.cssText访问该值时候返回的是大写字符串,如图
操做表格
为方便构建表格,HTML DOM还为<table>,<tbody>,<tr>元素添加了些属性和方法。先来看看它们都有啥方法和属性。
(1).table.__proto__->HTMLTableElement.prototype->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype->Object.prototype
(2).tbody.__proto__->HTMLTableSectionElement.prototype->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype->Object.prototype
(3).tr.__proto__->HTMLTableRowElement.prototype->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype->Object.prototype
//建立table var table = document.createElement('table'); table.border = 1; table.width = "100%"; //建立tbody var tbody = document.createElement("tbody"); table.appendChild(tbody); //建立第一行 tbody.insertRow(0); tbody.rows[0].insertCell(0); tbody.rows[0].cells[0].appendChild(document.createTextNode("cell 1,1")); tbody.rows[0].insertCell(1); tbody.rows[0].cells[1].appendChild(document.createTextNode("cell 1,2")); //建立第二行 tbody.insertRow(1); tbody.rows[1].insertCell(0); tbody.rows[1].cells[0].appendChild(document.createTextNode("cell 2,1")); tbody.rows[1].insertCell(1); tbody.rows[1].cells[1].appendChild(document.createTextNode("cell 2,2")); //表格添加到文档中 document.body.appendChild(table);
使用NodeList
NodeList NamedNodeMap HTMLCollection 这三个集合都是动态的,除了有个例。
NodeList :getElementsByName,childNodes,querySelectorAll(静态集合)等返回的都是NodeList实例
HTMLCollection:getElementsByTagName,getElementsByClassName,getElementsByTagNameNS,document.forms,document.children等返回的都是HTMLCollection实例
NamedNodeMap:表示属性节点对象的集合,ele.attributes返回NamedNodeMap实例
访问DOM文档时实时运行的查询,因此下面代码会致使无限循环。
var divs = document.getElementsByTagName('div'),i,div; for(i = 0;i< divs.length; i++){ div = document.createElement('div'); document.body.appendChild(div); }
浏览器不会将建立的全部集合都保存在一个列表中,而是在下次访问集合时再更新集合,i和divs.length每次都会同时递增,结果它们的值永远不会相等。正确写法以下:
var divs = document.getElementsByTagName('div'),i,len,div; for(i = 0,len = divs.length; i<len;i++){ div = document.createElement('div'); document.body.appendChild(div); }
参考
《JavaScript高级程序设计》