DOM的發展,與WEB標準化的大趨勢相關甚密。只有基於正確的語意邏輯,DOM才能正確地發揮其功用。如今,正確的語意結構、表現與內容分離等要求,都已成為網頁設計的基本要求。因此,在網頁前端開發中,DOM的存在,無疑是為表現層、行為層甚至內容層面的連結提供了一個絕佳的API,成為熱門的Ajax應用中不可或缺的組成部分。
一、平穩退化
1、概念
早期,在未使用JavaScript之前,網頁中的內容可以正常顯示出來,使用者可以透過週邊裝置(如滑鼠)操控瀏覽到相關內容,而這種瀏覽體驗對使用者而言可能並不理想。
根據這個需求,內容的提供者就有了合理化目標——那就是在不影響內容展示的前提下,使用JavaScript來改善用戶體驗,提高用戶黏性。
在這個標目中,有個非常明顯的條件,就是不能影響內容的正常展示,換言之,即使用戶的瀏覽器不支援JavaScript,也能保證用戶可以正常瀏覽。
2、方法
①將JavaScript與HTML分離
這是首先應該想到的,讓兩者分離,HTML就像回到早期未使用JavaScript之前的狀態,乾爽如初啊。
譬如將element.onClick之類的事件處理函數寫進JavaScript中,與某函數進行綁定。
②對JavaScript中的方法進行偵測
之前提到的一些方法,如getElementById之類,都需要去判定該方法是否支援。
<script> if(! document.getElementById) return false; </script>
透過if語句這種方式來檢測是否支持該方法,如果支持,可以繼續,不支持,直接返回false,這樣就沒必要耽誤功夫了,也起到了性能優化的作用。
二、綁定onload事件
1、綁定緣由
有些函數需要在頁面載入完全之後才能有效執行,我們需要將函數綁定到window.onload這個事件上。
<!doctype html> <html> <head> <meta charset="utf-8"> <title>筱雨生 - 博客园</title> <script> function tagAttribute(){ var ali = document.getElementsByTagName('li'); for(var i = 0; i < ali.length; i++){ if(ali[i].firstChild.nodeType == 3){ alert(ali[i].childNodes[0].nodeValue); } } } window.onload = tagAttribute; </script> </head> <body> <h1>筱雨生</h1> <p>時光飛逝,莫讓網絡蹉跎了歲月</p> <div id="myBlog"> <ul> <li title="JavaScript">JavaScript</li> <li title="HTML">HTML</li> <li title="CSS">CSS</li> <li title="我的随笔">我的随笔</li> <li></li> </ul> </div> </body> </html>
在上面這個實例中,如果不綁定window.onload,執行函數tagAttribute將會毫無意義。
還要注意一點,綁定的是函數,而不是這個函數的值,所以後面不帶圓括號。
2、綁定方法
如果你只需要綁定一個函數,那麼上面的方法完全可以輕鬆實現你的目的。
window.onload = myFunction;
如果是多個,也許你會去一個個的綁定,可是,這樣做的結果是只有最後一個函數才會被有效執行,關於這一點其實很好理解。
我們的目的是,不管頁面中載入完畢時執行多少個函數,這些函數都可以有效執行,也就是說,這些函數都被成功綁定window.onload事件。
<!doctype html> <html> <head> <meta charset="utf-8"> <title>筱雨生 - 博客园</title> <script> function addOnLoadEvent(func){ var oldonload = window.onload; // 把现有的window.onload事件处理函数的值存储到变量oldonload if(typeof window.onload != 'function'){ // 如果这个处理函数上还没有绑定任何函数 window.onload = func; // 将这个函数绑定到window.onload事件 }else{ window.onload = function(){ // 如果这个处理函数已经绑定了函数,就把这个函数追加到指令的末尾 oldonload(); func(); } } } //自定义函数 tagAttribute //功能:获取li标签中的title值 function tagAttribute(){ var ali = document.getElementsByTagName('li'); for(var i = 0; i < ali.length; i++){ if(ali[i].childNodes[0].nodeType == 3){ alert(ali[i].childNodes[0].nodeValue); } } } addOnLoadEvent(tagAttribute); // 为tagAttribute函数绑定到window.onload事件 </script> </head> <body> <h1>筱雨生</h1> <p>時光飛逝,莫讓網絡蹉跎了歲月</p> <div id="myBlog"> <ul> <li title="JavaScript">JavaScript</li> <li title="HTML">HTML</li> <li title="CSS">CSS</li> <li title="我的随笔">我的随笔</li> <li></li> </ul> </div> </body> </html>
javascript学习笔记 Dom知识点总结
JavaScript的window对象对应着浏览器窗口本身,因此这个对象的属性和方法统称为BOM(浏览器对象模型),如window.open(),window.location等。
JavaScript的document对象是指文档对象模型,主要是处理网页内容。DOM(Document Object Model)即文档对象模型,是针对 HTML 和 XML 文档的 API 。字母D指document(文档),字母O指object(对象),字母指Model(模型)。DOM 描绘了一个层次化的节点树。节点表示一个连接点,文档是由节点构成的集合,DOM的节点主要分为三类:元素节点、文本节点(不是文本内容)、属性节点。
获取节点的名称和类型
1.nodeName属性用来获取节点的名称,文本节点返回#text,元素节点返回标签名称(此时等价于tagName)。语法:目标节点.nodeName
2.nodeType属性用来获取节点的类型,元素节点:1,属性节点:2,文本节点:3。语法:目标节点.nodeType
3.nodeValue属性用来获取和设置节点的值。元素节点返回 null 。语法:目标节点.nodeValue
获取元素节点的方式
1. document.getElementById
通过ID查找,返回唯一元素节点
2. document.getElementsByName
通过name属性查找,返回元素节点数组
3. document.getElementsByTagName
通过标签名称查找,返回元素节点数组
以下三种方法属于HTML5 DOM,并非所有浏览器支持(如某些低版本IE就不支持),属于高级方法
4. document.getElementsByClassName
通过class属性的类名查找,返回元素节点数组
5. document.querySelector
通过selector条件获取元素节点,只返回符合条件的第一个元素节点
6. document.querySelectorAll
通过selector条件获取元素节点,返回所有符合条件的元素节点数组,多条件使用逗号分隔,表示要查找的元素必须符合所有逗号分隔的条件,如果一个元素只符合逗号分隔的条件中的一个,则不会被返回
小结: getElementById和querySelector只返回一个元素节点,而getElementsByName、getElementsByTagName、getElementsByClassName、querySelectorAll返回的是元素节点数组
节点指针
1.childNodes属性用来获取元素节点的子节点,返回节点数组。语法:父节点.childNodes;
2.children属性可以用来获取忽略了空白节点的有效节点(在某些浏览器上,空白符或换行符也是一个文本节点)。语法:父节点.children;
3.firstChild属性可以用来获取元素的第一个子节点,等价于 childNodes[0]。语法:父节点.firstChild;
3.lastChild属性可以用来获取元素的最后一个子节点,等价于 childNodes[childNodes.length-1]。语法:父节点.lastChild;
4.previousSibling属性用来获取目标节点的前一个兄弟节点。语法:目标节点.previousSibling;
5.nextSibling属性用来获取目标节点的后一个兄弟节点。语法:目标节点.nextSibling;
6.parentNode属性用来获取已知节点的父节点。语法:子节点.parentNode;
7.ownerDocument属性用来当前节点所在文档的根节点,等价于document。语法:目标节点.ownerDocument;
节点的操作
1.createElement方法用来创建元素节点。语法:document.createElement('元素标签名称');
2.createAttribute方法用来创建属性节点。语法:document.createAttribute('属性名称');
3.createTextNode方法用来创建文本节点。语法:document.createTextNode('文本内容');
4.appendChild方法用来在目标节点的子节点的末尾添加一个子节点(可以是createElement创建的元素节点,也可以是createTextNode创建的文本节点)。语法:parent.appendChild(要插入的节点);
5.insertBefore方法用来在目标元素的前面插入一个新元素节点,此时的指针在目标元素的父级上。语法:parent.insertBefore(newElement,targetElement);
6.DOM中没有insertAfter这个方法,但是可以通过以下方法来模拟insertAfter;
/* * newElement : 要插入的新元素 * targetElement : 目标元素 */ function insertAfter(newElement,targetElement){ var parent = targetElement.parentNode; if(parent.lastChild == targetElement){ /* 如果目标元素是parent的最后一个子元素,则把新元素追加到parent元素上, 也就是在parent的子元素的末尾位置添加新元素 */ parent.appendChild(newElement); }else{ /* 否则,就把新元素添加到目标元素和目标元素的下一个兄弟元素之间 */ parent.insertBefore(newElement,targetElement.nextSibling); } }
7.replaceChild方法用来替换一个元素节点,此时的指针在目标元素的父级上。语法:parent.replaceChild(replaceElement,targetElement);
8.cloneChild方法用来克隆一个元素节点,传递一个布尔参数,参数为true时表示复制当前节点及其所有子节点,参数为false时表示支付至当前节点。语法:目标元素.cloneChild(true|false);
9.removeChild方法用来删除一个指定节点。语法:removeChild(要删除的节点);
10.getAttribute方法用来获取一个属性的值。语法:目标元素.getAttribute(元素属性名称);
11.setAttribute方法用来设置一个属性的值,没有该属性则创建。语法:目标元素.setAttribute(元素属性名称,属性值);
12.removeAttribute方法用来删除一个属性节点。语法:目标元素.removeAttribute(要删除的属性名称);
DOM操作内容
1.innerHTML属性用来获取和设置HTML内容。语法:元素节点.innerHTML 或者 元素节点.innerHTML = 'HTML字符串';
2.innerText|textContent属性用来获取和设置文本内容。fireFox使用textContent来获取和设置(注意兼容性)。语法:元素节点.innerText 或者 元素节点.innerText = 'HTML字符串';
DOM操作样式
1.style属性用来获取和设置元素的行内样式。语法:element.style;style属性只能获取和设置行内样式,对于如font-size这种样式属性,应该去掉 - 并且将 - 后面的第一个字母大写,驼峰法来获取和设置 如:element.style.fontSize , element.style.backgroundColor
2.getComputedStyle全局方法用来获取计算后的样式,第一个参数是元素节点,第二个参数是类型,如:hover,:active等伪类,默认情况下传 null ,某些IE版本使用currentStyle属性来获取 box.currentStyle。语法:window.getComputedStyle(元素,类型)
3.className属性用来获取和设置元素的样式名称。语法:element.className
4.自定义的 addClass() | hasClass() | removeClass() 方法
//元素是否含有某样式 function hasClass(element,className){ return !!element.className.match(new RegExp('(\\s|^)'+className+'(\\s|$)')); } //向元素添加新样式 function addClass(element,className){ if(hasClass(element,className) == false){ element.className += ' '+className; } } //移除元素的指定样式 function removeClass(element,className){ var currentClass = element.className; if(hasClass(element,className)){ currentClass = currentClass.replace(new RegExp('(\\s|^)'+className+'(\\s|$)'),' '); //去除空格 currentClass = currentClass.replace(/(^\s*)|(\s*$)/g,''); element.className = currentClass; } }
DOM操作位置和大小
1.clientWidth属性用来获取元素的实际宽度,该值受滚动条和内边距影响,外边距和border不会影响。语法:
element.clientWidth;
2.clientHeight属性用来获取元素的实际高度,该值受滚动条和内边距影响,外边距和border不会影响。语法:
element.clientHeight;
3.offsetWidth属性用来获取元素的实际宽度,该值受边框和内边距影响,外边距和滚动条不会影响。语法:
element.offsetWidth;
4.offsetHeight属性用来获取元素的实际高度,该值受边框和内边距影响,外边距和滚动条不会影响。语法:
element.offsetHeight;
5.offsetTop和offsetLeft属性用来获取元素相对于父级的位置。该值受外边距影响。语法:element.offsetTop ||
element.offsetLeft;
6.scrollTop和scrollLeft属性用来获取滚动条被隐藏的区域大小,也可设置定位到该区域(比如返回顶部)。语法:
element.scrollTop || element.scrollLeft || element.scrollTop = 0;
常用到的简洁快速的document属性和方法
document.title 用来获取文档标题
document.domain 用来获取当前域名
document.URL 用来获取当前url路径
document.forms 获取表单集合
document.images 获取图片集合
document.body 获取body元素节点
document.compatMode 识别文档模式