概述

DOM(Document Object Model)文档对象模型,针对Html和XML的文档的对象API,是一项 W3C (World Wide Web Consortium) 标准。文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问、更新文档的内容、结构和样式。本文主要以一些简单的小例子,简述前端开发中,DOM的常见内容,仅供学习分享使用,如有不足之处,还请指正。

获取元素

DOM操作必须等待HTML文档加载完毕,才可以访问。html将标签节点,称为元素,如果存在元素,则返回html的javascript对象;如果不存在,则范围null。

通过ID获取元素

一个页面每个标签元素只能有一个id,表示唯一性。通过getElementById获取标签对应的JavaScript对象,建议区分大小写,以免浏览器之间不兼容。如下所示:

 var box = document.getElementById('A01');
document.write(box);//返回:[object HTMLDivElement]
document.write(box.tagName);//获取标签名:DIV
alert(box.innerHTML);//以文本形式获取标签的子内容
document.write(box.id);//返回元素的唯一ID,如:A01
document.write(box.title);//返回元素的标题属性
document.write(box.style);//返回元素的样式对象。输出:[object MSStyleCSSProperties]
document.write(box.style.color);//返回样式中设置的颜色属性,输出:blue
document.write(box.class);//class是保留字,不能使用,会报错,改用如下替代:
document.write(box.className);//返回样式名称,输出:box
//自定义属性,非IE不支持
box.innerHTML='玩转JS DOM';//重新赋值,会覆盖掉之前的内容

通过tagName获取元素

一个文档中,相同标签的元素可以有多个,所以通过getElementsByTagName获取的是对应标签的数组列表对象,如下所示:

 var box=document.getElementsByTagName('li');
document.write(box);//返回的是HTML列表数组集合对象,如:[object HTMLCollection]
document.write(box.length);//数组集合的长度,元素个数。从0开始
document.write(box.item(0));//返回:[object HTMLLIElement]
document.write(box[0].tagName);//返回对应标签 LI
document.write(box[0].innerHTML);//返回指定位置的纯文本内容

获取body

一个文档对象,也可以有多个body,所以通过tagName获取的也是数组列表对象,通过索引来访问具体内容。如下所示:

 var box =document.getElementsByTagName('body')[0];
document.write(box);//返回body对象,输出:[object HTMLBodyElement]

通过name获取元素

通过name获取元素,即通过元素的name属性来获取,且name不是唯一的,所以获取到的也是数组列表对象,如下所示:

 var box=document.getElementsByName('A');
document.write(box);//返回一个数组集合:[object HTMLCollection]
document.write(box[0]);//返回第一个元素:[object HTMLDivElement]
document.write(box[0].name);//对于IE,因为name在div中是不合法的属性,所以在IE:输出undefined ,其他则正常。
document.write(box[0].getAttribute('name'));//通过此方法在IE中可以获取name的值
document.write(box[0].getAttribute('style'));//IE中,返回的是:color: blue; 字符串
alert(box[0].getAttribute('style'));
document.write(box[0].getAttribute('class'));//IE浏览器不支持,其他可以
document.write(box[0].getAttribute('className'));//IE支持,其他不可以

设置属性

当获取元素后,如何给元素动态的设置属性呢,可以通过setAttribute方法来设置,如下所示:

 box[0].setAttribute('title','玩转,hexkj');//设置属性,两个参数:属性,属性值,会覆盖掉之前的值
box[0].setAttribute('align','center');
//设置自定义属性
box[0].setAttribute('test','hexkj');//也可以设置成功
box[0].removeAttribute('style');//移除属性

节点类型

DOM的节点类型,常见的有以下几种,如下所示:

元素节点

元素节点,即html标签元素节点,节点类型为1

 var box = document.getElementById('A01');
document.write(box.nodeName);//获取元素的标签名,和tagName一样,输出:DIV
document.write(box.nodeType);//获取元素的节点类型值,输出:1
document.write(box.nodeValue);//当前节点的value,div为空,只能获取当前节点,不能获取子节点的内容
document.write(box.innerHTML);//输出纯文本内容,是一个整体
document.write(box.childNodes);//子节点集合。返回:[object NodeList]
document.write(box.childNodes.length);//子节点的长度,输出:3

文本节点

文本节点,即只有文本内容的节点。

 //[object HTMLUListElement]UL节点 元素节点
//[object Text]文本节点 属性节点
for (var i=0;i<box.childNodes.length;i++) {
document.writeln(box.childNodes[i].nodeName);
document.writeln(box.childNodes[i].nodeType);
document.writeln(box.childNodes[i].nodeValue);
document.writeln('<br />');
}

属性节点

属性节点,即标签元素的属性,通过attributes来访问,如下所示:

 document.write(box.attributes.length);//属性节点的个数
document.write(box.attributes[0].nodeType);//属性类型 ,输出:2
document.write(box.attributes[0].nodeName);//属性名称,输出:title
document.write(box.attributes[0].nodeValue);//属性的值,输出:我是AO1
document.write(box.attributes['title'].nodeValue);//获取指定属性的值,本例输出:我是AO1

节点赋值

可以通过nodeValue和innerHTML进行赋值,但是在设置HTML时,会有差异,如下所示:

 box.childNodes[0].nodeValue='hello js dom!!!';//可以设置节点内容
box.childNodes[0].nodeValue='hello <strong>js</strong> dom!!!';//但是不能设置html内容:hello <strong>js</strong> dom!!!
box.innerHTML='hello <strong>js</strong> dom!!!';//可以设置html属性

获取相关节点

可以与节点相关的其他节点,如第一个节点,最后一个节点,父节点,等相关内容,如下所示:

 var box = document.getElementById('A01');
document.write(box.firstChild.nodeValue);//获取第一个节点
document.write(box.lastChild.nodeValue);//获取最后一个节点
document.write(box.ownerDocument);//返回当前的文档对象,输出:[object HTMLDocument]
document.write(box.ownerDocument.nodeName);//输出:#document
document.write(box.parentNode);//返回当前节点的父节点,本例输出:[object HTMLDivElement]
document.write(box.firstChild.nextSibling);//返回第一个节点的下一个同级节点,本例输出:[object HTMLUListElement]
document.write(box.lastChild.previousSibling);//返回最后一个节点的上一个同级节点,本例输出:[object HTMLUListElement]

忽略空白节点

空白节点对于HTML元素节点来说,是没有太大意义的,要如何去除呢,有两种方法都可以过滤掉空白节点,如下所示:

 //忽略空白字符
var box = document.getElementById('A02');
document.write(box.childNodes.length);//IE浏览器,输出是7,其中包括文本节点
document.write(box.childNodes[0]);//输出:[object Text] 表名第一个是文本节点,且内容为空
//以下函数过滤掉空白节点
function filterWhiteNodes(node){
var ret=[];
for (var i=0;i<node.length;i++) {
if (node[i].nodeType==3 && /^\s+$/.test( node[i].nodeValue)) {
continue;
} else{
ret.push(node[i]);
}
}
return ret;
}
document.write(filterNodes(box.childNodes).length);//输出:3
//输出空白文本节点
function removeWhiteNodes(node){
for (var i=0;i<node.length;i++) {
if (node[i].nodeType==3 && /^\s+$/.test( node[i].nodeValue)) {
node[i].parentNode.removeChild(node[i]);
}
}
return node;
}
document.write(removeWhiteNodes(box.childNodes).length);//输出:3
document.write(removeWhiteNodes(box.childNodes)[0].nodeName);//输出P标签

创建元素节点

通过createElement来创建元素,通过insertBefore来插入指定元素之前,如下所示:

 var p=document.createElement('P');//创建一个元素
var text=document.createTextNode('DDDDD');//创建一个文本节点
p.appendChild(text);//将文本节点附加一个子元素节点
box.appendChild(p);//将p元素节点,添加到box后面
box.insertBefore(p,box.childNodes[1]);//在第2个节点之前添加节点,其中可能会包括空白文本节点

如何插入到指定元素之后呢,如下所示:

 function insertAfter(newElement,targetElement){
//得到父节点
var parent=targetElement.parentNode;
if(parent.lastChild==targetElement){
//如果当前已经是最后一个节点,则直接添加
parent.appendChild(newElement);
}else{
parent.insertBefore(newElement,targetElement.nextSibling);
}
}
//在A02,SPAN之间,添加标签
insertAfter(p,box);

替换节点

通过replaceChild替换节点,如下所示:

 var span=document.getElementsByTagName('span')[0];
var em=document.createElement('em');
span.parentNode.replaceChild(em,span);

克隆节点

通过cloneNode方法克隆节点,有一个参数,true:深度克隆,包括内容 false:浅克隆,只克隆标签。

 //cloneChild克隆节点
var clone = box.cloneNode(true);//true:深度克隆,包括内容 false:浅克隆,只克隆标签
box.parentNode.appendChild(clone);

删除节点

通过removeChild来删除节点

 box.removeChild(box.firstChild);//删除第一个节点
box.parentNode.removeChild(box);//删除自己

DOM进阶

DOM本身的属性相关内容,如下所示:

 alert(document.nodeType);//输出9代表文档根
alert(document.nodeName);//输出:#document
alert(document.nodeValue);//null
alert(document.firstChild.nodeName);//第一个节点,输出html
alert(document.firstChild.nodeType);//输出:10
alert(document.documentElement);//获取文档的根元素,输出:[object HTMLHtmlElement]
alert(document.documentElement.nodeName);//输出:HTML
alert(document.documentElement.nodeType);//输出:1
alert(document.body);//获取body元素,输出:[object HTMLBodyElement]
alert(document.body.nodeType);//输出:1
alert(document.body.nodeName);//输出:BODY
alert(document.doctype);//获取文档类型 输出:[object DocumentType]
alert(document.doctype.nodeType);//输出:10
alert(document.title);//返回文档的标题
alert(document.URL);//返回文档的URL,必须是从服务器访问才生效
alert(document.referrer);//返回上一个url路径,即跳转到当前页面的url
alert(document.domain);//返回当前的域名
alert( document.images.length);//返回文档中图片的数组

合并节点

通过normalize方法来合并相邻的文本节点,为一个节点,如下所示:

 var box=document.getElementById("A01");
//合并相邻节点
var text1=document.createTextNode('Mr.');
var text2=document.createTextNode('Hex');
box.appendChild(text1);
box.appendChild(text2);
//alert(box.childNodes.length);//此时会发现A01的子节点数是2
box.normalize();//此方法用户合并相邻的文本节点为一个节点
alert(box.childNodes.length);//此时会发现A01的子节点数是1

分离节点

通过splitText方法,分离文本节点为两个相邻的节点,如下所示:

 //分离节点,原始:<div id="A01">Mr.Hex</div>
alert(box.firstChild.nodeValue);//输出Mr.Hex
box.firstChild.splitText(3);//分离前三个字符为一个节点
alert(box.firstChild.nodeValue);//输出Mr.

操作节点内容

 box.firstChild.deleteData(0,3);//删除节点中的字符,起始位置,删除个数
box.firstChild.insertData(0,'Hello,');//添加字符,起始位置,添加的字符串
box.firstChild.replaceData(0,2,'Miss');//替换字符串 起始位置,替换字符数,要替换的字符
alert(box.firstChild.substringData(0,2));//返回截取字符串,起始位置,截取字符个数

注释节点

注释节点即文档中的注释,以<!-- -->包裹,如下所示:

 var c = document.getElementsByTagName("!");
alert( c.length);//经测试IE11获取不到,长度为0

滚动到可见位置

当元素默认看不到时,需要手动滚动条才可以显示,可以通过scrollIntoView默认打开时,滚动到指定位置。如下所示:

 //浏览器文档呈现模式
alert(document.compatMode) ;//是否为通过标准模式,或混合模式 CSS1Compat
//<div id="A03" style="height: 800px;"></div>
box.scrollIntoView(true);//将节点设置为滚动可见节点,即会将滚动调试,滚动到显示节点的位置上

判断是否包含元素节点

判断一个元素是否包含指定元素,通过contains方法来判断。 如下所示:

 var box=document.getElementById("A02");
alert(box.childNodes.length);//会包含空白节点
alert(box.children.length);//不会包含空白节点和注释,和文本元素,不过children是非标准的
var box=document.getElementById("A01");
var p=box.children[0];
alert(box.contains(p));//返回true,是否包含节点
var box=document.getElementById("A02");
//var t=box.children[0];
alert(box.childNodes.length);//输出3
//alert(box.children.length);//输出0
var t=box.childNodes[1];
alert(t.nodeValue);//注释节点
alert(box.contains(t));//检测不出文本节点

兼容浏览器,因为有的浏览器不支持contains方法,如下所示:

 var box=document.getElementById("A01");
var p=box.children[0];
function contains(refNode,otherNode){
if(typeof refNode.contains !='undefined'){
return refNode.contains(otherNode);
}else if(typeof refNode.compareDocumentPosition !='undefined'){
return refNode.compareDocumentPosition(otherNode)>16;
}else{
//或者判断otherNode的递归判断父节点是不是refNode
var node=otherNode.parentNode;
do{
if(node==refNode){
return true;
}else{
node=otherNode.parentNode;
}
}while (node!=null)
}
}
alert(contains(box,p));//返回true

innerText和outerText的差异

innerText不会覆盖掉元素本身,outerText会在赋值时覆盖掉元素本身,如下所示:

 var box=document.getElementById("A01");
alert(box.innerText);//获取元素包含的文本,不包含html内容,且火狐不兼容
alert(box.textContent);//支持火狐的3.0
box.innerText='<strong>Hex Js</strong>';//赋值的时,会进行转义输出 alert(box.outerText);//获取内容和innerText一样
box.outerText='Mr. Hex';//但是赋值时会将元素删掉
alert(document.getElementById("A01"));//输出null alert(box.outerHTML);//获取内容和innerHTML一样
box.outerHTML='<strong>Hex Js</strong>';//但是赋值时会将元素删掉
alert(document.getElementById("A01"));//输出null

备注

己亥杂诗(清-龚自珍)

浩荡离愁白日斜,吟鞭东指即天涯。

落红不是无情物,化作春泥更护花。

JavaScript之DOM基础的更多相关文章

  1. JavaScript笔记:DOM基础

    一.什么是DOM DOM全称是document object model(文档对象模型).在网页上,组织页面(或文档)的对象被组织在一个树形结构中,用来表示文档中对象的标准模型就称为DOM.通俗的说D ...

  2. javascript中DOM基础知识介绍

    1.1.     基本概念 1.1.1.      DOM DOM Document Object Model 文档对象模型 就是把HTML文档模型化,当作对象来处理 DOM提供的一系列属性和方法可以 ...

  3. JavaScript DOM基础总结

    上个月在进行百度三面时候,面试官提问JavaScript DOM方法,我回答的有点少,前面太关注JavaScript 兼容性,框架方面,JavaScript 原生DOM基础没有记牢,心中有点遗憾.下来 ...

  4. 第一百一十三节,JavaScript文档对象,DOM基础

    JavaScript文档对象,DOM基础 学习要点: 1.DOM介绍 2.查找元素 3.DOM节点 4.节点操作 DOM(Document Object Model)即文档对象模型,针对HTML和XM ...

  5. JavaScript Dom基础-9-Dom查找方法; 设置DOM元素的样式; innerHTML属性的应用; className属性的应用; DOM元素上添加删除获取属性;

    JavaScript Dom基础 学习目标 1.掌握基本的Dom查找方法 domcument.getElementById() Domcument.getElementBy TagName() 2.掌 ...

  6. day29—JavaScript中DOM的基础知识应用

    转行学开发,代码100天——2018-04-14 JavaScript中DOM操作基础知识即对DOM元素进行增删改操作.主要表现与HTML元素的操作,以及对CSS样式的操作.其主要应用知识如下图: 通 ...

  7. JavaScript DOM 基础操作

    JavaScript DOM 基础操作 一.获取元素的六方式 document.getElementById('id名称') //根据id名称获取 document.getElementsByclas ...

  8. 二、JavaScript语言--JS基础--JavaScript进阶篇--DOM对象 控制HTML元素

    1.认识DOM 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树). 先来看看下面 ...

  9. Javascript DOM基础(一)概念

    Dom基础概念: <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" ...

随机推荐

  1. selenium之窗口滚动

    在这里和大家分享一下,selenium里面常用于处理窗口滚动的方法. location_once_scrolled_into_view 一般用于定位窗口底部元素.将窗口拉到最底部. window.sc ...

  2. 实验四:划分多个VLAN

    1.配置图 2.配置命令 Switch1.Switch2.Switch3的配置是一样的,如下所示:(可直接复制交换机,可以只配置一次) 通过命令查看配置: Switch0的配置如下: 通过命令查看tr ...

  3. node js 爬啊爬 记录 向 Scott 致敬 不要问为什么

    更优雅的异步编程: 定向爬取 :http://www.010xww.com/list/travel.htm 上代码: 打印一下http . 嗯 http 模块加载没问题 获取一个 文章列表: 终于把人 ...

  4. 个人第4次作业——alpha项目测试

    这个作业属于哪个课程 http://edu.cnblogs.com/campus/xnsy/GeographicInformationScience 这个作业的要求在哪里 https://www.cn ...

  5. xpath写法大全(适用于selenium、robotframework)

    1.//input[contains(@id, 'txttags')] 定位出来是个ID,但是ID后面的“102”是个随机数,所以用定位ID的方法就不行了,用firepath生成的xpath也会包括这 ...

  6. robotframework,移动端(小程序)自动化,通过屏幕坐标点击对应按钮的方法

    使用场景: 下图通过常规方法是定位不到“红色”这个按钮的 我们把鼠标放置上去,下图右侧会显示该点的坐标地址 然后使用click a point指令定位 click a point 64 743 dur ...

  7. 贪心+huffman编码+模拟退火+分治(一)

    (一)贪心 1.A - 今年暑假不AC “今年暑假不AC?” “是的.” “那你干什么呢?” “看世界杯呀,笨蛋!” “@#$%^&*%...” 确实如此,世界杯来了,球迷的节日也来了,估计很 ...

  8. 三、Django学习之单表查询接口

    查询接口 all() 查询所有结果,结果是queryset类型 filter(**kwargs) and条件关系:参数用逗号分割表示and关系 models.Student.objects.filte ...

  9. oracle的锁种类知识普及

    锁概念基础 数据库是一个多用户使用的共享资源.当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性. 加 ...

  10. 第四次作业:使用Packet Tracer理解RIP路由协议及ICMP协议

    0 个人信息 张樱姿 201821121038 计算1812 1 实验目的 理解RIP路由表的建立与更新 感受RIP坏消息传得慢 2 实验内容 使用Packet Tracer,正确配置网络参数,使用命 ...