JavaScript高程第十章:DOM(上)

Node范例

除了IE(活该的IE),其他统统浏览器都能够接见到Node范例,而JS中统统节点范例都继续自Node范例,因而统统节点范例都同享着雷同的基础属性和要领.
每一个节点都有一个nodeType属性,能够表明节点的范例,我们来看看有哪些范例吧

  1. Node.ELEMENT_NODE(1)

  2. Node.ATTRIBUTE_NODE(2)

  3. Node.TEXT_NODE(3)

  4. Node.CDATA_SECTION_NODE(4)

  5. Node.ENTITY_REFERENCE_NODE(5)

  6. Node.ENTITY_NODE(6)

  7. Node.PROCESSING_INSTRUCTION_NODE(7)

  8. Node.COMMENT_NODE(8)

  9. Node.DOCUMENT_NODE(9)

  10. Node.DOCUMENT_TYPE_NODE(10)

  11. Node.DOCUMENT_FRAGMENT_NODE(11)

  12. Node.NOTATION_NODE(12)
    nodeNamenodeValue属性则完全取决于nodeType,关于元素节点,nodeName保留的一直为标署名,而nodeValue保留的值一直为null

childNodes属性中保留着一个NodeList对象(类数组对象,并不是Array的实例),NodeList是动态的,是基于DOM构造动态实行查询的结果,我们能经由过程以下体式格局来接见子节点.

var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;

关于NodeList对象,我们还能够转换为数组,以下

var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);

值得注重,该段代码在IE8及更早版本前是报错的,这是因为IE8及更早版本将NodeList完成为一个COM对象,而我们不能像运用JScript对象那样运用该对象,所以上述代码会致使毛病.以下是关于兼容性的解决要领.

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(node[i]);
    }
  }
  return array;
}

每一个节点另有parentNode属性,该属性指向文档树中的父节点.包含在childNodes列表中的统统节点都有雷同的父节点,而childNodes列表中的每一个节点之间为同胞节点,能够经由过程previousSiblingnextSibling属性接见.假如列表只要一个节点,则该节点上述两个属性为null.
父节点与其第一个和末了一个子节点之间也存在特别关联.父节点存在属性firstChildlastChild离别指向它们.个中firstChildchildNodes[0]相称,而x.lastChildx.childNodes[x.childNodes.length-1]相称.

节点中hasChildNodes()要领也是一个有效的要领,在包含节点情况下返回true,不然返回false.

统统节点末了一个属性都为ownerDocument,它指向示意全部文档的文档节点,即#document,能够使我们直接抵达顶层.

操纵节点

注重:关联指针都是只读的,所以DOM供应了一些函数供我们操纵节点.
以下引见了四种操纵要领,都须要先取得父节点,然则须要邃晓不是统统范例的节点都有/支撑子节点.

插进去节点

appendChild(node) //向childNodes列表末端增加一个节点,并在增加后,关联指针会响应更新.

值得注重的是appendChild()增加的节点假如已经是文档的一部份,那末相当于转移节点.

insertBefore(node,null) //参数一为插进去节点,第二个参数则为参照节点,设为null则结果与appendChild一样,存在参照节点则插进去节点变成参照节点前一个同胞节点(previousSibling)

移除/替代节点

removeChild(oldNode) //移除并不是替代节点,返回值为oldNode
replaceChild(newNode,oldNode) //oldNode替代为newNode,oldNode虽然技术上依然存在,然则文档中没有了它的位置

其他要领

这里有两个要领是统统范例节点都有的,它们就是cloneNode(boolean)normalize(),我们重点引见cloneNode()

cloneNode(boolean) //传入一个布尔值,该值决议实行深复制(节点及全部节点树)照样浅复制(仅复制自身)

注重点一:深复制IE9之前版本不会为空白符建立节点,所以深复制时childNodes长度会有所差异.
注重点二:cloneNode()要领只复制特性和子节点(指定情况下),不会复制JS属性如事宜处置惩罚顺序等等(除开IE,存在复制事宜处置惩罚顺序的bug),所以复制前最好先移除事宜处置惩罚顺序.

Element范例

除了Document范例,我们Web编程中最经常使用的范例就是Element范例啦.
Element 范例用于表现XML或HTML元素,供应了对元素标署名,子节点,特性的接见

特性

  • nodeType值为1

  • nodeName为元素标署名

  • nodeValue为null

  • parentNode多是Document或Element

  • 子节点多是Element,Text,Comment,ProcessingInstruction,CDATASection,EntityReference

个中nodeName和tagName属性返回雷同的值,引荐运用tagName,则表义更清楚,值得注重的是返回值大小写的题目,因为HTML中为报答,而XML/XHTML则会与源代码保持一致,所以比较时要一致大小写情势.
<!– more –>

HTML元素

HTML元素都由HTMLElement范例示意,不直接经由过程该范例,也是经由过程它的子范例示意.HTMLElement范例继续自Element而且增加了一些属性以下:

  • id 元素在文档中的唯一标识符

  • title 元素的附加申明信息,平常为东西提示条显现

  • lang 元素内容的言语代码,很少运用

  • dir 言语方向,ltr为从左到右,rtl则相反

  • className 与元素class的特性对应,没有设置为class则是因为class为ECMAScript的保留字

注重以上属性的修正并不是统统都邑在页面中直观的表现出来,id和lang修正对用户来讲是不可见的(假定没有css款式),对title的修正则只会在鼠标移动到元素上时才会显现出来(东西提示条),dir的修正则会在属性重写的那一刻马上影响页面中的文本,对className的修正则与是不是关联了差异的CSS款式有关.

特性

HTML元素每一个元素都有一个或多个特性,操纵特性的DOM要领以下有三个:

  • getAttribute()

  • setAttribute()

  • removeAttribute()
    这三个要领能够针对任何特性运用,包含自定义特性.

然则只要公认的特性才会增加到DOM元素属性上,自定义的特性一般是不存在的(undefined),固然这里又要注重我们的”好朋友”IE啦,它会为自定义特性建立属性.

特别特性

重要针对getAttribute()要领报告一下特别情况.

有两类特别特性,有对应的属性名,但值与getAttribute()返回的值并不雷同

  • style,经由过程getAttribute()接见会返回CSS文本,而经由过程属性接见返回一个对象

  • onclick如许的事宜处置惩罚顺序,经由过程getAttribute()接见会返回响应代码的字符串.而属性接见时,则会返回一个JavaScript函数(未指定则为null)

故一般只要取得自定义特性值的情况下,才会运用getAttribute()要领.

注重!:我们的”老朋友”IE7及之前版本中,getAttribute()要领接见上述两个特别特性时,返回的值与属性的值雷同.即getAttribute("style")返回一个对象,getAttribute("onclick")返回一个函数.

设置特性

这里重要讲解下setAttribute()要领,这和getAttribute()相对应.这个要领接收两个参数,要设置的特性名和值,假如特性存在则将值举行替代;不存在则建立并设置响应的值.
值得注重的是,设置特性名会转换为小写.而且直接给DOM元素增加一个自定义的属性并不会让这个属性成为元素的特性.

div.mycolor="red";
div.getAttribute("mycolor"); //这里返回null(IE除外)

移除特性

removeAttribute()要领用于完全删除元素特性,挪用该要领会消灭特性的值并完全删除特性.
注重!:IE6及之前版本不支撑该要领.

attributes属性

Element范例是运用attributes属性的唯一一个DOM节点范例.在该属性中包含一个NamedNodeMap,与NodeList类似,也是”动态”鸠合.元素每一个特性都由一个Attr节点示意,每一个节点都保留在NamedNodeMap对象中.相干要领以下:

  • getNamedItem(name)返回nodeName属性即是name的节点

  • removeNamedItem(name)从列表移除nodeName即是name的节点

  • setNamedItem(node)向列表增加节点,以节点的nodeName属性为索引

  • item(pos)返回处于数字pos位置处的节点

在该属性中有一系列的节点,每一个节点的nodeName就是特性的称号,nodeValue就是特性的值.要取得元素的id特性,能够运用attributes.getNamedItem("id").nodeValue
等同于attributes["id"].nodeValue

挪用removeNamedItem()与在元素上挪用removeAttribute()结果雷同.

setNamedItem()是一个很不经常使用的要领,该要领能够为元素增加一个新特性,另外须要为它传入一个特性节点.

注重!:IE7及更早版本会返回HTML元素中统统能够的特性,包含没指定的特性.
针对低版本革新:每一个特性节点都有一个名为specified的属性,假如为true则意味着要么HTML中指定了响应特性,要么经由过程setAttribute()设置了该特性,在IE中未设置过的特性都为false,其他浏览器则不会为这类特性天生对应特性节点.

建立元素

document.createElement()要领便可建立新元素.
该要领接收一个参数,就是元素标署名,这个标署名在HTML下不辨别大小写,XML中则会辨别大小写.

在建立新元素的同时,新元素也设置了ownerDocument属性,此时,还能够操纵元素特性,为它增加更多的子节点.
在设置完特性后,因为未增加到文档树,所以统统特性都不会影响浏览器的显现.我们能够经由过程之前讲到的appendChild(),insertBefore(),replaceChild()要领来举行响应的操纵.
一旦增加到文档树,则浏览器会马上显现该元素.今后我们的修正都邑反应到浏览器中.
注重!(常不斟酌):在IE中我们能够经由过程另一种体式格局举行建立

document.createElement("<div id=\"myNewDiv\" class=\"box\"></div>");

这个体式格局能够避开IE7及更早版本中动态建立元素的某些题目.(不能设置动态建立的iframe元素的name特性;不能经由过程表单的reset()要领重设动态建立的input元素;动态建立的type特性值为”reset”的button元素重设不了表单;动态建立的一批name雷同的单选按钮相互毫无关联)

元素子节点
除了IE,其他浏览器剖析代码时会剖析空白符为文本节点.我们能够经由过程nodeType属性的搜检来过滤掉它们.

Document 范例

在JavaScript中Document范例示意文档,我们经常使用的document对象是HTMLDocument(继续自Document范例)的一个实例,示意全部HTML页面;document对象照样window对象的一个属性,因而能够将其作为全局对象来接见.

特性

  • nodeType值为9

  • nodeName为”#document”

  • nodeValue为null

  • parentNode为null

  • ownerDocument为null

  • 子节点多是一个DocumentType(最多一个),Element(最多一个),ProcessingInstruction或Comment

Document范例能够示意HTML页面或许其他基于XML的文档,不过最常见的运用照样作为HTMLDocument实例的document对象.经由过程该对象,我们能够猎取页面有关信息,操纵页面的表面,以及其底层构造.
<!– more –>

文档子节点

虽然DOM范例划定Document节点的子节点能够是DocumentType,Element,ProcessingInstruction或Comment,然则另有两个内置的接见其子节点的快捷体式格局.
一:documentElement属性-一直指向HTML页面中的<html>元素
二:childNodes列表
而且以下代码所示

//html部份
//<html>
// <body></body>
//</html>

var html = document.documentElement;
console.log(html === document.childNodes[0]); //true
console.log(html === document.firstChild);    //true

可见documentElement,firstChild,childNodes[0]指向同一个元素<html>

而且作为HTMLDocument的实例,另有一个body属性,直接指向<body>元素.

统统浏览器都支撑document.documentElementdocument.body属性

DocumentType节点(不重要)

<!DOCTYPE>节点能够经由过程document.doctype属性猎取并接见它的信息.
以下是各浏览器支撑差异:

  • IE8及之前:存在文档范例声明,会毛病诠释为一个诠释并把它看成Comment节点;而document.doctype 值一直为null

  • IE9+及firefox:假如存在文档范例声明,则会将其作为文档第一个子节点;document.doctype是一个DocumentType节点,也能够经由过程document.firstChild或document.childNodes[0]接见.

  • Safari,Chrome和Opera:假如存在文档范例声明,则会将其剖析,但不作为文档子节点,document.doctype是一个DocumentType节点,但该节点不存在于document.childNodes中.

Comment(不重要)

<!-- 诠释1 -->
<html>
  <body>
  </body>
</html>
<!-- 诠释2 -->

关于上述诠释也在差异浏览器中存在差异.

  • IE8及之前,Safari3.1及更高,Opera和chrome:只为第一条诠释建立节点,部位第二条诠释建立节点.

  • IE9+:将第一条诠释建立为document.childNodes中的一个诠释节点,也将第二条诠释建立为document.childNodes中的诠释子节点

  • Safari3.1之前,firefox:完全疏忽

以上的不一致性致使了无论是诠释照样DocumentType节点关于我们来讲用途异常有限.

文档信息

document对象有属性供应了document对象所表现的网页的一些信息.

  • title:包含在<title>元素中的文本(浏览器窗口的标题栏或标签页上),然则修正该值不会转变<title>元素.

  • URL:包含页面完全的URL

  • domain:包含页面的域名

  • referrer:保留链接到当前页面的谁人页面的URL,如无泉源页面则为空字符串.
    注重!:这些信息都存在于HTTP头部,只不过我们能经由过程该属性在JS中接见它们.而且我们只能在遵守规则(不能将这个属性设置为URL中不包含的域,不能将域缩紧如将wrox.com设置为p2p.wrox.com一样(IE8及以后))的情况下设置domain属性.

个中domain属性照样超出跨域平安限定的好办法.

查找元素

重要用到document对象以下要领.

getElementById("id") //接收一个参数,假如找到响应元素则返回该元素,不存在则返回null

//注重!:IE8及较低版本不辨别ID大小写/假如存在多个ID则只返回第一次涌现的/IE7及较低版本中name值与ID婚配的表单元素会被返回

getElementsByTagName("img") //接收一个参数,为要取得元素的标署名,返回一个NodeList(包含零或多个元素).在HTML文档中,这个要领返回一个HTMLCollection对象,该对象与NodeList异常类似

getElementsByName("name") //只要HTMLDocument范例才有的要领.和上述两个要领类似,也就不诠释传入参数之类的啦

HTMLCollection对象

元素数目能够经由过程length取得,而且我们能够经由过程.item()和方括号语法[0]/["name特性"]来接见元素.namedItem()要领则能够经由过程name特性取得个中的元素.

特别鸠合

除了属性和要领,document对象另有一些特别鸠合.这些鸠合都是HTMLCollection对象,为接见文档经常使用部份供应了快捷体式格局,以下:

  • document.anchors 包含文档中统统带name特性的<a>元素

  • document.applets 包含文档中统统的<applet>元素(已不再引荐运用)

  • document.forms 包含文档中统统<form>元素

  • document.images 包含文档中统统<img>元素

  • document.links 包含文档中统统带href特性的<a>元素
    该鸠合一直能够经由过程HTMLDocument对象接见到.而且是动态的跟着当前文档内容的更新而更新.

DOM一致性(分级)

document.implementation属性就是用在检测浏览器完成了DOM的哪些部份.
document.implementation.hasFeature()要领接收两个参数,要检测的DOM功用称号和版本号,假如浏览器支撑则返回true.然则这并不代表着完成与范例一致

文档写入

document对象有一个存在良久的功用,将输出流写入到网页中的才能.这关乎到以下4个要领.

  • write()

  • writeln()
    上面两个要领都是接收一个字符串参数,writeln()额外在字符串写入后再写入一个换行符

注重!:假如要用于写入<script></script>则要对</script>举行转义=></script>,防备script标签被提早闭合致使没法实行;假如在文档接在完毕后再挪用则会致使全部页面重写.

  • open()

  • close()
    上述两个要领用于翻开和封闭网页的输出流,假如在页面加载时期运用write()和writeln()则不须要用到这两个要领(严厉型的XHTML文档不支撑文档写入)

    原文作者:thewindsword
    原文地址: https://segmentfault.com/a/1190000007240387
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞