学习JavaScript肯定是会遇到DOM操作,那么什么是DOM?它又是干嘛用的?这篇文章为你揭晓答案。

DOM是document object model的缩写,简称文档对象模型。

简单的说DOM是一套对文档的内容进行抽象和概念化的方法。我们可以把HTML文档模型化,当作对象来处理。

基本概念:

文档(document): HTML或XML文件。

节点(node):HTML文档中的所有内容都可以称之为节点,常见的节点有 元素节点 属性节点 文本节点 注释节点。

元素(element): HTML文档中的标签可以称为元素。

我们可以把一个HTML文档看做一个树形结构的对象,每一个标签会形成一个分支,这样就很容易理解了,如下图所示(图片来自w3school)。

知道了什么是DOM,肯定要问DOM有什么用?

DOM把HTML文档抽象成一个对象,肯定是为了方便使用JavaScript对HTML文档进行操作。DOM的作用就是为了对页面的结构内容进行操作,增加页面的动态特性。

好了,知道了DOM是干嘛用的,那么下面我们就学习如何进行DOM操作。

DOM操作主要分四个部分:

1、获取HTML节点及修改节点的属性

2、修改节点的样式

3、给节点绑定事件

4、节点操作

现在我们进行一一介绍

获取HTML节点与修改节点属性(包含表单元素)

DOM提供了三个获取节点的方法

方法一:

getElementById()   //根据id属性获取一个DOM对象,区分大小写,符合代码规范

通过id寻找一个元素(找到的是一个元素对象) 该方法只能被document对象调用(同一个文档中id不能重复)。

<div id="box"></div>

var box = document.getElementById(“box”);

方法二:

getElementsByTagName()    //根据标签返回多个DOM对象

通过标签名寻找一类元素(找到的是由元素对象组成的伪数组) 即可以被document调用,又可以被元素对象调用,被元素对象调用时表示在该元素对象内部执行查找。

通常针对多个标签,而且常会要用到for循环。

<div class="cl" id=“cl”>

    <div class="cl2"></div>

    <div class="cl2"></div>

</div>

<div class="cl"></div>

<div class="cl"></div>

var divs = document.getElementsByTagName("div");// 获取页面上所有div,divs是一个伪数组

var cl = document.getElementById("cl");// 获取id为cl的元素

var cl2s = cl.getElementsByTagName("div");// 获取cl元素下面所有的div标签,cl2s是一个伪数组

方法三:

getElementsByClassName()

通过类名寻找一类元素。

<div class="cl" id=“cl”>

    <p class="cl"></div>

    <span class="cl"></div>

</div>

<a class="cl"></a>

var cls = document.getElementsByClassName("cl");//获取到的是一个伪数组,里面装的是div p span a这四个元素对象

获得到了节点元素后我们就可以对节点元素的属性进行修改了。

DOM也提供了两个方法供我们获取和修改元素的属性值。

getAttribute()

getAttribute是一个函数,用于获取节点属性。它只有一个参数,即所需要查询的属性的名字。getAttribute不属于document对象,所有不能通过document对象调用,只能通过元素节点对象调用。

<div id="box" title=hello></div>

var box = document.getElementById(“box”);

console.log(box.getAttribute(“title”));

通过这个方法我们可以获取元素box的title属性值为hello。

setAttribute()

setAttribute也是一个函数,用于修改节点属性。与getAttribute用法类似,不同的地方在于它有两个参数,第一个为属性名,第二个参数为设定的属性值。

<div id="box" title=hello></div>

var box = document.getElementById(“box”);

console.log(box.setAttribute(“title”,”world”));

此时,box节点的title属性值已经变为world。

是不是感觉so easy.

其实还有更为简便的方法来修改属性值,直接使用点语法就可以了。

获取属性值

var 变量=box.title;

修改属性值

box.属性名 = “属性值”;

是不是感觉更简单呢。

在此我只举例了title属性,当然元素的属性还有很多,比如img标签的src属性,我们可以更改src属性来切换图片。还可以设置表单元素的属性

type可以设置input元素的类型;

value可以设置input元素的值;

checked可以设置input元素是否选中;

selected 可以设置下拉列表select中的option是否被选中;

disabled 可以设置input元素是否被禁用。

好了,属性的操作就到此为止。

获取节点与控制样式

关于节点的获取,上面只用到了三个方法,但是实际的项目HTML文档往往是很复杂的,

文档中所有的节点之间都存在这样或那样的关系。节点间的各种关系可以用传统的家族关系来描述,相当于把文档树比喻成家谱。在 HTML 中,可以将<body>元素看成是<html>元素的子元素;相应地,也就可以将<html>元素看成是<body>元素的父元素。而<head>元素,则可以看成是<body>元素的同胞元素,因为它们都是同一个父元素<html>的直接子元素。

首先我们来认识一下文档的层级结构,都有那些关系。

childNodes //子节点

children //子元素 虽然不是早期DOM标准中的方法,但是所有浏览器都支持

nextSibling //下一个兄弟节点

nextElementSibling //下一个兄弟元素 有兼容性问题

previousSibling//上一个兄弟节点

previousElementSibling //上一个兄弟元素 有兼容性问题

firstChild //第一个节点

firstElementChild //第一个子元素 有兼容性问题

lastChild //最后一个子节点

lastElementChild //最后一个子元素 有兼容性问题

parentNode //父节点 (一定是元素节点,所以无需处理)

所有获取节点相关属性都没有兼容性问题

注意:节点和元素不是同一个概念,文章开头说过,在此提醒一下。

获取子节点&子元素

  • childNodes: 获取指定元素的子节点,包括文本节点、元素节点等
  • children: 获取知道元素的子元素,只会获取元素节点。<ul id="list">
    <li><a href="javascript:void(0)">首页</a></li>

    <li><a href="javascript:void(0)">播客</a></li>

    <li><a href="javascript:void(0)">博客</a></li>

    <li><a href="javascript:void(0)">相册</a></li>

    <li><a href="javascript:void(0)">关于</a></li>

    <li><a href="javascript:void(0)">帮助</a></li>

</ul>
<script>
var ul = document.getElementById("list"); var lis = ul.getElementsByTagName("li"); //不关心层级 只找指定标签 //缺点: 如果内部还有li 也会找到 var nodes = ul.childNodes; //子节点 只找子级 //缺点: 除了我们想要的元素节点 还会获取到其他节点 var children = ul.children;//子元素 </script>

childNodes是DOM标准中规定的方法 获取节点的方式所有浏览器都支持
children不是DOM标准中规定的方法 因为很常用所有浏览器也都支持

在实际应用中,基本都是用children。

获取下一个兄弟节点

nextSibling:下一个兄弟节点

<input type="text" id="txtName">

<span></span>

<input type="text" id="txtPwd"><span></span>

<input type="button" id="btn" value="注册">

 <script>

var txt = document.getElementById("txtName");

var next = txt.nextSibling;// 获取到的是换行,空文本节点

var pwd = document.getElementById("txtPwd");

var next = pwd.nextSibling;// 获取到的是span元素,因为两个标签间没有其他节点

 </script>

获取下一个兄弟元素

nextElementSibling: 下一个兄弟元素

<input type="text" id="txtName">

<span></span>

 <script>

var txt = document.getElementById("txtName");

var next = txt.nextElementSibling;// 可以获取到span元素,只获取下一个兄弟元素,忽略非元素类型的节点

 </script>

获取父节点

parentNode: 获取元素的父节点,父节点肯定是一个元素

<div id = "box">
<img src="1.jpg" id="img"/>
</div>
<script>
var img = document.getElementById("img");
var parent = img.parentNode; //获取到的就是id为box的div元素
</script>

节点的获取我就先介绍到这里,关于兼容性的问题我会再做补充。

下面看一下如何进行节点的样式操作。

获取样式

  • 通过style只能获取行内样式
  • 获取的样式如果有单位,获取到的样式中也会带单位,类型是一个字符串

设置样式

1、通过style设置样式

  • 通过style设置的是行内样式
  • 如果样式需要单位,设置时也需要把单位带上
div{

    width:100px;

    height:100px;

}

<div id="box"></div>

var box = document.getElementById("box");

consloe.log(box.style.width);// 打印的是空字符串,因为只能获取行内样式

box.style.width = "300px";// 设置的是行内样式,而且这里必须带单位

console.log(box.style.width);// 打印的是“300px“/

2、通过类名设置样式

.b{

    width:100px;

    height:100px;

    background-color:red;

}

<div id="box"></div>

var box = document.getElementById("box");

// 通过类名设置样式 两种方式

box.className = "b";

box.setAttribute("class","b");

下面介绍事件绑定

绑定事件

事件三要素: 事件源 事件 事件处理程序

事件源.事件 = function(){

    // 事件处理程序

}

<img src="pic.jpg" id="img"/>

var img = document.getElementById("img");

img.onclick = function(){

   ...

}

img是事件源 事件是点击onclick 事件处理程序是函数体中的内容

下面为常用事件总结

属性

描述

Onblur

元素失去焦点。

Onchange

域的内容被改变。

Onclick

当用户点击某个对象时调用的事件句柄。

ondblclick

当用户双击某个对象时调用的事件句柄。

Onfocus

元素获得焦点。

onkeydown

某个键盘按键被按下。

onkeypress

某个键盘按键被按下并松开。

Onkeyup

某个键盘按键被松开。

Onload

一张页面或一幅图像完成加载。

onmousedown

鼠标按钮被按下。

onmousemove

鼠标被移动。

onmouseout

鼠标从某元素移开。

onmouseover

鼠标移到某元素之上。

onmouseup

鼠标按键被松开。

Onreset

重置按钮被点击。

Onresize

窗口或框架被重新调整大小。

Onunload

用户退出页面。

 

节点操作

节点操作就5种形式,克隆节点、添加节点、插入节点、移除节点和创建节点。

克隆节点 - cloneNode()

element.cloneNode(): 复制element节点

参数:布尔值,

true代表深层克隆,把当前节点和内部所有节点都复制一份

false代表浅层克隆,只复制当前节点

<div id="father">

    <div id="son"><div/>

</div>

var father = document.getElementById("father");

var son = document.getElementById("son");

var clone = son.cloneNode(true);// 把son这个div复制一份 复制出来的clone和son没有任何关系了

添加节点 - appendChild()

father.appendChild(son):将son节点追加到father内部的最后位置

<div id="father">
<div id="son"><div/>
</div>
<div id="demo"></div> var father = document.getElementById("father");
var demo = document.getElementById("demo");
var clone = demo.cloneNode(true);// 将demo克隆一份 father.appendChild(clone);// 将克隆出来的clone追加到father中 // 此时页面结构应该为 <div id="father"> <div id="son"><div/> <div id="demo"></div> </div> <div id="demo"></div>

//追加克隆节点对原节点不会产生影响

//如果代码如下 则会将demo节点直接移动到father节点下

father.appendChild(demo);// demo是页面上存在的节点

// 此时页面结构应该为

<div id="father">

<div id="son"><div/>

<div id="demo"></div>

</div>

插入节点 - insertBefore()

father.inserBefore(son1,son2): 将son1插入到father节点下的son2前面

<div id="father">

    <div id="son"><div/>

</div>

<div id="demo"></div>

var father = document.getElementById("father");

var son = document.getElementById("son");

var demo = document.getElementById("demo");

father.inserBefore(son,demo);//会直接将demo节点移动到father下的son前面       

插入克隆出来的节点也不会对原节点产生影响

移除节点 - removeChild()

father.removeChild(son): 将father下的son节点移除

<div id="father">

    <div id="son"><div/>

</div>

var father = document.getElementById("father");

var son = document.getElementById("son");

father.removeChild(son);// 直接将son节点删除

创建节点

document.write()

特点:只能被document调用,而且会覆盖页面上原有内容

document.write("<a href="http://www.baidu.com">百度</a>")

// 可以在页面上创建一个a标签,而且会覆盖页面上原有的所有内容

innerHtml()

特点:往页面添加html标签,可以限定范围

<div id="box"></div>

var box = document.getElementById("box");

box.innerHtml = "<a href="http://www.baidu.com">百度</a>";

// 追加后的结构为

<div id="box">

    <a href="http://www.baidu.com">百度</a>

</div>

createElement()

特点:动态创建标签,添加到页面需要配合appendChild使用。

<div id="box"></div>

var box = document.getElementById("box");
var input = document.createElement("input"); input.type = "text";
box.appendChild(input);

DOM的基本操作就到此为止了,如果对你有所帮助就给本文点个赞吧O(∩_∩)O

一篇文章搞懂DOM的更多相关文章

  1. 一篇文章搞懂高级程序员、架构师、技术总监、CTO从薪资到技能的区别

    一篇文章搞懂高级程序员.架构师.技术总监.CTO从薪资到技能的区别 http://youzhixueyuan.com/senior-programmers-architects-technical-d ...

  2. 一篇文章搞懂python2、3编码

    说在前边: 编码问题一直困扰着每一个程序员的编程之路,如果不将它彻底搞清楚,那么你的的这条路一定会走的格外艰辛,尤其是针对使用python的程序员来说,这一问题更加显著, 因为python有两个版本, ...

  3. 五分钟学Java:一篇文章搞懂spring和springMVC

    原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图 什么是Spring,为什么你要学习spring? 你第一次接触spring框架是在什么时候?相信很多人和我一样,第一次了 ...

  4. 一篇文章搞懂filebeat(ELK)

    本文使用的filebeat是7.7.0的版本本文从如下几个方面说明: filebeat是什么,可以用来干嘛 filebeat的原理是怎样的,怎么构成的 filebeat应该怎么玩 一.filebeat ...

  5. 一篇文章搞懂Android组件化

    网上组件化的文章很多,我本人学习组建化的过程也借鉴了网上先辈们的文章.但大多数文章都从底层的细枝末节开始讲述,由下而上给人一种这门技术“博大精深”望而生畏的感觉.而我写这篇文章的初衷就是由上而下,希望 ...

  6. 一篇文章搞懂Linux安全!

    Linux是开放源代码的免费正版软件,同时也是因为较之微软的Windows NT网络操作系统而言,Linux系统具有更好的稳定性.效率性和安全性. 在Internet/Intranet的大量应用中,网 ...

  7. InfluxDB从原理到实战 - 一篇文章搞懂InfluxDB时区

    0x00 简介    InfluxDB默认以UTC时间存储并返回时间戳,当接收到一个时序数据记录时,InfluxDB将时间戳从本地时区时间转换为UTC时间并存储,查询时,InfluxDB返回的时间戳对 ...

  8. 一篇文章搞懂Python装饰器所有用法

    01. 装饰器语法糖 如果你接触 Python 有一段时间了的话,想必你对 @ 符号一定不陌生了,没错 @ 符号就是装饰器的语法糖. 它放在一个函数开始定义的地方,它就像一顶帽子一样戴在这个函数的头上 ...

  9. 一篇文章搞懂android存储目录结构

    前言 前两天因为开发一个app更新的功能,我将从服务器下载的apk文件放在了内部存储目录(测试手机为小米,路径为:data/user/0/packagename/files)下面,然后安装的时候一直安 ...

随机推荐

  1. 关于SVN提交注释的问题

    如果客户端是TortoiseSVN的话,在客户端要设置的版本库上点右键,选择菜单TortoiseSVN--属性,新建属性,选择属性tsvn:logminsize,设置log的最短长度,然后提交.然后如 ...

  2. eclipse相关问题处理

    maven,新建的web工程下,没有resource跟test目录,做法:https://blog.csdn.net/gengjianchun/article/details/78679036 项目右 ...

  3. [日常] MySQL的预处理技术测试

    MySQL预处理技术:1.减轻服务器压力2.防止sql注入,把传递过去的危险字符也只当做参数处理3.将sql语句强制一分为二:第一部分为前面相同的命令和结构部分,第二部分为后面可变的数据部分基本使用 ...

  4. python 查询数据库返回的数据类型

    self.conn=MySQLdb.connect(host='localhost',port=3306, user='keystone', passwd='OptValley@4312', db=s ...

  5. python数据类型之集合

    对python中集合的理解 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 常用操作 s = set ...

  6. CentOS7系列--1.2CentOS7基本设置

    CentOS7基本设置 1. 查看相关信息 1.1. 查看系统信息 1.1.1. 查看系统位数 方法1: [root@centos7 ~]# uname -a Linux centos7.smartm ...

  7. CSS 几款比较常用的翻转特效

    第一个:360度翻转特效 <style>* { margin:0; padding:0; } .aa { width: 220px; height: 220px; margin: 0 au ...

  8. windows域渗透实战

    测试环境 域控: 192.168.211.130 已经控制的机器: 192.168.211.133 获取网络信息 查看机器的网络信息 ipconfig /all # 查看 网卡信息,获取dns 服务器 ...

  9. mysql 字符串函数、分组函数

    字符串函数 1.concat 函数 drop table test;create table test(id int(4), name varchar(10), sex char(2));insert ...

  10. ES6-Generator

    Generator 关键词:状态机,遍历器,同步方式写异步方法 基本概念 形式上,Generator函数是一个普通函数,但是有两个特征. function关键字与函数名之间有一个星号. 二是,函数体内 ...