7. DOM

7.1 DOM简介

  • DOM是文档对象模型,HTML文档的所有内容都是节点:

    • 整个文档是一个文档节点 (document 最顶级)

    • HTML元素内的文本是文本节点

    • 每个表面的属性是属性节点

    • 注释是注释节点

  • HTML DOM将HTML文档视作树结构,这种结构被称为节点树。

     
    文档 document
    根元素 html
    元素 head
    元素 body
    元素 title
    文本节点
    元素 a
    属性节点 href
     
  • 节点父、子、同胞:

    • 在节点树中,顶端节点称为根(root)

    • 除了根每个节点都有父节点

    • 一个节点可以拥有任意数量的子节点

    • 同胞是拥有相同父节点的节点

  • Node 类型:

    • JS中的所有节点类型都继承自Node类型,因此所有节点类型都共享着相同的基本属性和方法。每个节点都有一个nodeType属性,用于表明节点类型。节点类型由Node类型中定义的下列常量表示。

      • Node.ELEMENT_NODE == 1 //元素

      • Node.ATTRIBUTE_NODE == 2 //属性

      • Node.TEXT_NODE == 3 //文本

      • Node.ENTITY_NODE == 6 //实体

      • Node.DOCUMENT_NODE == 9 //文档

      • if(xxx.nodeType === Node.ELEMENT_NODE){alert(1)};·

  • Document 类型:

    • Document表示整个文档,Document对象是window对象的一个属性,所以可以当做全局对象访问。

    • 特征:nodeType=9;nodeName='#document';nodeValue=null;parentNode=null

    • 文档的子节点:

      • document.documentELement 该属性始终指向HTML页面的<html>元素,取得对<html>的引用

      • document.body //取得对<body>的引用,使用频率很高

      • document.head 选取 <head> 元素

    • 文档信息:

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

      • document.tilte = 'xxx';//修改文档标题

      • document.URL; //取得当前页面完整URL

      • document.domain;//获得域名 URL和referrer都不可以赋值,而domain可以赋值,domain只能赋值为同网站的

      • document.referrer;//获得来源页面的URL

    • 文档写入:

      • write('string'); writeln('string'); //区别是writeln会在字符串末尾加\\n

      • 可以动态地加载外部资源,例如JavaScript(无法自动执行代码),但是要注意:</script> 要写成这样 <\/script> ,因为不转义的话,会被当成标签结束,后面的代码将无法执行。

  • Element 类型:

    • Element 类型用于表现 XML 或 HTML 元素,提供了对元素标签名、子节点及特性的访问

  • Text 类型:

    • 文本节点由 Text 类型表示,包含的是可以照字面解释的纯文本内容。纯文本中可以包含转义后的 HTML 字符,但不能包含 HTML 代码。 即:HTML字符会被转义成实体

    • nodeType 的值为 3; nodeName 的值为"#text"; nodeValue 的值为节点所包含的文本; parentNode 是一个 Element; 不支持(没有)子节点。

    • appendData(text):将 text 添加到节点的末尾。

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

    • insertData(offset, text):在 offset 指定的位置插入 text。

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

    • splitText(offset):从 offset 指定的位置将当前文本节点分成两个文本节点。

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

    • 除了这些方法之外,文本节点还有一个 length 属性,保存着节点中字符的数目。

7.2 选取元素

【注意】:DOM操作必须等待HTML文档加载完毕才可以获取,可以用window.onload=function(){};或把<script>标签移到最后解决

  1. ///【通过ID选取】
  2. var div = document.getELementById('id');//返回带有【一个】指定ID的元素节点对象(PS:一个页面只允许一个id,表示唯一性)
  3. alert(div); //Object HTMLDivElement
  4. alert(div.tagName); //获取这个元素节点的标签名

  5. //当想要通过ID查找多个元素时,下面呢的getElements()函数很有用:
  6. function getElements(/*ids...*/){ //接收任意多个字符串参数(id)
  7. var elements = {}; //用于保存元素对象的空map映射对象
  8. for(var i = 0; i < arguments.length; i++){ //遍历每个id
  9. var id = arguments[i];
  10. var elt = document.getElementById(id);
  11. if(elt == null)
  12. throw new Error("No element with id: " + id); //如果id不存在,抛出异常,退出
  13. elements[id] = elt; //保存idd和元素之间的映射
  14. }
  15. return elements;
  16. }



  17. ///【通过name选取元素】
  18. // name属性用于向服务器提交数据,不唯一,多个元素可能具有同一个name;在表单中,单选、复选框通常是这种情况。和id不一样,name属性只在少数几个HTML元素中有效,包括:表单、表单元素、img、iframe
  19. var h1 = document.getELementsByName('h1'); //返回 NodeList 对象,类似一个包含若干Element对象的只读数组
  20. alert(h1.length); //获取长度
  21. alert(h1[0]); //访问第一个h1



  22. ///【通过标签名选取】
  23. var h1 = document.getELementsByTagName('h1'); //返回 NodeList 对象,对于标签名不区分大小写

  24. // NodeList中返回的元素是按照在文档中的顺序排序的,所以可以用下面的代码选取文档中第一个p元素
  25. var firstPara = document.getElementsByTagName("p")[0];

  26. // 给 getELementsByTagName() 传递通配符参数 * ,将获得一个代表文档所有元素的 NodeList 对象
  27. // Element 类也定义了 getElementsByTagName() 方法,原理和Document版本一样,只是它只选取调用该方法的元素的后代元素



  28. ///【通过 class 选取】
  29. var cla1 = document.getELementsByClassName('cla1'); //选取 class 属性值中包含 cla1 的元素
  30. var ab = document.getElementsByClassName('cla1 cla2'); //选取有 cla1 和 cla2 类的元素



  31. //【根据CSS选择器查找】
  32. document.querySelector('#nav'); //接收一个CSS选择器,返回子节点【第一个匹配到的元素】,没有返回null

  33. div.querySelector('p');//上面是文档搜索,这个是在 div 下的子节点搜索

  34. document.querySelectorAll('body');//返回所有符合的结果,NodeList




  35. //***** DOM扩展 (不是HTML5规范,但都可以用) ******
  36. //滚动
  37. var p = document.getElementById('p');
  38. p.scrollIntoView();//滚动到 ID 为p 的标签,类似于锚点

  

7.3 DOM节点

  1. ///【节点(node)属性】
  2. alert(node.nodeName);//获取元素节点标签名,和tagName等价;属性节点名;文本节点是#text
  3. alert(node.nodeType);//获取元素节点类型 1;属性节点类型 2;文本节点类型 3;
  4. alert(node.nodeValue);//获取元素节点为null;获取属性节点的属性值;获取文本节点的文本内容
  5. alert(node.innerHTML);//只能获取元素节点的文本内容(两个标签间的所有内容),无法获取文本节点内容
  6.  
  7. a.href = 'http://test.cc'; //可以直接访问、修改元素的原生属性
  8. alert(div.className); //通过className获取class属性的值,不用class,因为是保留字
  9.  
  10. // 【可以设置、读取 元素的非标准属性】
  11. alert(div.getAttribute('xxx')); //获取自定义和自有的属性,可以用class
  12. div.setAttribute('属性名','值'); //设置属性值
  13. div.removeAttribute('属性名'); //删除属性名
  14. div.hasAttribute('属性名'); //判断是否有某个属性,判断布尔值属性(disabled)很有用
  15.  
  16. //【数据集属性】
  17. // 想要给HTML元素绑定额外的信息,可以用getAttribute() setAttribute()方法来读写非标准属性的值。HTML5 提供了一个解决方案,在HTML5 中任意以“data-”为前缀的小写属性都是合法的 数据集属性。
  18. // HTML5在Element对象上定义了dataset属性,该属性指代一个对象,它的各个属性对应于去掉前缀的data-属性,如:dataset.xy 保存着 data-xy的属性的值;data-后的属性名如果有 - ,改成驼峰命名法
  19.  
  20. ///【层次节点属性】
  21. // childNodes 属性
  22. // <node>haha <b>xxx</b> end</node>
  23. alert(node.childNodes);//返回 NodeList 对象,当前元素节点的所有子节点列表
  24. alert(node.childNodes.length);//返回 NodeList 的长度,3
  25. alert(node.childNodes[0]);//返回第一个子节点,文本节点(Object Text) haha
  26. node.childNodes[0].nodeValue = '<b>xxx</b>';//可以赋值,标签会被转义成实体,innerHTML不会
  27.  
  28. //firstChild lastChild removeChild
  29. alert(node.firstChild);//返回第一个子节点(文本和元素节点)
  30. alert(node.lastChild.nodeValue);//返回最后一个子节点 end
  31. node.removeChild(node[0])//移除子节点
  32.  
  33. //firstElementChild lastElementChild childElementCount
  34. alert(node.firstElementChild);//返回第一个【元素节点】
  35. alert(node.lastElementChild);//返回最后一个【元素节点】
  36. alert(node.childElementCount);//返回元素节点数量
  37.  
  38. //parentNode previousSibling nextSibling
  39. alert(node.parentNode);//返回父节点
  40. alert(node.previousSibling);//返回本节点上一个节点(文本节点和元素节点)
  41. alert(node.nextSibiling);//返回本节点的下一个节点
  42.  
  43. //nextElementSibling previousElementSibling parentNode
  44. alert(node.nextElementSibling);//返回下一个【元素节点】
  45.  
  46. //attributes 属性
  47. alert(node.attributes);//返回 object NamedNodeMap,这个元素节点的属性结合
  48. alert(node.attributes.length);//返回属性集合长度
  49. alert(node.attributes[0]);//返回一个属节点
  50. alert(node.attributes['id']);//通过属性名访问
  51. node.attributes['id']='test';//修改属性
  52.  
  53. //移除空白节点
  54. //当两个标签里含有空格或换行符时会被当做空白的文本节点
  55. function removeWhiteNodes(node){
  56. for(var i=0; i<node.childNodes.length; i++){
  57. if(node.childNodes[i].nodeType==3 && /^\s+$/.test(node.childNodes[i].nodeValue)){
  58. node.childNodes[i].parentNode.removeChild(node.childNodes[i]);
  59. //childNodes[i].remove();
  60. }
  61. }
  62. return node;
  63. }
  64.  
  65. //*****DOM扩展 (不是HTML5规范,但都可以用) *****
  66. // children 属性 【解决空白节点的问题】
  67. // 返回节点的所有子元素节点,只返回子节点中的元素节点
  68. /*
  69. <div id='div'>
  70. 111
  71. <p>haha</p>
  72. <p>enen</p>
  73. 222
  74. </div>
  75. */
  76. alert(document.getElementById('div').children.length);//2
  77. alert(document.getElementById('div').children[0]);//返回第一个 p元素节点HTMLParagraphElement
  78.  
  79. //contains()方法
  80. //判断一个节点是不是另一个节点的子节点
  81. alert(div.contains(p));//true

  

7.4 节点操作

  1. //createElement createTextNode appendChild
  2. var div = document.getElementById('div');
  3. var p = document.createElement('p');//创建一个元素节点,没有添加到文档,只是驻留在内存里
  4. var text = document.createTextNode('ppppp');//创建一个文本节点
  5. p.appendChild(text);
  6. div.appendChild(p);//将节点添加到子节点末尾
  7.  
  8. //insertBefore()
  9. node.insertBefore(newItem[,existingItem]);//在node 的子节点existingItem前插入一个newItem
  10. //JavaScript没有提供insertAfter
  11. function insertAfter(newItem,targetItem){
  12. var parent = targetItem.parentNode;
  13. if(targetItem == parent.lastChild){
  14. parent.appendChild(newItem);
  15. }else{
  16. parent.insertBefore(newItem,targetItem.nextSibling);
  17. }
  18. }
  19.  
  20. //replaceChild removeChild cloneNode remove
  21. node.replaceChild(newItem,oldItem);//替换子节点,【注意新节点在前】
  22. node.removeChild(node[1])//移除子节点
  23. var clone = node.cloneNode(true);//克隆一个节点,true表示包括所有子节点,false不包括
  24. node.remove();//删除自身
  25.  
  26. //***** DOM扩展 - 插入 *****
  27. /*
  28. 虽然 DOM 为操作节点提供了细致入微的控制手段,但在需要给文档插入大量新 HTML 标记的情况下,通过 DOM 操作仍然非常麻烦,因为不仅要创建一系列 DOM 节点,而且还要小心地按照正确的顺序把它们连接起来。相对而言,使用插入标记的技术,直接插入 HTML 字符串不仅更简单,速度也更快。以下与插入标记相关的 DOM 扩展已经纳入了 HTML5 规范。
  29. */
  30.  
  31. //innerHTML属性 (是HTML5规范)
  32. //在读模式下,innerHTML 属性返回与调用元素的所有子节点(包括元素、注释和文本节点)字符串。在写模式下,innerHTML 会根据字符串创建新的 DOM 树,然后用这个 DOM 树完全替换调用元素原先的所有子节点。
  33. //插入 script 标签并不会执行里面的JS代码
  34.  
  35. //innerTEXT属性 (不是HTML5规范)
  36. //返回子节点中所有文本节点的字符串,即去除所有标签
  37. /*
  38. <div>
  39. aaa
  40. <p>bbb</p>
  41. haha
  42. */
  43. alert(div.innerTEXT);//aaa bbb haha
  44.  
  45. //outerHTML属性 (是HTML5规范)
  46. //在读模式下, outerHTML 返回调用它的元素及所有子节点的 HTML 标签。 在写模式下, outerHTML会根据指定的 HTML 字符串创建新的 DOM 子树,然后用这个 DOM 子树完全替换调用元素
  47. //和innerHTML 类似,只不过操作包括了当前节点
  48.  
  49. //outerTEXT属性 (不是HTML5规范)
  50. //同上,包括了当前节点

  

7.5 样式

7.5.1 访问元素的样式

任何支持 style 特性的 HTML 元素在 JavaScript 中都有一个对应的 style 属性。 这个 style 对象 是 CSSStyleDeclaration 的实例,包含着通过 HTML 的 style 特性指定的所有样式信息,但不包含与外部样式表或嵌入样式表经层叠而来的样式。在 style 特性中指定的任何 CSS 属性都将表现为这个 style 对象的相应属性。对于使用短划线(分隔不同的词汇,例如 background-image)的 CSS 属性名,必须将其转换成驼峰大小写形式,才能通过 JavaScript 来访问。例如:

  1. background-image ==> backgroundImage font-size ==> fontSize
  1. //-----只要取得一个有效的 DOM 元素的引用,就可以随时使用 JavaScript 为其设置样式(但是float是JavaScript保留字,所以不能直接使用CSS属性float,改成cssFloat
  2. //-----例如:
  3. var div = document.getElementById('div');
  4. div.style.backgroundColor = 'red';//设置背景颜色
  5. div.style.width = '100px';
  6. div.style.height = '200px';//改变大小
  7. div.style.border = '1px solid black';//设置边框
  8.  
  9. //-----通过 style 对象同样可以取得在 style 特性中指定的样式,只能是获得行内的(style属性)
  10. alert(div.style.backgroundColor);
  11. alert(div.style.width);
  12.  
  13. //-----【DOM 样式属性和方法】
  14. //style 对象定义了一些属性和方法。这些属性和方法在提供元素的 style特性值的同时,【也可以修改样式】。
  15. style.cssText //获得style属性的CSS代码
  16. style.length //获得CSS属性的数量
  17. styl.e.parentRule //CSS信息的CSSRule对象
  18. style.getPropertyValue(属性名); //返回给定属性的字符串值
  19. style.removeProperty(属性名); //从样式中删除指定属性
  20. style.setProperty(属性名,值); //设置属性
  21. style.item(index); //返回指定索引的CSS属性名
  22.  
  23. ///【操作样式表】

  

7.5.2 元素大小 和 位置

  • 偏移量:

    • 偏移量(offset dimension),包括元素在屏幕上占用的所有可见的空间。

    • 这些属性每次访问都要重新计算,可以保存在局部变量中以提高性能

    • offsetHeight:元素在垂直方向上占用的空间大小,以像素计。包括元素的高度、(可见的)水平滚动条的高度、上边框高度和下边框高度。

    • offsetWidth:元素在水平方向上占用的空间大小,以像素计。包括元素的宽度、(可见的)垂直滚动条的宽度、左边框宽度和右边框宽度。

    • offsetLeft:元素的左外边框 至包含元素的左内边框之间的像素距离。

    • offsetTop:元素的上外边框 至包含元素的上内边框之间的像素距离

  • 客户区大小:

    • 元素的客户区大小(client dimension),指的是元素内容及其内边距所占据的空间大小。

  • 滚动大小:

    • 滚动大小(scroll dimension),指的是包含滚动内容的元素的大小。

    • scrollWidth 和 scrollHeight 主要用于确定元素内容的实际大小。

7. JavaScript学习笔记——DOM的更多相关文章

  1. Javascript学习笔记二——操作DOM

    Javascript学习笔记 DOM操作: 一.GetElementById() ID在HTML是唯一的,getElementById()可以定位唯一的一个DOM节点 二.querySelector( ...

  2. Javascript学习笔记三——操作DOM(二)

    Javascript学习笔记 在我的上一个博客讲了对于DOM的基本操作内容,这篇继续巩固一下对于DOM的更新,插入和删除的操作. 对于HTML解析的DOM树来说,我们肯定会时不时对其进行一些更改,在原 ...

  3. Java程序猿的JavaScript学习笔记(8——jQuery选择器)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  4. Java程序猿JavaScript学习笔记(2——复制和继承财产)

    计划和完成在这个例子中,音符的以下序列: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaSc ...

  5. Java程序猿的JavaScript学习笔记(12——jQuery-扩展选择器)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  6. html学习笔记-DOM

    html学习笔记-DOM Table of Contents 1. 什么是 DOM? 2. DOM 节点 3. DOM 方法 4. DOM 属性 5. DOM 访问 6. DOM 修改 7. DOM ...

  7. Java程序猿的JavaScript学习笔记(9—— jQuery工具方法)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  8. Java程序猿的JavaScript学习笔记(6——面向对象模拟)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  9. Javascript学习笔记四——操作表单

    Javascript学习笔记 大多网页比如腾讯,百度云之类的需要登陆,用户输入账号密码就可以登陆,那么浏览器是如何获取用户的输入的呢?今天就记录一下操作表单. 操作表单与操作DOM是差不多的,表单本身 ...

随机推荐

  1. Python爬虫入门五之URLError异常处理

    大家好,本节在这里主要说的是URLError还有HTTPError,以及对它们的一些处理. 1.URLError 首先解释下URLError可能产生的原因: 网络无连接,即本机无法上网 连接不到特定的 ...

  2. [SHELL]:let 命令详解

    [SHELL]:let 命令详解 摘自:https://blog.csdn.net/happygongzhuo/article/details/6819099 let :简单的计算器  语 法let[ ...

  3. php eval

    // Our PHP code inside a variable $phpCode = ' class Foo { private $name; public function __construc ...

  4. 【转】jvm 堆内存 栈内存 大小设置

    原文地址:http://blog.csdn.net/qh_java/article/details/46608395 4种方式配置不同作用域的jvm的堆栈内存! 1.Eclise 中设置jvm内存: ...

  5. jQuary总结7:动画操作,显示与隐藏 淡入淡出, 滑入滑出

    1 jquery提供了三组基本动画,这些动画都是标准的.有规律的效果,jquery还提供了自定义动画的功能. 2 显示与隐藏: show([speed],[easing],[callback]) 显示 ...

  6. CodeForces 347B Fixed Points (水题)

    题意:给定 n 数,让你交换最多1次,求满足 ai = i的元素个数. 析:很简单么,只要暴力一遍就OK了,先把符合的扫出来,然后再想,最多只能交换一次,也就是说最多也就是加两个,然后一个的判,注意数 ...

  7. Exception (3) Java exception handling best practices

    List Never swallow the exception in catch block Declare the specific checked exceptions that your me ...

  8. 检测远程主机上的某个端口是否开启——telnet命令

    要测试远程主机上的某个端口是否开启,无需使用太复杂的工作,windows下就自带了工具,那就是telnet.ping命令是不能检测端口,只能检测你和相应IP是否能连通. 1 安装telnet.win7 ...

  9. 查看Linux系统是32位的还是64位的

    方法1: getconf LONG_BIT 上面显示我先用的是32位的系统. 方法2: .uanme -a .uname -m 显示i686或x86就是32位的系统,显示x86_64就是64位系统. ...

  10. Maven整理笔记の生命周期和插件

    项目构建的生命周期,其实软件开发人员每天都在干这个事,即项目清理.初始化.编译.测试.打包.集成测试.验证.部署和站点生成等,可以说几乎所有项目的构建都可以映射到这样一个生命周期上. Maven的插件 ...