1,DOM操作
1.1 概念
所谓DOM,全称Document Object Model 文档对象模型,DOM是W3C(World Wide Web Consortuum )标准,同时也定义了访问诸如XML和HTML文档的标准。DOM是一个使程序和脚本有能力动态地访问和更新文档的内容,结构以及样式的平台和语言中立的接口。
在文档中一切皆对象,比如 html,body,div,p等等都看做对象,那么我们如何来点击某个盒子让他变色呢?
DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。目的其实就是为了能让 js 操作 html 元素而制定的一个规范。
1.2 解析过程
HTML 加载完毕,渲染引擎会在内存中把HTML文档,生成一个DOM树,getElementByid 是获取内中DOM上的元素节点。然后操作的时候修改的是该元素的属性。
1.3 DOM(树)一切皆是节点
HTML 标签通过浏览器的解析后才会形成DOM树,此后HTML中的每个标签元素,属性,文本都能看做是一个DOM的节点,JavaScript都能通过DOM的提供的编程接口操作到每个节点,去了解浏览器的渲染机制能够帮助我们了解DOM。
上图可知,在HTML当中,一切都是节点,并且文本节点和属性节点属于元素节点:
- 元素节点:HTML标签
- 文本节点:标签中的文字(比如标签之间的空格,换行)
- 属性节点:标签的属性
整个html 文档就是一个文档节点,所有的节点都是Object。要注意:文本节点和属性节点就像这棵DOM树的果子,而元素节点就是树枝,所以,在操作时,一定要记顺枝摘果:得先取到元素节点,然后再操作子节点!!!
1.4 DOM可以做什么?
- 找对象(元素节点)
- 设置元素的属性值
- 设置元素的样式
- 动态创建和删除元素
- 事件的触发响应:事件源,事件,事件的驱动程序
1.5 清楚DOM的结构
- 获取文档对象:document
- 获取html:document.documentElement
- 获取body:document.body
1.6 常用DOM对象方法
下面列出常用的DOM对象方法:
操作代码如下:
<head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .active{ width: 200px; height: 200px; background-color:red; color: white; line-height:200px; text-align:center; font-size:30px; } </style> </head> <body> <div id="box"> <p id="active">this is p label</p> <p>this also is p label</p> </div> <!-- 动态的操作节点 1,创建节点 createElement() 2,插入节点 appendChild() insertBefore(newNode, node) 3,删除节点 removeChild() 4,替换节点 replaceChild(newNode, node) 5,创建文本节点 createTextNode()--> <script type="text/javascript"> var oDiv = document.getElementById('box'); // 创建节点 var newNode = document.createElement('p'); // 插入节点 oDiv.appendChild(newNode); // 设置属性 newNode.setAttribute('class', 'active'); // 创建文本 节点 var textNode = document.createTextNode('this is p label too'); oDiv.appendChild(textNode); var newNode1 = document.createElement('p'); var newNode2 = document.createElement('p'); oDiv.appendChild(newNode1); oDiv.appendChild(newNode2); // 创建innerHTML newNode1.innerHTML = '<a href="#">123.qq.com</a>'; newNode2.innerText = '<a href="#">123.qq.com</a>'; // 释放节点 // newNode2 = null; // 删除节点 // oDiv.remove(newNode2) </script>
效果如下:
在页面查看的html代码如下:
1.7 获取其他DOM(事件源)的四种方法
其实可以通过使用getElement系列方法,取到元素节点。
//方式一:通过id获取单个标签 var oDiv1 = document.getElementById("box1"); //方式二:通过 标签名 获得 标签数组,所以有s var oDiv2 = document.getElementsByTagName("div")[0]; //方式三:通过 类名 获得 标签数组,所以有s var oDiv3 = document.getElementsByClassName("box")[0]; //方式四:通过 name属性 获得id号,返回元素对象数组 var oDiv3 = document.getElementsByName("box")[0];
1.8 获取/设置元素的属性值
- 1,element.getAttribute(attrubuteName) // 括号传入属性名,返回对应属性的属性值
- 2,element.setAttribute(attributeName, attributeValue) // 传入属性名及设置的值
1.9 创建节点 Node
- 1,document.createElement('h3') // 创建一个html元素
- 2,document.createTextNode(string) // 创建一个文本节点
- 1,document.createAttribute('class') // 创建一个属性节点
1.10 增添节点
- 1,element.appendChild(Node) // 往element内部最后面添加一个节点,参数是节点类型
- 2,element.insertBefore(newNode, existingNode) // 在element内部中在existingNode前面插入 newNode
1.11 删除节点
- 1,element.removeChild(Node) // 删除当前节点下指定的子节点,删除成功返回该删除的节点,否则返回 null
2,事件
JS 是事件驱动为核心的一门语言。
2.1,事件三要素
事件源,事件,事件驱动程序
比如,我用手去按开关,灯亮了。这件事情里,事件源是:手。事件是:按开关。事件驱动程序是:灯的开和关。
再比如,网页上弹出一个广告,我点击右上角的 x,广告就关闭了。这件事情里,事件源是:x,事件是 onclick。事件驱动程序是:广告关闭了。
于是我们可以总结出:谁引发的后续事件,谁就是事件源。
- 事件源:引发后续事件的html标签
- 事件:js已经定义好了(如下图)
- 事件驱动程序:对样式和HTML的操作,也就是DOM。
代码书写步骤如下:
(1)获取事件源:document.getElementById(“box”); //类似与ios语言的UIButton *adBtn = [UIButton buttonWithType:UIButtonTypeCustom]; (2)绑定事件: 事件源box.事件onclick = function(){ 事件驱动程序 }; (3)书写事件驱动程序:关于DOM的操作
常用事件如下:
2.2,绑定事件的方法
直接绑定匿名函数
var oDiv = document.getElementById("box"); //绑定事件的第一种方式 oDiv.onclick = function () { alert("我是弹出的内容"); };
先单独定义函数,再绑定
var oDiv = document.getElementById("box"); //绑定事件的第二种方式 oDiv.onclick = fn; //注意,这里是fn,不是fn()。fn()指的是返回值。 //单独定义函数 function fn() { alert("我是弹出的内容"); };
注意上方代码的注释。绑定的时候,是写 fn,而不是 fn()。fn代表的是整个函数,而fn() 代表的是返回值。
行内绑定
<!--行内绑定--> <div id="box" onclick="fn()"></div> <script type="text/javascript"> function fn() { alert("我是弹出的内容"); } </script>
注意第一行代码,绑定时,是写的“fn()”,不是写的“fn”。因为绑定的这段代码不是写在js代码里的,而是被识别成了字符串。
2.3 JavaScript入口函数 window.onload()
此函数调用,是当页面加载完毕(文档和图片)的时候,触发 onload() 函数,文档先加载,图片资源后加载。
<script type="text/javascript"> window.onload = function () { console.log("james"); //等页面加载完毕时,打印字符串 } </script>
有一点我们要知道:js的加载是和html 同步加载的。因此,如果使用元素在定义元素之前,容易报错。这个时候onload事件就能派上用场了,我们可以把使用元素的代码放在 onload 里,就能保证这段代码是最后执行。
window.onload() 方法存在的问题
- 图片加载完成才调用onload方法,大家想个问题,如果现在用户访问JD商城页面,如果JD商城中的脚本文件在 window.onload() 方法调用,如果此时用户网速卡了,然后图片资源加载失败了,此时用户是做不了任何操作的,所以 window.onload() 方法有很大的问题。
- window.onload() 方法如果脚本中书写两个这样的方法,那么会有事件覆盖现象。
2.4 样式属性操作
所谓样式书写,就是对之前所讲解的 style 标签中的属性进行操作,并且通过 js 控制盒模型的属性(width,height等),控制盒子的显示隐藏(display: none|block),控制盒子的颜色切换(background:red|green)等等。
首先大家明确一点,你要操作文档对象了,要遵循事件三步走:
- 获取事件源
- 事件
- 事件驱动程序
<div id='box'></div> <script> window.onload = function(){ //1.获取事件源(事件对象,在文档中一切的标签都是对象) var oDiv = docuement.getElementById('box'); //2.事件 oDiv.onclick = function(){ //3.事件驱动程序 ps:记得 所有的style中使用的像margin-left //在js操作时都是用marginLeft属性进行赋值 oDiv.style.backgroundColor = 'yellow'; } }; </script>
2.5 值的操作
所谓值的操作,就是对前闭合标签和后闭合标签中间的文本内容的设置和获取。
- 双闭合标签:innerText或者innerHTML
- 单闭合标签:除了img标签,就剩 input了,使用value进行赋值
<div id='box'></div> <input type='text' value = 'james' id='user'> <script> window.onload = function(){ //1.获取事件源(事件对象,在文档中一切的标签都是对象) var oDiv = docuement.getElementById('box'); var oInput = docuement.getElementById('user'); //2.事件 oDiv.onclick = function(){ //3.事件驱动程序 oDiv.innerText = 'james';//仅仅设置文本内容 oDiv.innerHTML = '<h1>james</h1>';//将标签和文本内容一起解析 }; //2.事件 oInput.onclick = function(){ //3.事件驱动程序 只有有value属性的 才能使用value赋值和设置值 oInput.value = 'the king'; } }; </script>
2.6 标签属性操作
所谓标签属性,就是对标签中(字面上看到的)属性的操作。比如像每个标签中 id,class,title,img 标签的src属性和 alt属性,a标签的href属性,input标签中的name,type 属性等等。
<script> //window.onload页面加载完毕以后再执行此代码 window.onload = function () { //需求:鼠标放到img上,更换为另一张图片,也就是修改路径(src的值)。 //步骤: //1.获取事件源 //2.绑定事件 //3.书写事件驱动程序 //1.获取事件源 var oImg = document.getElementById("box"); //2.绑定事件(悬停事件:鼠标进入到事件源中立即出发事件) oImg.onmouseover = function () { //3.书写事件驱动程序(修改src) img.src = "image/jd2.png"; // this.src = "image/jd2.png"; } //2.绑定事件(悬停事件:鼠标进入到事件源中立即出发事件) oImg.onmouseout = function () { //3.书写事件驱动程序(修改src) img.src = "image/jd1.png"; } } </script>
3,节点操作
都是函数(方法)。JavaScript原生方法对DOM节点的操作包括:访问(查找),创建,添加,删除,替换,插入,复制,移动等。
总体代码总结如下:
//查找节点 document.getElementById("id");// 通过id查找,返回唯一的节点 document.getElementsByClassName("class");// 通过class查找,返回值为nodeList类型 document.getElementsByTagName("div");// 通过标签名查找,返回值为nodeList类型 //创建节点 document.createDocumentFragment();//创建内存文档碎片 document.createElement();//创建元素 document.createTextNode();//创建文本节点 //添加节点 var ele = document.getElementById("my_div"); var oldEle = document.createElement("p"); var newEle=document.createElement("div"); ele.appendChild(oldEle); //删除节点 ele.removeChild(oldEle); //替换节点 ele.replaceChild(newEle,oldEle); //插入节点 ele.insertBefore(oldEle,newEle);//在newEle之前插入 oldEle节点 //复制节点 var cEle = oldEle.cloneNode(true);//深度复制,复制节点下面所有的子节点 cEle = oldEle.cloneNode(false);//只复制当前节点,不复制子节点 //移动节点 var cloneEle = oldEle.cloneNode(true);//被移动的节点 document.removeChild(oldEle);//删除原节点 document.insertBefore(cloneEle,newEle);//插入到目标节点之前
下面我们一一学习。
3.1 创建节点
格式如下:
新的标签(元素节点) = document.createElement("标签名");
比如,如果我们想创建一个 li 标签,或者是创建一个不存在的 adbc 标签,可以这样做:
<script type="text/javascript"> var a1 = document.createElement("li"); //创建一个li标签 var a2 = document.createElement("adbc"); //创建一个不存在的标签 console.log(a1); console.log(a2); console.log(typeof a1); console.log(typeof a2); </script>
结果如下
3.2 插入节点
插入节点有两种方式,他们的含义是不同的。
方式1:
父节点.appendChild(新的子节点);
解释:父节点的最后插入一个新的子节点(属性节点,文本节点,元素节点)。
方式2:
父节点.insertBefore(新的子节点,作为参考的子节点);
解释:
- 在参考节点前插入一个新的节点。
- 如果参考节点为 null,那么他将在父节点最后插入一个子节点。
3.3 删除节点
格式如下:
父节点.removeChild(子节点);
解释:用父节点删除子节点。必须要指定是删除那个子节点。
如果我想删除自己这个节点,那么可以这样做:
node1.parentNode.removeChild(node1);
4,DOM操作的常用属性
4.1,获取当前元素的父节点
element.parentNode //返回当前元素的父节点对象
4.2,获取当前元素的子节点
//返回当前元素所有子元素节点对象,只返回HTML节点 element.chlidren //返回当前元素多有子节点,包括文本,HTML,属性节点。(回车也会当做一个节点) element.chilidNodes //返回当前元素的第一个子节点对象 element.firstChild //返回当前元素的最后一个子节点对象 element.lastChild
4.3,获取当前元素的同级元素
//返回当前元素的下一个同级元素 没有就返回null element.nextSibling //返回当前元素上一个同级元素 没有就返回null element.previousSibling
4.4,获取当前元素的文本
//返回元素的所有文本,包括html代码 element.innerHTML //返回当前元素的自身及子代所有文本值,只是文本内容,不包括html代码 element.innerText
4.5,获取当前元素的节点类型
//返回节点的类型,数字形式(1-12)常见几个1:元素节点,2:属性节点,3:文本节点。 node.nodeType
4.6,设置样式
//设置元素的样式时使用style,这里以设置文字颜色为例 element.style.color=“#eea”;
5,DOM的节点对象属性在各浏览器兼容性处理
5.1 innerHTML属性和innerText属性的区别
document 对象中有 innerHTML和 innerText 两个属性,这两个属性都是获取 document 对象的文本内容的,这两个属性的区别下面学习一下:
innerHTML 返回从 body元素开始所有的带标签的文本内容,并按照在HTML文档中的原格式显示
innerText 返回从 body 元素开始所有的文本内容,但是它去除HTML标签
同时,innerHTML 是所有浏览器都支持的,innerText 是IE浏览器和chrome 浏览器支持的,Firefox浏览器不支持。其实,innerHTML 是W3C 组织规定的属性;而innerText 属性是IE浏览器自己的属性,不过后来的浏览器部分实现这个属性罢了。
下面看个示例:
<body> <div id = "box1"> hello div 1 </div> <div id = "box2"> <p>hello p 1</p> <p>hello p 2</p> </div> <script type="text/javascript"> var oNode = document.getElementById('box1'); console.log(oNode.innerHTML); console.log(oNode.innerText); </script>
控制台打印如下:
通过示例,我们很清楚的发现,innerHTML是带有标签的文本内容,并且按照原格式显示(包括空格);而innerText只是内容,去除了HTML标签。
6,DOM操作的代码过程
6.1 先找树枝——获取元素节点
首先可以通过 getElement 系列的方法,取到元素节点。
下面展示一个代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .btn{ width: 200px; height: 200px; background-color:red; color: white; line-height:200px; text-align:center; font-size:30px; } </style> </head> <body> <div class="btn" id="box" onclick="add()"> hello dom </div> <script type="text/javascript"> window.onload = function(){ var oDiv = document.getElementById('box'); console.log(oDiv); <!-- 这个注释的代码 只能一次性的转换--> <!-- oDiv.onclick = function add(){--> <!-- // this指向了当前元素的节点对象--> <!-- console.log(this);--> <!-- this.style.backgroundColor = 'green';--> <!-- }--> var flag = true; oDiv.onclick = function add(){ if (flag){ this.style.backgroundColor = 'green'; flag = false; }else{ this.style.backgroundColor = 'red'; flag = true; } } } </script> </body> </html>
原图和效果图如下:
下面我们通过 name属性 ,标签属性和 class名,直接看一下怎么使用:
<div class="btn" id="box" onclick="add()"> hello dom </div> <script type="text/javascript"> var idName = document.getElementById("box"); var className = document.getElementsByClassName("btn"); var tagName = document.getElementsByTagName("div"); var name = document.getElementsByName("btn"); console.log(idName) console.log(className) console.log(tagName); console.log(name); </script>
结果如下:
注意:获取元素节点时,一定要注意:获取节点的语句,必须在DOM渲染完成后执行。可以有两种方式实现:1将JS代码写在BODY之后,2将代码写到 window.onload函数之中;后面三个 getElements,取到的是数组格式,不能直接添加各种属性,而应该去除数组的每一个单独操作:
getElementsByName("name1")[0].onclick = function;
6.2 再找树枝摘果子——查看设置属性节点
首先我们注意:查看和设置属性节点,必须先取到元素节点,才能使用;
下面看查看和设置属性节点函数:
1、查看属性节点:getAttribute("属性名");
2、设置属性节点:setAttribute("属性名","新属性值");
下面代码展示了查看和设置属性节点:
<head> <meta charset="UTF-8"> <title></title> <style type="text/css"> #box{ width: 200px; height: 200px; background-color:red; color: white; line-height:200px; text-align:center; font-size:30px; } </style> </head> <body> <p title="p的title">this is p</p> <ul id="classList"> <li class="'item">JavaScript</li> <li class="'item">CSS</li> </ul> <script type="text/javascript"> var oP = document.getElementsByTagName('p')[0]; console.log(document.getElementsByTagName('p')); console.log(oP); // 设置属性值 有一个必需的参数,这个节点对象的名字 var title = oP.getAttribute('title'); console.log(title); var className = oP.getAttribute('class'); console.log(className); // 设置属性值 oP.setAttribute("id", 'box'); </script> </body>
我们查看网页(包括控制台打印的结果):
查看网页源码,我们发现id被赋值了:
注意:这里 setAtribute()函数在IE浏览器中可能会存在兼容性问题。比如在IE中不支持这个函数设置 style onclick。等样式属性和事件属性。
我们推荐使用符号法替代上述函数:
eg:dom1.style.color="" dom1.onclick="" dom1.src=""
总结:js修改DOM节点的样式
1,使用setAttribute() 设置 class和style 属性,但是存在兼容性问题,不提倡;
div.setAttribute("class","cls1");
2,使用 .className直接设置class类,注意是className而不是 .class:
div.className = "cls1";
3,使用 .style 设置单个属性,注意属性名要用驼峰命名法:
div.style.backgroundColor = "red";
4,使用 .style 或者 .style.cssText 设置多个样式属性:
div.style = "background-color:red;color:yellow;" div.style = "background - color:red;color:yellow" √
6.3 查看设置文本节点
- .innerText:取到或设置节点里面的文字内容;
- .innerHTML:取到或设置节点里面的HTML代码;
- .tagName:取到当前结点的标签名。标签名全部大写
上面已经学习过,就不多学习。
7,DOM事件练习
在HTML中允许JavaScript对HTML事件作出反应。比如当用户点击一个HTML元素时,如需要在用户点击某个元素执行代码,请把JavaScript代码添加到HTML事件属性中。
HTML事件的例子练习:
- 当用户点击鼠标时
- 当网页已加载时
- 当图片已加载时
- 当鼠标移动到元素上时
- 当输入字段被改变时
- 当 HTML 表单被提交时
- 当用户触发按键时
也就是上面学习的事件常用函数的使用,下面一一练习:
7.1,当用户点击时,会改变<h1>元素的内容
代码如下:
<h1 onclick="this.innerHTML='hello!'">请点击这段文本!</h1>
原图及其效果:
7.2,下面会从事件处理程序中调用函数
代码如下(效果和上面相同,这里不展示)
<h1 onclick="changetext(this)">请点击这段文本!</h1> <script type="text/javascript"> function changetext(id){ id.innerHTML = 'hello!'; } </script>
7.3,向button元素分配一个onclick()事件(HTML事件属性)
如需向HTML元素分配事件,你可以使用事件属性。
<p >点击按钮来执行<b>displayDate()</b>函数。</p> <button onclick="displayDate()">试一试</button> <p id="demo"></p> <script type="text/javascript"> function displayDate(){ document.getElementById('demo').innerHTML = Date(); } </script>
我们点击按钮时,会执行名为 displayDate()的函数,效果如下:
7.4,为button元素分配onclick()事件(使用HTML DOM分配事件)
HTML DOM 允许你使用JavaScript向HTML元素分配事件,比如为button元素分配 onclick事件:
<p >点击按钮来执行<b>displayDate()</b>函数。</p> <button id="myBtn">试一试</button> <p id="demo"></p> <script type="text/javascript"> document.getElementById('myBtn').onclick=function(){ displayDate() }; function displayDate(){ document.getElementById('demo').innerHTML=Date(); } </script>
效果和上面相同,只不过名为 displayDate 的函数被分配给了 id='myBtn'的HTML元素,当按钮被点击时,将执行函数。
7.5,onload() 和 onunload() 事件
当用户进入或离开页面时,会触发 onload 和 onunload 事件
onload事件用于检查访客的浏览器类型和版本,以便基于这些信息来加载不同版本的网页。等待文档元素加载完成才会调用 onload() 事件。
onload和 onunload事件可用于处理 cookies。
代码如下:
<body onload="checkCookies()"> <p>弹出的提示框会告诉你浏览器是否已启用 cookie</p> <script type="text/javascript"> function checkCookies(){ if (navigator.cookieEnbaled==true) { alert('Cookies are enabled') }else{ alert('Cookies are not enabled') } } </script>
效果如下:
7.6,onchange事件
onchange事件常用于输入字段的验证。
下面的例子展示了如何使用 onchange。当用户改变输入字段的内容时,将调用 upperCase() 函数。
代码如下:
请输入你的英文名: <input type="text" id="fname" onchange="myFunction()"> <p>当你离开输入框时,被触发的函数会把你输入的文本转换为大写字母。</p> <script type="text/javascript"> function myFunction(){ var x=document.getElementById('fname'); x.value = x.value.toUpperCase(); } </script>
效果如下:
7.7,onmouseover和onmouseout事件
onmouseover 和 onmouseout 事件可用于在鼠标指针移动到或离开元素时触发函数。下面一个简单的 onmouseover-onmouseout 例子:
<style type="text/css"> .active{ width: 200px; height: 200px; background-color:red; color: white; line-height:200px; text-align:center; font-size:30px; } </style> </head> <body> <div class="active" onmouseover = 'mOver(this)' onmouseout='mOut(this)'> Mouse Over Me </div> <script type="text/javascript"> function mOver(obj){ obj.innerHTML = 'thank you'; } function mOut(obj){ obj.innerHTML = 'please move mouse cursor'; } </script>
效果如下:
7.8,onmousedown,onmouseup以及 onclick 事件
onmousedown、onmouseup 以及 onclick 事件是鼠标点击的全部过程。首先当某个鼠标按钮被点击时,触发 onmousedown 事件,然后,当鼠标按钮被松开时,会触发 onmouseup 事件,最后,当鼠标点击完成时,触发 onclick 事件。
代码如下:
<style type="text/css"> .active{ width: 200px; height: 200px; background-color:red; color: white; line-height:200px; text-align:center; font-size:30px; } </style> </head> <body> <div class="active" onmouseover = 'mDown(this)' onmouseout='mUp(this)'> Mouse Over Me </div> <script type="text/javascript"> function mDown(obj){ obj.style.backgroundColor = 'green'; obj.innerHTML = 'level to mouse'; } function mUp(obj){ obj.style.backgroundColor = 'blue'; obj.innerHTML = 'thank you '; } </script>
效果如下:
参考文献:https://www.cnblogs.com/Ry-yuan/p/6918155.html