一,基本定义
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. 云计算——Google App Eng…

    云计算--Google App Engine(一) 编者:王尚 2014.04.12 20:20 介绍:Google App Engine提供一套开发组件让用户轻松的在本地构建和调试网络应用,之后能让 ...

  2. springMVC两种方式实现多文件上传及效率比较

    springMVC实现 多文件上传的方式有两种,一种是我们经常使用的以字节流的方式进行文件上传,另外一种是使用springMVC包装好的解析器进行上传.这两种方式对于实 现多文件上传效率上却有着很大的 ...

  3. UICollectionView基本使用详解(OC)

    概述 UICollectionView是从iOS6开始引入使用的,目前应用非常广泛,很牛逼!老外的博客也是这么说的(传送门) ## 与UITableView的初步比较 UITableView应该是大家 ...

  4. Oracle sql 查询结果某一列字段合并成为一条数据

    使用oracle中自带函数  wmsys.wm_concat(需合并列的字段名) 用法如下: select code,name,wmsys.wm_concat(baname) from tab gro ...

  5. SpringBoot集成MyBatis的分页插件PageHelper(回头草)

    俗话说:好

  6. 读书笔记 之《Thinking in Java》(对象、集合)

    一.前言: 本来想看完书再整理下自己的笔记的,可是书才看了一半发现笔记有点多,有点乱,就先整理一份吧,顺便复习下前面的知识,之后的再补上. 真的感觉,看书是个好习惯啊,难怪人家说"书籍是人类 ...

  7. javascript+HTMl5游戏下载,开发一个都能月薪上万!舅服你

    HTML5时代已经到来许久了,你是否已经掌握了那么一点呢?今天小编给大家讲讲h5的折叠多设备.跨平台特性, 即用HTML5制作游戏.相比flash,HTML5更加灵活方便,随着浏览器技术的不断升级,H ...

  8. HDU 5543 Pick The Sticks:01背包变种

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5543 题意: 给你N个金条和一张长度为L的桌子.每个金条长度为a[i],价值为w[i].金条只能在桌子 ...

  9. Java 脚本引擎

    脚本引擎,就是一个编程语言的解释器,它的功能是解释执行用户的程序文本,将它译成计算机能执行的机器代码,完成一系列的功能. Java脚本引擎简单地说就是指Java提供的一组兼容操作各种脚本语言的的API ...

  10. iOS Notification – 远程通知

    本文讲解iOS的远程通知的基本使用,主要包括远程通知的类型,处理远程通知的场景,以及远程通知相关证书的配置等等. 一.APNs简介 APNs是苹果公司提供的远程通知的服务器,当App处于后台或者没有运 ...