Node.nodeType == 1 元素节点
Node.nodeType == 2 属性节点
Node.nodeType == 3 文本节点

<head>
    <meta charset="UTF-8">
    <title></title>
</head>

    var h = document.getElementsByTagName('head')[0]
 //   h.nodeType == 1 && console.log('this is an elem')
    h.nodeType == 1 && console.log(h.nodeName) //HEAD

//每个节点都有一个childNodes 属性,其中保存着一个NodeList 对象。即类数组对象
    console.log(h.childNodes[0])
    console.log(h.childNodes[1])
    console.log(h.childNodes[2])
    console.log(h.childNodes[3])
    console.log(h.childNodes[4])

    console.log(h.parentNode)  //5

    console.log(h.childNodes.length)

把NodeTypelist转为数组

function convertToArray(nodes) {
    var array = null;
    try {
        array = Array.prototype.slice.call(nodes, 0); //针对非IE 浏览器
    } catch (ex) {
        array = new Array();
        for (var i = 0, len = nodes.length; i < len; i++) {
            array.push(nodes[i]);
        }
    }
    return array;
}

每个Node都有一个parentNode属性,该属性指向文档树中的父节点;
nodeName //HEAD
parentNode //Html文档结构
childNodes //Nodelists节点集合
previousSibling //前一个
nextSibling //后一个

如果没有子节点,那么firstChild 和lastChild 的值均为null

hasChildNodes(),这个方法在节点包含一或多个子节点的情况下返回true;应该说,这是比查询childNodes
列表的length 属性更简单的方法。

h.hasChildNodes()

ownerDocument,所有节点的共同属性,指向整个文档节点

console.log(h.ownerDocument)

操作节点

末尾:
appendChild()相当于向childNodes列表尾部添加一个节点,,如果是已有节点,则相当于剪切;

中间:
insertBefore(),向childNodes列表放在特定的位置上
insertBefore(要插入的节点,作为参照的节点) 【插入之后按顺序前后排:要插入的节点,作为参照的节点】

插入节点后,被插
入的节点会变成参照节点的前一个同胞节点(previousSibling),

returnedNode = someNode.insertBefore(newNode, null);
alert(newNode == someNode.lastChild); //true

//插入后成为第一个子节点
var returnedNode = someNode.insertBefore(newNode, someNode.firstChild);
alert(returnedNode == newNode); //true
alert(newNode == someNode.firstChild); //true

//插入到最后一个子节点前面
returnedNode = someNode.insertBefore(newNode, someNode.lastChild);
alert(newNode == someNode.childNodes[someNode.childNodes.length-2]); //true

替换:

replaceChild(要插入的节点,要替换的节点)

//替换第一个子节点
var returnedNode = someNode.replaceChild(newNode, someNode.firstChild);

//替换最后一个子节点
returnedNode = someNode.replaceChild(newNode, someNode.lastChild);

移除:
removeChild(要移除的节点)

前面介绍的四个方法操作的都是某个节点的子节点,也就是说,要使用这几个方法必须先取得父节
点(使用parentNode 属性)。另外,并不是所有类型的节点都有子节点,如果在不支持子节点的节点
上调用了这些方法,将会导致错误发生。

共有的节点方法:

cloneNode(true/false),需要再使用 appendChild()/insertBefore()/replaceChild()

normalize() /这个方法唯一的作用就是处理文档树中的文本节点



Document类型

 nodeType 的值为9;
 nodeName 的值为"#document";
 nodeValue 的值为null;
 parentNode 的值为null;
 ownerDocument 的值为 null;
Document 节点的子节点可以是DocumentType、Element、ProcessingInstruction
或Comment,

内置访问子节点的快捷方式:
document.documentElement属性

document.documentElement ==
document.childNodes[0] ==
document.firstChild ==

document.body 属性,直接指向<body>元素;

另一个子节点可能是:(浏览器支持有限)

var doctype = document.doctype; //取得对<!DOCTYPE>的引用

文档信息

document对象属性:

//取得文档标题
var originalTitle = document.title;

//设置文档标题
document.title = "New page title";

//取得完整的URL
var url = document.URL;

//取得域名
var domain = document.domain;

//取得来源页面的URL
var referrer = document.referrer;

IE7下,name與ID相同的不同元素使用doc..ById會返回name的元素

    alert(document.getElementById('myelem').nodeName)

不要讓表單字段的name與其他ID相同

var imgs = document.getElementsByTagName('img')
var imgsname = imgs.namedItem('myimgName')

取得單選按鈕【常用】 getElementByName('color');

特殊集合
document.anchors:包括name屬性的a元素
document.links:包含所有帶href特性的a元素
document.images:包含所img元素
document.forms:包含所form元素

一個element類型:

    console.log(box.nodeType)  //1
    console.log(box.nodeName)  //DIV
    console.log(box.nodeValue) //null
    
    console.log(box.parentNode) //<body......body>
    console.log(box.childNodes) //[elem..text..com...]
    
    console.log(box.tagName) //DIV  tagName == nodeName

HTML元素,可读可写

alert(div.id); //"myDiv""
alert(div.className); //"bd"
alert(div.title); //"Body text"
alert(div.lang); //"en"
alert(div.dir); //"ltr"

取得特性

alert(div.getAttribute("id")); //"myDiv"
alert(div.getAttribute("class")); //"bd"
alert(div.getAttribute("title")); //"Body text"
alert(div.getAttribute("lang")); //"en"
alert(div.getAttribute("dir")); //"ltr"

不存在返回null;

自定义属性应该加上data-前缀以便验证

    var div = document.getElementById('myDiv')
        alert(div.my_special_attribute); //undefined(IE<8 弹 hello ,其它弹undefined)

设置属性:
box.setAttribute('style') //如果不写出错 box.setAttribute('style','')//正确

自定义属性不能简单地使用.来设置

        box.mycolor = 'red';  //使用.设置
        alert(box.getAttribute('mycolor')) //null;(IE9<可弹出)
        
        //setAttributte配套使用;
        box.setAttribute('myspace','300px')
        alert(box.getAttribute('myspace'))

div.removeAttribute("class");完全清除,彻底删除元素特性;

  1. attributes 属性
    Element 类型是使用attributes 属性的唯一一个DOM 节点类型。attributes 属性中包含一个

NamedNodeMap,与NodeList 类似,也是一个“动态”的集合。元素的每一个特性都由一个Attr 节
点表示,每个节点都保存在NamedNodeMap 对象中。NamedNodeMap 对象拥有下列方法

遍历元素特性序列化

function outputAttributes(element) {
    var pairs = new Array(),
        attrName,
        attrValue,
        i,
        len;
    for (i = 0, len = element.attributes.length; i < len; i++) {
        attrName = element.attributes[i].nodeName;
        attrValue = element.attributes[i].nodeValue;
        if (element.attributes[i].specified) {
            pairs.push(attrName + "=\"" + attrValue + "\"");
        }
    }
    return pairs.join(" ");
}

console.log(outputAttributes(box)) // id="box" style="font-size:14px;color:#000" class="boxclass"

创建元素

``javascript

var div = document.body.appendChild('div')
div.id = mydiv
document.body.appendChild(div)

创建文本

var box = document.getElementById('box')
if(box.childNodes[0].nodeType == 3 ){
    alert(123)
}
alert(box.childNodes[0].nodeValue)
alert(box.childNodes[0].data)

Text类型
var e = document.createElement('div')
e.className = 'message'
var atnode = document.createTextNode('fuck ')
e.appendChild(atnode)

var atnode2 = document.createTextNode('world')
e.appendChild(atnode2)


alert(e.childNodes.length) //2  个节点 

e.normalize()  //规范化成1个(合并)
alert(e.childNodes.length) //1

alert(e.firstChild.nodeValue) //fuck world

分割  splitText()
var e = document.createElement('div')
e.className = 'message'

var Tnode = document.createTextNode('hello world')
e.appendChild(Tnode)
document.body.appendChild(e);
var newNode = e.firstChild.splitText(2)
alert(e.firstChild.nodeValue) //he 从2的位置开始分割
comment类型 注释类型 nodeType == 8 
CDATASection类型 XML 文档,表示CDATA区域 nodeType == 4 
DocumentType类型 nodeType == 10
DocumentFragment类型 nodeType == 11;
Attr类型 存在于元素的attributes属性中的节点,nodeType == 11; ??

创建动态脚本:

function loadScript(url) {

var script = document.createElement('script')
script.type = 'text/javascript'
script.src = url
document.body.appendChild(script)

}
loadScript('main.js')


代码执行
function loadScriptString(code) {
    var script = document.createElement('script')
    script.type = 'text/javascript'
    try {
        script.appendChild(document.createTextNode(code))
    } catch (ex) {
        script.text = code;
    }
    document.body.appendChild(script)
}
loadScriptString("function sayHi(){alert('hi')}")`
其实效果跟     eval("function sayName(){alert('name')}")  一样; 

动态样式
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)
}
loadStyles('style.css')

function loadStyleString(css) {

var style = document.createElement('style')
style.type = 'text/css'
try {
    style.appendChild(document.createTextNode(css))
} catch (ex) {
    style.style.cssText = css;
}
document.getElementsByTagName('head')[0].appendChild(style);

}

loadStyleString('body{background:#1F78BF}')

操作表格
cell 11 cell 22
cell 33 cell 44
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 11'))
tbody.rows[0].insertCell(1);
tbody.rows[0].cells[1].appendChild(document.createTextNode('cell 22'))

//第二行

tbody.insertRow(1)
tbody.rows[1].insertCell(0);
tbody.rows[1].cells[0].appendChild(document.createTextNode('cell 33'))
tbody.rows[1].insertCell(1);
tbody.rows[1].cells[1].appendChild(document.createTextNode('cell 44'))

document.body.appendChild(table)

**HTMLCollection、NodeList以及NamedNodeMap这三个集合都是“动态的”,每当文档发生变化时,他们都会更新。他们将始终保持这最新、最准确的消息。且看以下程序:**
var divs = document.getElementsByTagName('div'),
    i, div;
for (i = 0; i < divs.length; i++) {
    div = document.createElement('div')
    document.body.appendChild(div)
}
//以上代码,第一次取得所有div 元素的HTMLCollection,下次取得会更新,造成死循环

//正确使用

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)
}

<hr />

DOM元素的特性(Attribute)  和    属性(Property)

Attribute特性: dom节点自带的属性,例如html中常用的id、class、title、align等:

<div id="div1" class="divClass" title="divTitle"></div>

//赋值:之后立即体现到DOM ,如果是标准特性,也会关联到相对应的属性值 ;

div1.setAttribute('class', 'a');
div1.setAttribute('title1', 'c');
Property属性: 而Property是这个DOM元素作为对象,其附加的内容,例如childNodes、firstChild等:

//取值,用.
var id = div1.id;
var attrs = div1.attributes;

//上面代码中的div1.attributes是取的attributes这一属性,取出来保存到attrs变量中,attrs就成了一个NamedNodeList类型的对象,里面存储了若干个Attr类型。

//赋值 :对属性Property可以赋任何类型的值,而对特性Attribute只能赋值字符串!
div1.className = 'a';



<hr >
NodeList v.s. HTMLCollection

Node及对应集合NodeList
Element(继承Node)及对应集合HTMLCollection
Document(继承Node)