一,基本定义
DOM是针对HTML和XML文档的API,根据W3C的HTML DOM标准,html文档中所以内容(无论是元素还是标签还是注释还是元素属性)都是节点。

二,Node类型:
每一个节点都含有一个nodeType属性,对应着不同的数字,一共有12个,这里只记住前三个:
1.代表元素节点,也是最多的
2.代表属性节点,就是元素的属性,也是节点
3.代表文本,一个空格,一个回车都是代表#text节点
9.代表document文档

如果nodeType=1,元素节点,则nodeName就是标签名,注意这里是大写的(如“DIV”),nodeValue始终是null。

注意:nodeValue和innerHTML的区别
nodeValue指的是当前节点的值,这个节点是具体的,如果只是一个元素节点,那么没有任何值,它下面的子节点的值是它子节点的nodeValue,而且这个nodeValue包括所有的内容,像换行符也会包括,不是它的,所以它为null;而innerHTML指的是该节点下所有的子节点的字符串形式,包括它们的值。

html: <div id=“aa”>
    这里有一句话
   </div>

js: var aa = document.getElementById(“aa”);
aa.nodeValue; //null
aa.attributes[’id’].nodeValue; // aa
aa.childNodes[0].nodeValue; // (空行)
这里有一句话
(空行)
aa.innerHTML; // 这里有一句话

每一个节点都有一个childNodes属性,它保存着一个NodeList对象(就是你取一个节点,然后打印出来,就是这个对象,对象展开下面就是该节点下面所有的子节点),可以通过childNodes[a]来访问值,这个NodeList也有length值,它是类数组,但是它不是数组,同样不可以用数组的一些迭代运算。不过它有一个特殊的方法,item(a)可以访问到里面的子节点,
例:var secondChildNode = someNode.childNodes.item(1)。访问子节点的时候要注意,如果是常规的写法,没有写在一行里,分行写的,那么每一个换行都有一个#text节点。例如:
html: <div id=“aa”>
    <li></li>
    <li></li>
  </div>

js:
var div = document.getElementById(“aa”);
console.log(div.childNodes);

结果:
#text
li
#text
li
#text
(上面每一个都是对象,可展开的,里面就是他自身node节点属性)

如果需要把NodeList转换成数组来进行一系列的操作,可以用Array.prototype.slice()方法。不过这个方法在IE8之前无效,所以如果那样需要手动塞入:

function convertToArray(nodeList){
  var array = null;
  try{
    array = Array.prototype.slice.call(nodeList, 0);    //先检测是否是IE8之前版本
  } catch(ex){
    array = new Array();
    for(var i=0; i<nodeList.length; i++){
      array.push(nodeList[i])
    }
  }
  return array
}

三,节点属性:

parentNode: 父节点
firstChild: 第一个子节点
lastChild: 最后一个子节点
previousSibling: 前一个兄弟节点,NodeList.firstChild的这个属性一定是null
nextSibling: 后一个兄弟节点,NodeList.lastChild的这个属性一定是null
ownerDocument: 所有的节点最后一个属性都是这个,指向当前文档节点,可以直接找到它,唯一一个

四,操作节点(带child的都是操作的子节点)

appendChild(node):向子节点的末尾添加一个节点node,添加的节点必须是定义的或者是查找出来的,不能像jquery那样手动去写字符串。
例:
var newNode = document.createElement(“div”),
newText = document.createTextNode(“hello world!”);
newNode.appendChild(newText);
someNode.appendChild(newNode);

insertBefore(a, b):在子节点b前面添加一个a节点,如果b为null,则a添加至最后,和appendChild()方法一样

replaceChild(a, b): 用a节点来替换子节点b

removeChild(node):移除子节点node

cloneNode():可以传参数true,如果不传,则为浅复制,就是只复制这个节点,而不包括它的子节点,如果传了,则为深复制,会包含该节点以及它下面的所有的子节点

五,查找元素

getElementById() //ID
getElementsByTagName() //标签名,得到数组,如果传的是”*”,则表示全部
getElementsByName() //name值
getElementsByClassName() //IE5,6,7,8中无效,所以不要用这个

上面四个都是基于document对象来查找

someNode.nameItem(name) //根据name属性值来查找

六,特性值

getAttribute()
setAttribute()
removeAttribute()

可以直接给属性赋值来修改或者设置属性值,但是注意,这里的属性一定要是内部包含的(或者本身具备的属性),而不是自定义的属性
div.id = “aa”;
div.className = “cc”;

attributes属性:
每一个节点都有这个属性,该属性后可接一些方法(nodeName全部为大写)

someNode.attributes.getNamedItem(name); //获得nodeName为name的节点,注意,这里的attribute查找是在该节点的自身里面查找,而不是子节点。
等同于:someNode.attributes[name]; //简写

someNode.attributes.removeNamedItem(name); //移除nodeName为name的节点

someNode.attributes.setNamedItem(node); //设置一个新的节点,这个用的比较少,还是用setAttribute()比较好

七,创建元素
document.createElement() //元素节点
document.createTextNode() //文本节点

八,Text类型(所有的方法都是基于文本节点,offset、count都是数字,text是字符串)

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结束的文本字符串

normalize():父节点使用这个方法,将内部的文本子节点全部合并成一个,就是字符串拼接

九,DOM操作技术

动态脚本:

function loadScript(url){
    var scriptNode = document.createElement(“script”);
    scriptNode.src = url;
    scriptNode.type = “text/javascript”;
    document.body.appendChild(scriptNode);
}

动态样式:

function loadScript(url){

var cssNode = document.createElement(“link”);
  cssNode.href = url;
  cssNode.type = “text/css”;
  cssNode.rel = “stylesheet”;
  document.getElementsByTagName(“head”)[0].appendChild(cssNode);
}

=======================

DOM扩展:

1,选择器

querySelector(): 类似于jquery的选择器,传入的css选择符
querySelectorAll(): 也是传入css选择符,只不过返回的是所有的匹配到的,一个数组,相当于NodeList

2,元素遍历:
由于之前的childNodes包含文本节点、注释节点等,不利于我们去查找获取子节点,所以推出了新的API:

childElementCount: 获取子节点的个数(只是元素节点)
firstElementChild: 第一个元素子节点
lastElementChild: 最后。。。。
previousElementSibling: 。。。。
nextElementSibling: 。。。。

3,classList属性(返回的是一个DOMTokenList对象,这个对象的结构类似于这样:
{
0: ‘class1’,
1: ‘class2’,
2: ‘class3’,
value: ‘class1 class2 class3’
}
):

elementNode(元素节点).classList.add(value); 添加value类,如果有就不添加了
elementNode(元素节点).classList.contains(value); 列表中是否存在这个值,如果存在返回true,否则false
elementNode(元素节点).classList.remove(value); 删除value类
elementNode(元素节点).classList.toggle(value); 如果列表中有,就删除,没有就添加

4,焦点
focus();
document.hasFocus(); 判断文档是否获得焦点

5,document.head,目前只有Safari 5和谷歌浏览器能用,所以还是用getElementsByTagName方法

6,自定义属性

html5为元素添加自定义属性的时候,一定要用 data- 开头,目的是提供语义信息,如果要访问这个属性值,不能用div.data-myname,会报错,只能用dataset,后面跟的是 data- 后面的myname,

div.dataset.myname = 123; 设置自定义属性值

7,innderHTML属性
返回子节点所有的内容,包括元素、注释、文本,但是IE和Opera返回的是大写的,所以不同的浏览器返回的也不同。不是所有的元素都有这个属性,像table相关的都不支持这个。

8,outerHTML
返回的是包含当前节点的所有内容

9,insertAdjacentHTML()方法,两个参数

element.insertAdjacentHTML(“beforebegin”, “<p>hello</p>”); //作为前一个同辈元素插入,就是同级
element.insertAdjacentHTML(“afterbegin”, “<p>hello</p>”); //作为第一个子元素插入,是在子节点里面
element.insertAdjacentHTML(“beforeend”, “<p>hello</p>”); //作为最后一个子元素插入,也是在子节点里面
element.insertAdjacentHTML(“afterend”, “<p>hello</p>”); //作为后一个同辈元素插入

10,scrollIntoView();    // 项目中遇到的做城市列表选择右侧的首字母跳转功能
someNode.scrollIntoView(); //如果不传参数或者传true,默认节点的顶端与视口顶部平行,如果传false,默认节点的底部与视口顶部平行

11,children属性:
和childNodes差别,children只包含元素子节点,IE9以后是只包含元素节点,IE8及之前也包含注释节点

12,contains(someNode):检测某节点下是否包含此子节点

DOM3级,类似方法:compareDocumentPosition(someNode),返回值
1 //无关
2 //居前(在参考节点之前)
4 //居后
8 //包含(给定节点是参考节点的祖先)
16 //被包含(是子节点,等同于contains)

13,innerText,Firefox不支持,
和innerHTML区别,一个返回的是纯文本,不包含元素节点标签等,一个返回的html代码,包含所有节点

14,outerText
div.outerText = “hello world”;
等同于
var text = document.createTextNode(“hello world”)
div.parentNode.replaceChild(text, div)

=======================

DOM2和DOM3

DOM1级主要定义的是HTML和XML文档的底层结构,DOM2和DOM3则在这个结构的基础上引入了更多的交互能力,也支持了更高级的XML特性。

获得浏览器视口大小:

function getViewPort(){

  if (document.compatMode == 'BackCompat') {

    return {

      width: document.body.clientWidth,

      height: document.body.clientHeight

    }

  } else {

    return {

      width: document.documentElement.clientWidth,

      height: document.documentElement.clientHeight

    }

  }  

}

监测某元素是否在顶部,如果不是就使其滚到顶部

function scrollToTop(element){
  if (element.scrollTop != 0) {
     element.scrollTop = 0
  }
}

JavaScript学习日志(五):DOM的更多相关文章

  1. javascript学习日志:前言

    javascript学习日志系列的所有博客,主要理论依据是<javascript权威指南>(犀牛书第6版)以及<javascript高级程序设计第三版>(红色书),目前js行业 ...

  2. JavaScript学习总结(五)——jQuery插件开发与发布

    jQuery插件就是以jQuery库为基础衍生出来的库,jQuery插件的好处是封装功能,提高了代码的复用性,加快了开发速度,现在网络上开源的jQuery插件非常多,随着版本的不停迭代越来越稳定好用, ...

  3. javascript学习 真正理解DOM脚本编程技术背后的思路和原则

    本文学习来源于<javascriptDOM编程艺术>仅作笔记 学会怎样才能利用DOM脚本编程技术以一种既方便自己更体贴用户的方式去充实和完善你们的网页. 循序渐进:从最核心的内容开始,逐步 ...

  4. javascript学习笔记之DOM与表单

    DOM(文档对象模型),猫叔了一个层次化的节点树 一.DOM NODE相关公共属性与方法 DOM中所有节点都实现了NODE接口,该接口的公共属性和方法如下: 1.节点基本属性 1)NodeType 节 ...

  5. JavaScript学习日志(六):事件

    这篇随笔,深恶痛绝,敲到快结束的时候,凌晨00:19,突然闪退,也不知道是Mac的原因还是chrome的原因,重新打开的时候,以为自动保存有效果,心想没关系,结果他么的只保存了四分之一,WTF?!!! ...

  6. javascript学习笔记之DOM

    DOM(文档对象模型),描述了一个层次化的节点树 一.DOM NODE相关公共属性与方法 DOM中所有节点都实现了NODE接口,该接口的公共属性和方法如下: 1.节点基本属性 1)NodeType 节 ...

  7. JavaScript 学习笔记-HTML&&DOM

    HTML DOM (文档对象模型) 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model). HTML DOM 模型被构造为对象的树. JavaScript 能够 ...

  8. 【JavaScript学习整理】DOM对象(location history screen navigator)

    DOM: 描述网页各个组成部分之间的关系. parentNode: 父节点 childNode: 子节点 firstChild: 第一个子节点 lastChild: 最后一个子节点 nextSibli ...

  9. JavaScript学习笔记之DOM介绍

    目录 1.简介 2.方法 3.属性 4.访问节点 5.修改节点 6.添加节点 7.删除节点 8.替换节点 9.改变 CSS 1.简介 文档对象模型(Document Object Model,DOM) ...

随机推荐

  1. MySQL系列(五)---总结MySQL中的锁

    MySQL中的锁 目录 MySQL系列(一):基础知识大总结 MySQL系列(二):MySQL事务 MySQL系列(三):索引 MySQL系列(四):引擎 概述 MyISAM支持表锁,InnoDB支持 ...

  2. 实现wpf的值转换器

    从数据库取出来的数据是1,2,3,4,5,不过要显示在控件上的,是1,2,3,4,5对应的string值,怎么办?wpf提供了很好的实现方法,那就是值转换器,我们需要做的是: 1.定义值转换类,继承I ...

  3. 利用Java随机,生成随机学生数据

    为模拟向数据库中大量插入学生数据(注:此处应该用PreparedStatement.batchUpdate等批处理提高效率)的情形,通过Java随机来生成学生数据. 一.要生成的学生数据 studen ...

  4. TestNG的组测试和组中组测试

    在编写测试的过程中,我们经常遇到只想执行个别或者某一部分/某一类型的测试用例,这时我们可以使用TestNG的分组测试方法 分组测试在配置时,TestNG执行的原则是:只保留最小集合进行执行 看代码: ...

  5. python基础===zip在python3中的用法

    name=["ad","kein","tom"] age=[23,45,22] tel=['157','139','167'] print( ...

  6. windows 注入 之 SetWindowHookEx

    前面的项目用到hook 还是在半年前,没想到最近有用到了,说实话,在项目组就提出,能用别的办法还是不要用这种,毕竟不太正道(感觉哈). 最近又牵扯到第三方对接的任务,没办法我又回到了HOOK上了.与窗 ...

  7. vbs系统监控

    vbs CPU 内存 硬盘监控脚本 On Error Resume Next Dim dwTotalMem, dwAvailMem, totalvolumn, freespace Const szRo ...

  8. HTML中直接写js 函数

    1.在HTML中直接写JS函数: <body onload="javascript:{window.location.href='http://www.baidu.com/'}&quo ...

  9. Selenium2 (python)

    包名:selenium 支持浏览器:Firefox,InternetExplorerDriver,OperaDriver,Chrome(要使用一种浏览器应下载相应的driver驱动) 一.基本命令 d ...

  10. Mac OS X 终端命令开启功能

    1.系统目录下显示资源库2.Finder显示隐藏文件3.Xcode卸载4.在Finder标题栏显示完整路径5.去掉窗口截屏的阴影6.强制Safari在新标签中打开网页7.改变截屏图片的保存位置 1.系 ...