DOM

作者: flyingtoparis | 来源:发表于2017-07-26 17:47 被阅读0次

节点层次

节点分为几种不同的类型,每种类型分别表示文档中不同的信息或标志,每个节点拥有各自的特点,数据和方法,节点与其他节点之间存在某种关系。节点之间构成了层次。

Node类型

  • js中所有的节点类型都继承自Node类型,因此所有的节点类型都共享着相同的基本属性和方法。
  • 每个节点都有一个nodeType属性,用于表示节点的类型
  • nodeType属性,用于表明节点的类型
if (some.nodeType == Node.ElEMENT_NODE){    // 节点类型p248   该方法在IE中无效
    console.log('node is an element')    
}

if(some.nodeType == 1){
    console.log('node is an element')       // 适用于所有的浏览器中
}
nodeName和nodeValue 属性
<body>
<div id="box"></div>
<script>
    var oBox = document.getElementById('box');
    console.log(box.nodeName);   // DIV  保存的始终是元素的标签名
    console.log(box.nodeType);   // 1    识别到元素的类型
    console.log(box.nodeValue);  // null 始终为null
</script>
</body>
节点关系
  • 每个节点包含childNodes属性,用于保存一组有序的节点,可以通过位置访问,有length属性,但是并不是Array实例
  • NodeList对象可以自动反映DOM的节点变化,并不是瞬间固定的
<body>
<div id="box">
    <a>1111111</a>
    <a>222222222</a>
    <a>3333333333</a>
    <a>44444444444</a>
</div>
<script>
    var oBox = document.getElementById('box');
    for ( var  i = 0; i < oBox.childNodes.length ; i ++){
        console.log(oBox.childNodes[i].nodeName);    //  #text A #text A #text A #text A #text
    }
    //console.log(oBox.childNodes[1].nodeName);
    // 这里只包含子节点,且包括文本节点(包括空格)
</script>
</body>
  • 对arguments对象使用Array.prototype.slice()方法可以将其转化为数组,采用同样的方法,也可以将NodeList对象转化为数组
var arrayofNodes = Array.prototype.slice(someNode.childNodes,0)    // IE8及以下不兼容

// IE8及以下版本
function convertToArray(nodes){
    var array = null;
    try{
        array = Array.prototype.slice(nodes,0)
    }catch(e){
        array = new Array;
        for ( var i = 0; i < nodes.length; i ++){
            array.push(nodes[i])
        }
    }
    return array;
}
  • children 只读属性子节点列表的集合
    标准下: 只包含元素类型的节点,包含非法嵌套节点
    非标准下: 只包含元素类型的节点,不包括非法嵌套

  • parentNode属性,指向文档树中的父节点

    • 包含在childNodes列表中的所有节点具有相同的父节点
    • 通过previousSibling和nextSibling属性,访问同一列表中的其他节点,第一子节点和最后一个子节点的previousSibling和nextSibling为null。如果只有一个字节点的话,都为null
    • 父节点的lastChild和firstChild指向第一个和最后一个子节点,只有一个节点的话,lastChild和firstChild指向相同的节点,没有子节点,为null
      firstChild 和 lastChild 标准下: 包含文本类型的节点
      非标准下: 只包含元素节点
var oFirst = oUl.firstElmentChild || oUl.firstChild   // 兼容
// 最好的解决方式 oUl.children[0].style.background = 'red';

var oNext = oBox.nextSibling || oBox.nextElementSibling;
var oPrev = oBox.previousSibling || oBox.previousElementSibling

操作节点

  • appendChild(),用于向childNodes列表末尾添加节点,如果传入到appendChild()方法的节点是已经存在的,则改变了节点的位置
<div id="box">
    <span class="span">span1</span>
    <span class="span">span2</span>
    <span class="span">span3</span>
</div>

<script>
    var oBox = document.getElementById('box');
    var aSpan = document.getElementsByTagName('span');
    //var oSpan = document.getElementById('span');
    oBox.onclick = function () {
        oBox.appendChild(aSpan[0])   
        // 被放入的父元素.appendChild(元素)   改变了现有元素的排列顺利
        // appendChild()操作的元素放入所有中的最后
    }
</script>
  • insertBefore() 接受两个参数,要插入的节点,和作为参考的节点,如果第二个参数不需要,则必须传入null,效果与appendChild()一样
<div id="box">
    <span class="span">span1</span>
    <span class="span">span2</span>
    <span class="span">span3</span>
</div>

<script>
    var oBox = document.getElementById('box');
    var aSpan = document.getElementsByTagName('span');
    //var oSpan = document.getElementById('span');
    oBox.onclick = function () {
        console.log('askdj')
        oBox.insertBefore(aSpan[0],aSpan[2])   // 在aSpan[2]的位置前插入aSpan[0]
        oBox.insertBefore(aSpan[0],null)       // 效果与appendChild一致
        console.log('afjkals')
    }
</script>
  • replaceChild() 接受两个参数,要插入的节点和替换的节点,要替换的节点将由这个方法返回并从文档中移除,同时由插入的节点占据其位置
<div id="box">
    <span class="span" id="span">span0</span>
    <span class="span">span1</span>
    <span class="span">span2</span>
</div>

<script>
    var oBox = document.getElementById('box');
    var aSpan = document.getElementsByTagName('span');
    var oSpan = document.getElementById('span');
    //var oSpan = document.getElementById('span');
    oBox.onclick = function () {
        console.log('askdj')
        oBox.replaceChild(aSpan[2],aSpan[0])    //  aSpan[2]替换了aSpan[0]的位置,方法返回移除的节点
        console.log('afjkals')

    }
    aSpan[2].onclick = function(){
        alert(oSpan.innerHTML)    // aSpan[0] 只是在文档中不存在这样位置了,但是节点仍然存在在文档中
    }
</script>
  • removeChild() 接受一个参数,即将要移除的节点,被移除的节点为这个方法的返回值
<div id="box">
    <span class="span" id="span">span0</span>
    <span class="span">span1</span>
    <span class="span">span2</span>
</div>

<script>
    var oBox = document.getElementById('box');
    var aSpan = document.getElementsByTagName('span');
    var oSpan = document.getElementById('span');
    //var oSpan = document.getElementById('span');
    oBox.onclick = function () {
        oBox.removeChild(aSpan[0])   // 删除该节点,且文档中没有改节点的位置
    }
</script>

Document 类型

  • document表示整个HTML页面,document是window对象的一个属性
文档的子节点
  • 页面经过浏览器的解析后,其文档只包含一个子节点,即html元素
var html = document.documentElement;
console.log(html === document.childNode[0]);   // true
console.log(html === document.firstChild);    // true
  • document 对象还有一个body属性,直接指向body元素
var body = document.body;    // 取得body的引用
文档信息
  • title 通过这个属性可以取得到当前页面的标题
var oTitle = document.title;   // 取得title
document.title = 'new';     // 设置title
  • URL,domain,referrer
    URL 包含页面完整的URL(地址栏中显示的URL),domain属性只包含页面的域名,而referrer包含链接到当前页面的那个页面的URL
查找元素
  • getElementById()
    要注意大小写的匹配(IE8和较低版本不区分ID的大小写)

  • getElementsByTagName() 接受一个参数,要取得元素的标签名

<div id="box">
    <span class="span" id="span">span0</span>
    <span class="span">span1</span>
    <span class="span" name="mySpan">span2</span>
</div>

<script>
    var oBox = document.getElementById('box');
    var aSpan = document.getElementsByTagName('span');    // 将一个HTMLCollection对象保存在images变量中
</script>

HTMLCollection对象上还有一个方法,namedItem(),通过name特性取得相应的值

<div id="box">
    <span class="span" id="span">span0</span>
    <span class="span" name="mySpan">span1</span>
    <span class="span" name="mySpan">span2</span>
</div>

<script>
    var oBox = document.getElementById('box');
    var aSpan = document.getElementsByTagName('span');
    aSpan.namedItem('mySpan').innerHTML = 'yellow';  
    console.log(aSpan.namedItem('mySpan'));    // 得到一个name是mySpan的元素
    aSpan['mySpan'].innerHTML = '444'
</script>

要得到所有元素则传入''
var allEle = document.getElementsByTagName('
')

  • getElementsByName()
    返回一个NodeList,同样具有namedItem()方法,只会取得第一项

  • 特殊集合
    document.links 包含所有带href特性的<a>元素

  • DOM一致性检测 p259

console.log(document.implementation.hasFeature('XML','1.0'));    
// 如果浏览器支持给定名称和版本功能,则该方法返回true
  • 文档的写入 write(),writeln(),open(),close()
<body>
<script>
    window.onload = function(){
        console.log(document.implementation.hasFeature('XML','1.0'));
        document.write('111111111111')      //  重写页面中的所有元素,包括title等只有body中留有write中的内容
    }
</script>
</body>


<script>
    document.write('111111111111');    // 在页面中添加元素
</script>

Element类型

  • 元素节点具有以下特征
    nodeType = 1
    nodeName 为元素的标签名
    nodeValue 值为null

  • 访问元素的标签名,可以使用nodeName,也可以使用tagName,这两个属性返回相同的值

<div id="box">kasdjf</div>
<script>
    var oBox = document.getElementById('box');
    console.log(oBox.tagName);    // 'DIV'
    console.log(oBox.nodeName);   // 'DIV'

    if ( ele.tagName.toLowerCase() == 'div'){    // 适用于任何文档(XML,XHTML)

    }
</script>
  1. HTML 元素

    • 元素中指定的信息,都可以通过下列方式获得
    <div id="box" title="askldfj" dir="rtl" class="red" lang="en">kasdjf</div>
    <script>
    var oBox = document.getElementById('box');
    console.log(oBox.id);    // oBox.title  oBox.dir  oBox.className   oBox.lang
    oBox.id = 'div'     // 修改相关样式
    console.log(oBox.style)    // 打印出所有的style样式
    </script>
    
  2. 取得特性 getAttribute()

    <script>
    console.log(oBox.getAttribute('id'))
    console.log(oBox.getAttribute('class'));    // 这种方式取得class属性传入的参数与实际的特性吗相同
    </script>
    
    1. 特性名称并不区分大小写
    2. 根据H5规范,自定义的属性应该加上data-前缀一遍验证
  3. 设置属性 setAttritute()

    • 接受两个参数,特性名和特性值,如果存在这样的值,则替换,如果特性不存在,则创建相应的值
div.setAttribute('id','someId')

//所有的特性都是属性
div.id = 'someId'
  1. 删除特性 removeAttribute()
    • 不仅会删除特性的值,也会完全的删除特性
div.removeAttribute('class');
  1. attributes 属性
console.log(oBox.id);
    console.log(oBox["id"]);
var id = ele.attribute['id'].nodeValue;
var id = element.attributes.getNamedItem('id').nodeValue;   // 取得id的属性值

var oldAttr = ele.attributes.removeNamedItem('id');
console.log(oldAttr);    // id="box"
  1. 创建元素
var div = document.createElement('div');   // 创建元素
div.id = 'div';
div.className = 'box';     // 设置属性

doucment.body.appendChild(div);
* IE7一些bug
    * 不能设置iframe元素的name特性
    * 不能通过reset()重设动态创建input元素
    * 动态创建的type特性值为reset的button元素重设不了表单
    * 动态创建的name相同的单选按钮毫无关系

    ```js
    var iframe = document.createElement("<iframe name=\"myframe\"></iframe>")
    var input = document.createElement("<input type=\"checkbox\">")
    var radio = document.createElement("<input type=\"radio\" name=\"choice\">")
    ```
  1. 元素的子节点
<ul id="myList">
    <li>kldjf</li>
    <li>kldjf</li>
    <li>kldjf</li>
</ul>
  • 在IE中ul的childNodes包含3个子节点,只有3个li
  • 在标准浏览器中,childNodes包含了7个子节点,3个li和li之间的空白符

DOM操作技术

操作表格

<script>
    var table = document.createElement('table');
    table.border = 1;
    table.width = "100%";
    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 2,1"));
    tbody.rows[0].insertCell(2);
    tbody.rows[0].cells[2].appendChild(document.createTextNode("cell 2,2"));

    tbody.insertRow(1);
    tbody.rows[1].insertCell(0);
    tbody.rows[1].cells[0].appendChild(document.createTextNode("cell 1,1"));
    tbody.rows[1].insertCell(1);
    tbody.rows[1].cells[1].appendChild(document.createTextNode("cell 2,1"));
    tbody.rows[1].insertCell(2);
    tbody.rows[1].cells[2].appendChild(document.createTextNode("cell 2,2"));

    document.body.appendChild(table);

    tbody.rows[0].cells[0]    // 这种方法获得表格中的相应的单元格
</script>

相关文章

  • dom 级别和dom 事件处理

    dom级别:dom0 dom1 dom2 dom3 dom事件处理:dom0 dom2 dom3 (1级DOM标准...

  • WY-DOM编程

    DOM Document Object Model DOM Core DOM HTML DOM Style DOM...

  • DOM事件

    DOM级别与DOM事件 DOM级别:DOM0级、DOM1级、DOM2级、DOM3级DOM事件:DOM0级事件处理、...

  • DOM事件

    DOM级别与DOM事件 DOM级别:DOM0级,DOM1级,DOM2级和DOM3级DOM事件:DOM0级事件处理,...

  • js红包雨活动

    function Block( dom ){ this.dom = dom; //dom this.parentW...

  • DOM操作的分类

    DOM操作分为三个方面,即DOM Core(核心)、HTML-DOM和CSS-DOM。 DOM Core DOM ...

  • 虚拟 DOM 和 diff 算法

    虚拟 DOM(Virtual DOM) 通过 JS 对象表示 DOM 结构,虚拟DOM 是对 DOM 的抽象 通常...

  • jQuery——DOM

    DOM操作分类 一般来说,DOM操作分为3个方面,即DOM Core、HTML-DOM、CSS-DOM。 DOM ...

  • JavaScript高级程序设计前四章

    1. DOM级别 1.1 DOM1级 由DOM核心(DOM Core)和DOM HTML两个模块组成。 DOM核心...

  • DOM分级详解

    DOM1 级(DOM Level 1) DOM1 级由两个模块组成:DOM核心(DOM Core)和DOM HTM...

网友评论

      本文标题:DOM

      本文链接:https://www.haomeiwen.com/subject/ldyokxtx.html