DOM操作

一、Node类型

以下是所有节点都有的属性

1.nodeType判断节点类型,nodeType=1 元素节点  nodeType=2 属性节点   nodeType=3 文本节点

为了确保跨浏览器兼容,最好将nodeType值与数字比较。

2.nodeName节点名称。对于元素节点,nodeName中保存的始终都是元素的标签名,nodeValue的值则始终都是null。

3.节点关系

1)childNodes 属性查看子节点,保存的是NodeList对象,是一种类数组对象,用于保存有序的节点。其length属性是变化的

可以通过Array.prototype.slice()方法将其转换为数组。

var arrayofNodes=Array.prototype.slice.call(someNode.childNodes,0)//IE8及之前版本中无效

跨浏览器:

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]);

    }

  }

}

2)parentNode 该属性指向文档树中的父节点。

3)previousSibling  前一个相邻的兄弟,nextSibling 后一个相邻的兄弟,兄弟节点不保证是元素节点

4)firstChild  lastChild

5)hasChildNodes()节点是否有子节点,这个方法在节点包含一或多个子节点的情况下返回true

6)ownerDocument该属性指向表示整个文档的文档节点

4.操作节点方法

1)appendChild()向childNodes列表的末尾添加一个节点,返回新增的节点,参数是新节点

如果传入到appendChild()中的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新位置。

2)insertBefore(要插入的节点,作为参照的节点),插入节点后,被插入节点会变成参照节点的前一个同胞节点,同时被方法返回。如果参照节点是null,则insertBefore()与appendChild()执行相同的操作。调用这个方法的是父节点

3)replaceChild(要插入的节点,要替换的节点),要替换的节点将由这个方法返回并从文档数中被移除,同时由要插入的节点占据其位置。

4)removeChild(要移除的节点),被移除的节点作为方法的返回值

5)cloneNode()用于创建调用这个方法的节点的一个完全相同的副本。cloneNode()接受一个布尔值参数,表示是否进行深复制。true:深复制,复制节点及其整个子节点树

false:浅复制,只复制节点本身。复制后返回节点副本属于文档所有,但并没有为它指定父节点。

cloneNode()不会复制添加到DOM节点中的JavaScript属性,因此建议在复制之前先移除事件处理程序。(IE除外)。

6)normalize()唯一的作用就是处理文档树中的文本节点。当在某个节点上调用这个方法时,就会在该节点的后代节点中查找,如果找到了空文本节点就删除,如果找到相邻文本节点则将他们合并为一个文本节点。

二、Document类型

1.文档的子节点。

1)文档的子节点值的是html元素。document.documentElement始终指向html元素,另一个就是document.childNodes[0],document.firstChild

2)document.body直接指向body元素。所有浏览器都支持document.documentElement和document.body属性

2.文档信息

1)document.doctype取得对<!DOCTYPE>的引用,浏览器对其的支持差别很大。

2)document.title通过这个属性可以取得当前页面的标题,也可以修改当前页面的标题并反映在浏览器的标题栏中。修改title属性的值会改变<title>元素。

3)document.URL包含页面的完整URL

4)document.domain包含页面的域名

5)document.referrer保存着链接到当前页面的那个页面的URL

3),4),5)中只有document.domain是可以设置的,并且只能设置为URL中包含的域。

3.查找元素

1)document.getElementById() 找到返回该元素,没找到返回null

IE7及较低版本有个怪癖:name特性与给定ID匹配的表单元素(<input>、<textarea>、<button>、<select>)也会被该方法返回。如果有哪个表单元素的name特性等于指定的ID,而且该元素在文档中位于带有给定ID的元素前面,那么IE就会返回那个表单元素。为了避免IE中存在的这个问题,最好的办法是不让表单字段的name特性与其他元素的ID相同

2)document.getElementsByTagName() 返回的是包含0或多个元素的NodeList。这个方法会返回一个HTMLCollection对象,作为一个动态集合。

HTMLCollection对象还有一个方法,namedItem(),使用这个方法可以通过元素的name特性取得集合中的项。

<img src='' name='myImage'>

var myImage=document.getElementsByTagName('img').namedItem('myImage');

HTMLCollection对象也可以用方括号索引,传入的是数字,就调用item方法,传入的是字符串就调用namedItem方法。

3)document.getElementsByName()

3.文档写入

1)document.write()

2) document.writeIn()

write和writeIn都接受一个字符串参数,即要写入到输出流中的文本。write()会原样写入,writeIn()会在字符串末尾添加一个换行符‘ ’。

write和writeIn动态的包含外部资源,所以不能直接包含字符串'</script>',这会导致该字符串被解释为脚本块的结束。

3) document.open()

4) document.close()

open close打开和关闭网页的输出流

三、Element类型

要访问元素的标签名,可以使用nodeName属性或tagName属性;这两个属性会返回相同的值。 

注意:div.tagName输出的是大写的标签名,在XML中输出与源码一致。因此比较时应该这样:if(element.tagName.toLowerCase()=='div');对于nodeName同样采用这种方式。

1.HTML元素

标准特性有:id title lang dir className这些属性都可以用来取得或修改相应的特性值。

2.取得特性

1)getAttribute()

getAttribute()方法不区分大小写,也可以取得自定义特性。不过只有公认的(非自定义)特性才会以属性的形式添加到DOM对象中。

<div id='myDiv' align='left' data-my_attribute='hello'></div>

div.id  //myDiv

div.data-my_attribute //undefined

div.align //left

有两类特殊的特性,虽然有对应的属性名,但属性的值与通过getAttribute()返回的值不相同。第一类特性是style,用于通过CSS为元素指定样式。getAttribute()返回的style特性值中包含的是CSS文本,而通过属性来访问它则会返回一个对象。

第二类是onclick这样的事件处理程序,当在元素上使用时,onclick特性中包含的是js代码,如果通过getAttribute返回的是相应代码的字符串。在访问onclick属性时,则会返回一个js函数(如果未在元素中指定相应特性,则返回null)。这是因为onclick及其他事件处理程序属性本身就应该被赋予函数值。

开发人员经常不使用getAttribute而是只使用对象的属性。只有在取得自定义特性值的情况下,才会使用getAttribute方法。

2) setAttribute(要设置的特性名,值)

如果特性已经存在,会以指定的值替换现有的值;如果特性不存在,就创建该属性并设置相应的值。

3) removeAttribute()

3.attributes属性

attributes属性的nodeValue为属性名,nodeName为属性值。通过attributes属性可以遍历一个元素的属性,但是在IE7及更早版本中会返回HTML元素中所有可能的特性,包括没有指定的特性。每个特性节点都有个specified属性,这个属性的值为true则意味着要么是HTML中指定了相应特性,要么是通过setAttribute方法设置了特性。因此可以如下跨浏览器遍历元素特性

function outputAttribute(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(' ');

}

4.创建元素

document.createElement(要创建元素的标签名)

5.元素的子节点

IE中计算子节点会忽略空白符,但是其他浏览器中会将空白符算在子节点中,因此在执行操作前,需先检查一下nodeType属性

for(var i=0,len=element.childNodes.length;i<len;i++){

  if(element.childNodes[i].nodeType==1){

  }

}

四、Text类型

可以通过nodeValue属性或data属性访问Text节点中包含的文本,这两个属性中包含的值相同。

1.操作节点中的文本方法

1)appendData(text)将text添加到节点末尾

2)deleteData(offset,count)从offset指定的位置开始删除count个字符

3)insertData(offset,text)在offset指定的位置插入text

4)replaceData(offset,count,text)用text替换从offset指定的位置开始到offset+count为止处的文本。不包括offset+count

5)splitText(offset)从offset指定的位置将当前文本节点分成两个文本节点,offset处的文本划分到后一个文本节点

6)substringData(offset,count)提取从offset指定的位置开始到offset+count为止处的字符串

2.创建文本节点document.createTextNode(要插入节点中的文本)

3.规范化文本节点normalize()。在具有两个相邻文本节点的父元素上调用normalize()方法,能将其合并为一个文本节点。

五、DocumentFragment类型

虽然不能把文档片段直接添加到文档中,但可以将它作为一个仓库来使用,即可以在里面保存将来可能会添加到文档中的节点。要创建文档片段,可以使用document.createDocumentFragment()方法。

var fragment=document.createDocumentFragment();

如果将文档中的节点添加到文档片段(fragment)中,就会从文档树中移除该节点,也不会从浏览器中再看到该节点。添加到fragment中的新节点同样也不属于文档树。

可以通过appendChild()或insertBefore()将fragment中内容添加到文档中。在将文档片段作为参数传递给这两个方法时,实际上只会将文档片段的所有子节点添加到相应位置上;文档片段本身永远不会成为文档树的一部分。

<ul id='myList'></ul>

现在想为这个ul元素添加3个li元素,如果逐个添加列表项,将会导致浏览器反复渲染(呈现)新信息。为避免这个问题,可以用一个文档片段来保存创建的列表项,然后再一次性将它们添加到文档中。

var ul=document.getElementById('myList');

var li=null;

for(var i=0;i<3;i++){

  li=document.createElement('li');

  li.appendChild(document.createTextNode('Item'+(i+1)));

  fragment.appendChild(li);

}

ul.appendChild(fragment);

Dom 操作技术

1.动态加载script脚本,两种方式都是立即可用

外部方式

function loadScript(url){

  var script=document.createElement('script');

  script.type='text/javascript';

  script.src=url;

  document.body.appendChild(script);

}

行内方式

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

}

2.动态样式

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.appendChld(link);

}

嵌入式

function loadStyleString(css){

  var style=document.createElement('style');

  style.type='text/css';

  try{

    style.appendChild(document.createTextNode(css));

  }catch(ex){

    style.styleSheet.cssText=css;

  }

  var head=document.getElementsByTagName('head')[0];

  head.appendChild(style);

}

3.操作表格

<table>中添加的属性和方法:

caption  tBodies   tFoot   tHead   rows  

createTHead()   createTFoot()   createCaption()    deleteTHead()   deleteTFoot()   deleteCaption()   deleteRow(pos)   insertRow(pos)

<tbody>添加的属性和方法

rows   deleteRows(pos)   insertRow(pos)

<tr>添加的属性和方法

cells  deleteCell(pos)   insertCell(pos)

举例

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 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'));

原文地址:https://www.cnblogs.com/YangqinCao/p/5485117.html