<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Page Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="main.css" /> <script src="main.js"></script> </head> <body> <!-- <div>123</div> <a>234</a> <div>345</div> --> <div class="box" id="box"> 我是文本节点 <!-- 我是注释 --> <h1>head</h1> <a href="">link</a> <p>paragraph</p> </div> <script> // DOM -> Document Object Model 文档对象模型 // DOM 对象-> 宿主对象 // 3种对象: // 1. 本地对象:Native Object // Object Array function String Number Boolean // Error EvalError SyntaxError RangeError ReferenceError TypeError URIError // Date RegExp // 2. 内置对象 Built-in Object // global Match // ECMA: isNAN() parseInt() Number decodeURI encodeURI Infinity NaN undefined // 本地对象和内置对象都是ES的内部对象 // 3. 宿主对象 // 执行JS脚本的环境提供的对, 浏览器对象, 可能会有兼容性问题 // 浏览器对象window(BOM)和document(DOM) -> w3c // DOM: 通过浏览器提供的这一套方法表示或者操作html和XML 不可以操作css,只能操作dom的style属性 // querySelector / querySelectorAll HTML5 新引入的web API,IE7都支持 // querySelector 只选择第一个 通过css选择器进行选择 // querySelectorAll 选择所有的元素,选择出来的一定是类数组 // 缺点:性能不好, 不实时 // var divs = document.getElementsByTagName('div'); // console.log(divs); // divs[0].remove(); // console.log(divs); // var queryDivs = document.querySelectorAll('div'); // console.log(queryDivs); // queryDivs[0].remove(); // console.log(queryDivs); // 不会更新,还是输出三个 // 遍历节点树 // 节点包含元素 -〉元素节点 = DOM元素 // parentNode // var a = document.getElementsByTagName('a')[0]; // console.log(a);
// a.parentNode.parentNode.parentNode.parentNode = null
// 层级关系: body -> html -> document -> null // childNode: // 1. 元素节点 = 1 // 2. 属性节点 = 2 // 3. 文本节点 = 3 两个元素之间的换行内容是文本节点 // 4. 注释节点 = 8 // 5. document = 9 // 6. DocumentFragment = 11 // firstChild lastChild // nextSibling previousSibling -> 如果有文本节点, 会把文本节点输出来(一般不使用) // 以上IE5都支持 // 遍历元素节点树 // parentElement IE9及以下不支持 // children IE7及以下不支持 // childElementCount = children.length IE9及以下不支持 // firstElementChild lastElementChild IE9及以下不支持 // nextElementSiblig previousSibling // nodeName 只读 // document.nodeName //#document // 元素节点.nodeName // 标签名大写 DIV // 文本节点.nodeName // #text // 注释节点.nodeName // #comment // nodeValue 可写 属性节点 文本节点 注释节点 有nodeValue, 元素节点没有nodeValue // div.getAttributeNode('id').nodeValue // 获取属性节点,以及nodeValue // div.getAttributeNode('id').value // nodeType 只读 // 1. 元素节点 = 1 // 2. 属性节点 = 2 // 3. 文本节点 = 3 两个元素之间的换行内容是文本节点,换行也是文本节点 // 4. 注释节点 = 8 // 5. document = 9 // 6. DocumentFragment = 11 // childNode -> children // 性能优化,在循环中少用 带点的访问 // function elemChildren(node){ // var arr = [], // children= node.childNodes; // for(var i = 0; i < children.length; i++) { // var childItem = children[i]; // if(childItem.nodeType === 1) { // arr.push(childItem); // } // } // return arr; // } // console.log(elemChildren(div)) // // 类数组 // var arr = [1, 2, 3]; // var obj = { // '0': 1, // '1': 2, // '2': 3, // 'length': 3, // 必须要有length 属性 // 'push': Array.prototype.push, // 'splice': Array.prototype.splice // 对象的{}会变成[] // } // obj.push(4); // 寻找子元素的方法 // function elemChildren(node) { // var temp = { // 'length': 0, // 'push': Array.prototype.push, // 'splice': Array.prototype.splice // }, // children = node.childNodes; // for (var i = 0; i < children.length; i++) { // var childItem = children[i]; // if (childItem.nodeType === 1) { // // temp[temp['length']] = childItem; // // temp['length']++; // temp.push(childItem); // } // } // return temp; // } // div = document.getElementsByClassName("box")[0]; // console.log(elemChildren(div)); // hasChildNodes // doucument 继承 HTMLDocument 继承 Document // document.__proto__ = HTMLDocument.prototype; // HTMLDocument.__proto__ = Document.prototype; // HTMLDocument和XMLDocument继承于Document // Text/Comment 继承 CharacterData // HTMLDivElement/ HTMLParagraphElement 继承 HTMLElement 继承 Element // Document/ CharacterData/ Element 继承于 Node 继承于 EventTarget 继承于 object // DOM操作深入 // 1. getElementById(); 只在 Document.prototype上,CharacterData和Element没有 // 2. getElementsByName // // 在 Document.prototype上 // // Element.prototype上没有 // 3. getElementsByClassName/getElementsByClassName querySelector/ querySelectorAll // Document.prototype和Element.prototype上面都有 // HTMLDocument -> body head documentElement(选择元素) // document.createElement // 创建元素, 存在内存中 // document.createComment // 创建注释节点 // docuemnt.createTextNode // 创建文本节点 // 创建出来的节点会保存在内存中,通过appendChild来增加子节点 // appendChild // 1. 在Node.prototype上 // 2. 增加的元素,总是放在父级元素的最下方 // 3. 剪切节点 // appendChild内部必须是DOM元素或者节点,不是字符串 // var a = document.getElementsByTagName('a')[0]; // var div = document.createElement('div'); // div.innerHTML = '<p>I am paragraph</p>'; // document.body.appendChild(div); // div.appendChild(a); // a被从box div中剪切到创建的div中 // c.insertBefore(a, b); //在父级节点c下的子节点b之前插入a节点 // removeChild 父节点.removeChild(子节点) 并没有删除元素,只是删除了节,元素还存在于内存中 // 元素.remove() 自己删除自己,从内存中删除 // innerHTML innerText // 二者都存在于HTMLElement.prototype // innerHTML还存在于Element.prototype中 // innerText旧版本的火狐不支持 // parent.replaceChild(new, origin) 替换节点 // var div = document.getElementsByTagName('div')[0]; // element.setAttribute(name, value); // div.setAttribute('id', 'box'); // var attr = div.getAttribute('class'); // HTML5中元素增加了data-*属性,可以通过标签下的dataset获取data-*对象,但是兼容性不好 // document.createDocumentFragment() 创建文档片段(碎片),创建出来的节点,不存在在DOM中 </script> </body> </html>