JavaScript DOM编程

一、JavaScript DOM 概述

1.1、DOM概念

​ DOM(Document Object Model)即文档对象模型,针对HTML和XML文档的API(应用程序接口)。DOM描绘了一个层次化的节点树,可以添加、移除和修改页面的内容。

​ document用于表现HTML页面当前窗体的内容,document对象包含一个节点对象,此对象包含每个单独页面的所有HTML元素,这就是W3C的DOM对象。

​ 通过 JavaScript,您可以重构整个HTML文档。您可以添加、移除、改变或重排页面上的项目。要改变页面的某个东西,JavaScript就需要对HTML文档中所有元素进行访问的入口。这个入口,连同对HTML 元素进行添加、移动、改变或移除的方法和属性,都是通过文档对象模型来获得的(DOM)。

​ 在 1998 年,W3C 发布了第一级的 DOM 规范。这个规范允许访问和操作 HTML 页面中的每一个单独的元素。所有的浏览器都执行了这个标准,因此,DOM 的兼容性问题也几乎难觅踪影了。DOM 可被 JavaScript 用来读取、改变 HTML、XHTML 以及 XML 文档。

1.2、DOM的作用

​ 通过可编程的对象模型,JavaScript 获得了足够的能力来创建“动态的 HTML”。

JavaScript 能够改变页面中的所有 HTML 元素
JavaScript 能够改变页面中的所有 HTML 属性
JavaScript 能够改变页面中的所有 CSS 样式
JavaScript 能够对页面中的所有事件做出反应

静态页面和动态页面:

静态页面,即静态网页,是实际存在的,无需经过服务器的编译,直接加载到客户浏览器上显示出来。静态网页,随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了——除非你修改页面代码。常见的静态页面举例:.html扩展名的、.htm扩展名的。

所谓的动态网页,是指跟静态网页相对的一种网页编程技术。动态网页,页面代码虽然没有变,但是显示的内容却是可以随着时间、环境或者数据库操作的结果而发生改变的。

值得强调的是,不要将动态网页和页面内容是否有动感混为一谈。这里说的动态网页,与网页上的各种动画、滚动字幕等视觉上的动态效果没有直接关系,动态网页也可以是纯文字内容的,也可以是包含各种动画的内容,这些只是网页具体内容的表现形式,无论网页是否具有动态效果,只要是采用了动态网站技术生成的网页都可以称为动态网页。

我们现在学习JS写的动画效果,不叫动态页面,只能称之为静态页面的动态效果;

总之,动态网页是基本的html语法规范与Java、VB、VC等高级程序设计语言、数据库编程等多种技术的融合,以期实现对网站内容和风格的高效、动态和交互式的管理。因此,从这个意义上来讲,凡是结合了HTML以外的高级程序设计语言和数据库技术进行的网页编程技术生成的网页都是动态网页。

1.3、DOM总结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7KKxMEiR-1638872166556)(4_JavaScriptDOM编程_image\1573034437922.png)]

每个载入浏览器的 HTML 文档都会成为 Document 对象
​ ​ Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。
​ ​ Document 对象是 Window 对象的一部分。

当浏览器打开一个HTML文档时,浏览器解析HTML文档的标签,并创建表示这些标签的对象,这些对象就是HTML文档对象(标签元素对象)
​ ​ 文档对象即Document 对象,指的是一回事。

二、JavaScript节点与节点树

​ 当浏览器加载html页面的时候,会生成一个与之对应的Document对象。Dcoument对象又称之为文档对象;

​ 节点树: 加载HTML 页面时,Web 浏览器生成一个与之对应的树型结构,用来表示页面内部结构。DOM 将这种树型结构理解为由节点组成。

​ 下面这个图片表示一个文档树(节点树):

在这里插入图片描述

​ 从上图的树型结构,我们理解几个概念,html 标签没有父辈,没有兄弟,所以html 标签为根标签。head 标签是html子标签,meta 和title标签之间是兄弟关系。

​ 如果把每个标签当作一个节点的话,那么这些节点组合成了一棵节点树。经常把标签称作为元素,是同一个意思。

​ 常用节点分为三类:元素节点、文本节点、属性节点。

在这里插入图片描述

​ 根据 DOM,HTML 文档中的每个成分都是一个节点。

​ DOM 是这样规定的:

整个文档是一个文档节点。
每个 HTML 标签是一个元素节点。
包含在 HTML 元素中的文本是文本节点。
每一个 HTML 属性是一个属性节点。
注释属于注释节点。

三、JavaScript获取HTML标签元素

W3C提供了比较方便简单的定位节点的方法,以便我们快速的对节点进行操作,分别为:getElementById()、getElementsByClassName()、getElementsByName()、getElementsByTagName()、getElementsByTagNameNS(),其中常用的是下面四个方法。

3.1、常用方法介绍

getElementById()​ 返回对拥有指定 id 的第一个对象的引用,返回值Element。
getElementsByName()​ 返回带有指定名称的对象集合。返回值NodeList/HTMLCollection。
getElementsByTagName()​ 返回带有指定标签名的对象集合。返回值NodeList/HTMLCollection。
getElementsByClassName()​ 返回所有指定类名的对象集合。返回值NodeList/HTMLCollection。

getElementById()方法
​ 元素id属性表示一个元素节点的唯一性,不能同时给两个或以上的元素节点创建同一个命名的id。getElementById()方法,接受一个参数:获取元素的id。如果找到相应的元素则返回该元素,如果不存在,则返回null。

​ 比如获取id 为box 的元素节点:document.getElementById(‘box’);

​ 当我们通过getElementById()获取到特定元素节点时,访问它的一系列属性。

getElementsByName()方法
​ 元素name属性表示一个元素节点的名字,在同一个网页上,该属性并不要求唯一性,相同的name可以出现在多个标签上。

​ getElementsByName()方法可以获取相同名称(name)的元素,返回一个元素节点列表。

​ 可以通过下标来访问列表里面的元素。

示例:

document.getElementsByName('goods') //获取属性name的值为goods的所有元素
document.getElementsByName('goods')[0]//获取属性name的值为goods的第一个元素
document.getElementsByName('goods')[1]//获取属性name的值为goods的第二个元素

getElementsByTagName()方法
​​ getElementsByTagName()方法将返回一个元素节点对象,这个对象保存着所有相同元素名的节点列表。

示例:

document.getElementsByTagName('*'); //获取所有元素
document.getElementsByTagName('li'); //获取所有li 元素
document.getElementsByTagName('li')[0]; //获取第一个li元素
document.getElementsByTagName('li').length; //获取所有li元素的数目

​ 注:NodeList不仅可以通过下标访问指定标签元素,还可以通过length属性来查询列表节点数量.

重点: 该方法不仅可以通过document对象调用,还可以通过元素节点Element来访问

getElementsByClassName()方法
​ getElementsByClassName()方法返回文档中所有指定类名的元素集合,作为 NodeList 对象。参数为String,需要获取的元素类名,多个类名使用空格分隔(尽量不用);

示范代码1:

//获取包含 "example" 和 "color" 类名的所有元素:
var x = document.getElementsByClassName("example color");

示范代码2:

//查看文档中有多少个样式class="example"的元素(使用 NodeList 对的 length 属性):
var x = document.getElementsByClassName("example").length;

课堂代码:

//注意,下面的方法都只需要定义一个字符串类型的参数即可
//document.getElementById(id值)  根据id值获取到页面的指定元素,id是唯一的,返回值类型为Element  [HTMLXXXElement]
var div1Element = document.getElementById("div1"); //获取得到id值为div1的元素节点
// div1Element是元素节点,可以直接调用innerText
// alert(div1Element.innerText);

//document.getElementsByClassName(class值)  根据class属性值获取到页面的指定元素,返回值HTMLCollection
//通过getElementsByClassName获取到0个或多个
var allCp = document.getElementsByClassName("cp"); //获取到class值为cp的元素节点
//allCp不是元素节点,不能直接调用innerText
//我们可以把HTMLCollection当成是数组来处理,通过下标获取到指定的元素节点
// alert(allCp[2].innerText);

//document.getElementsByName(name值) 根据name属性值获取到页面的指定元素,返回值HTMLCollection
var allPp = document.getElementsByName("pp");
// alert(allPp[0].innerText);

//document.getElementsByTagName(标签名)  根据标签名获取到页面的指定元素,返回值HTMLCollection
var allP = document.getElementsByTagName("p"); //获取到页面中所有的p元素
// alert(allP[0].innerText);
// alert(allP.length);

//这四个方法,其中getElementById()/getElementsByName()只能通过document来调用

//但是getElementsByClassName()和getElementsByTagName()不仅可以通过document来调用,也可以通过元素节点来调用
//如果同document来调用这两方法,那么表示从文档中获取指定元素; 如果通过元素节点来调用,那么表示获取指定元素节点里面的指定元素;

//获取到div1里面的所有p标签元素,通过div1元素节点来调用和getElementsByTagName();
var div1AllP = div1Element.getElementsByTagName("p"); 
// alert(div1AllP.length);

//获取第二个div里面的class为cp的元素
    //document.getElementsByTagName("div")[1];
var allDiv = document.getElementsByTagName("div");
var towDiv = allDiv[1];

var div2Cp = towDiv.getElementsByClassName("cp");
// alert(div2Cp.length);


//Element  表示元素节点,代表的是一个元素节点
//HTMLCollection  表示元素节点集合,这个集合里面存储的都是元素节点,其实就是JS的数组,通过下标可以获取到指定的元素节点  
//NodeList    表示节点列表,节点里面里面存储的可能是各种各样的节点,其实就是JS数组

//扩展: 元素节点.innerText      获取到元素节点的文本内容

深入解析document.write():

​ write()​ 向文档写 HTML 表达式 或 JavaScript 代码。

​ 温馨提示:文档加载之后使用docunment.write()会覆盖原文档.
​ 除了直接输出文字外,它还支持带有HTML标签的输出内容。
​ 比如直接输出一个标题
​ 比如在输出内容中加入br换行标签
​ 比如直接输出列表项…

​ 注意事项:
​ 绝对不要在文档加载完成之后使用 document.write()。这会覆盖该文档。

3.2、Element和NodeList

​ 在 HTML DOM 中,Element 对象表示 HTML 元素。

​ Element 对象可以拥有类型为元素节点、文本节点、注释节点的子节点。

​ NodeList 对象表示节点列表,比如 HTML 元素的子节点集合。

​ 我们可通过节点列表中的节点索引号来访问列表中的节点(索引号由0开始)。

​ 节点列表可保持其自身的更新。如果节点列表或 XML 文档中的某个元素被删除或添加,列表也会被自动更新。

四、JavaScript操作标签元素的内容

在这里插入图片描述

​ element.innerHTML​ 设置或返回元素的内容。
​ 注:可以设置内容的时候加上标签,设置的标签会被浏览器解析

​ element.innerText​ 设置或返回元素的文本内容

​ element.tagName​ 返回元素的标签名。

innerText和innerHTML的区别:

​ innerText只能获取到文本内容,标签不会被获取; innerHTML获取到所有的内容,包含标签;

​ innerText设置的内容会被浏览器认为是纯文本;innerHTML设置的内容会被浏览器认为是HTML文本,如果存在标签会被解析;

五、JavaScript操作标签属性

5.1、HTML基本属性操作

​ element.属性名​ 设置或返回元素的指定属性。

​ element.className​ 设置或返回元素的 class 属性。
​​ 注:class属性的操作必须使用className

​ 注:Element对象使用 . 可以调用对象的各个属性

5.2、HTML方法操作属性

element.getAttribute()​ 返回元素节点的指定属性值。

​ getAttribute()方法将获取元素中某个属性的值。它和直接使用.属性获取属性值的方法有一定区别。

document.getElementById('box').getAttribute('id');//获取元素的id 值
document.getElementById('box').id; //获取元素的id 值
document.getElementById('box').getAttribute('mydiv');//获取元素的自定义属性值
document.getElementById('box').mydiv //获取元素的自定义属性值,非IE 不支持
document.getElementById('box').getAttribute('class');//获取元素的class 值

element.setAttribute()​ 把指定属性设置或更改为指定值
​ setAttribute()方法将设置元素中某个属性和值。它需要接受两个参数:属性名和值。如果属性本身已存在,那么就会被覆盖。

document.getElementById('box').setAttribute('align','center');//设置属性和值
document.getElementById('box').setAttribute('bbb','ccc');//设置自定义的属性和值

element.removeAttribute() 从元素中移除指定属性。
​ removeAttribute()可以移除HTML 属性。

document.getElementById('box').removeAttribute('style');//移除属性

​ 注:使用属性只能来获取和设置的是元素对象原始属性;使用方法可以用来设置元素对象自定义的属性;

六、JavaScript Document对象属性一览

​ document可以通过一下属性可以查询指定属性值或给指定属性赋值.

语法:
​ document.属性名 获取属性值
​ document.属性名 = 值; 给指定属性设置值

常用:
document.title //设置或读取文档标题等价于HTML的<title>标签

​ document.bgColor //设置或获取页面背景色

​ document.fgColor //设置或获取前景色(文本颜色)

​ document.linkColor //设置或获取未点击过的链接颜色

​ document.alinkColor //设置或获取激活链接(焦点在此链接上)的颜色

​ document.vlinkColor //设置或获取已点击过的链接颜色

document.cookie //设置和读出cookie

​ document.URL ​ //返回当前文档的 URL

document.images //获取页面上的<img>标签
​ images集合(页面中的图象):可以使用指定的元素访问其各个属性

​ 注:HTMLCollection 是一个集合,表示 HTML 元素的集合,它提供了可以遍历列表的方法和属性。
​ HTML DOM 中的 HTMLCollection 是“活”的;如果基本的文档改变时,那些改变通过所有 HTMLCollection 对象会立即显示出来。
​ HTMLCollection 对象是只读的,不能给它添加新元素,即使采用 JavaScript 数组语法也是如此。
​ HTMLCollection 对象和 NodeList 对象很相似

document.images.length      //对应页面上<img>标签的个数
document.images[0]          //第1个<img>标签
document.images.item(2)          //第3个<img>标签

​ forms集合(页面中的表单):可以使用指定的元素访问其各个属性

document.forms                 //对应页面上的<form>标签
document.forms.length          //对应页面上<form>标签的个数
document.forms[0]              //第1个<form>标签
document.forms[i].length       //第i-1个<form>中的控件数
document.forms[i].elements[j]  //第i-1个<form>中第j-1个控件

​ 注:除了forms/images,还有anchors/links/applets

​ anchors​ 返回对文档中所有 Anchor 对象的引用。(锚点)
​ links​ 返回对文档中所有 Area 和 Link 对象引用(超链接)。
​ applets​ 返回对文档中所有 Applet 对象的引用。

​ 注:Applet是采用Java编程语言编写的小应用程序,该程序可以包含在 HTML(标准通用标记语言的一个应用)页中,与在页中包含图像的方式大致相同。
含有Applet的网页的HTML文件代码中部带有<applet></applet>这样一对标记,当支持Java的网络浏览器遇到这对标记时,就将下载相应的小应用程序代码并在本地计算机上执行该Applet。

body 获取到body元素节点

head 获取到head元素节点

七、JavaScript获取层次节点

7.1、节点概念

​ 节点最常见的类型有元素节点、属性节点、注释节点和文本节点.

​ 节点的层次结构可以划分为:父节点与子节点、兄弟节点这两种。当我们获取其中一个元素节点的时候,就可以使用层次节点属性来获取它相关层次的节点
示例:

<div id="div1">
    <p>我是div中的p段落</p>
    <!--我是页面中的注释-->
    <div>我是div1中的子div</div>
    我是div的纯文本内容
    <h2>我是div中的h2标题标签</h2>
</div>

​ 上面的案例中: id为div1的元素是父节点,并且本身也是元素节点; div1里面的节点都是它的子节点;那么到底有多少个子节点呢?
​ 我们知道标签元素都是元素节点,纯文本内容就是文本节点,属性就是属性节点,注释就是注释节点,那么子节点看似是有5个,但是不是…我们进行深入研究。

​ childNodes​ 获取当前元素节点的所有子节点
​ 因为浏览器会把节点之间的空白符当作文本结点处理。

<div>
    javascript  
    <p>javascript</p> <!-- ←空白节点 -->
    <div>jQuery</div> <!-- ←空白节点 -->
    <h5>PHP</h5> <!-- ←空白节点 -->
</div>

​ 4个可见结点 + 3个看不出来的空白节点 = 7个节点
​ 注:文字节点之前之后的空格都算是内容的一部分。

​ 这些节点又有三个非常有用的属性,分别为:nodeName、nodeType 和nodeValue。

信息节点属性:

​ 节点类型​ nodeName​ nodeType​ nodeValue
​ 元素​ ​ 元素名称​ ​ 1​ ​ ​ null
​ 属性​ ​ 属性名称​ ​ 2​ ​ ​ 属性值
​ 文本​ ​ #text​ ​ ​ 3​ ​ ​ 文本内容
​ 注释​ ​ #comment​ ​ 8 ​ ​ ​ 注释内容

7.2、获取层次节点

​ firstChild​ 获取当前元素节点的第一个子节点

firstElementChild​ 获取当前元素节点的第一个元素子节点

​ lastChild​ 获取当前元素节点的最后一个子节点

lastElementChild​ 获取当前元素节点的最后一个元素子节点

​ ownerDocument​ 获取该节点的文档节点

parentNode​ 获取当前节点的父节点

​ previousSibling​ 获取当前节点的前一个同级节点

previousElementSibling​ 获取当前节点的前一个同级元素节点

​ nextSibling​ 获取当前节点的后一个同级节点

nextElementSibling​ 获取当前节点的后一个同级元素节点

​ attributes​ 获取当前元素节点的所有属性节点集合

childElementCount​ 获取当前节点的元素节点的个数

children​ 获取当前节点的所有元素子节点

​ childNodes 获取当前节点的所有子节点

八、JavaScript操作节点

​ 1、createElement()​ 创建一个元素节点

document.createElement(‘标签名’)
document.createElement('p'); //创建一个元素节点,这里写字符串标签名

​ 2、appendChild()​ 将新节点追加到子节点列表的末尾

元素节点.appendChild(‘节点’)
var box = document.getElementById('box'); //获取某一个元素节点
var p = document.createElement('p'); //创建一个新元素节点<p>
box.appendChild(p); //把新元素节点<p>添加子节点末尾

​ 3、createTextNode()​ 创建一个文件节点

document.createTextNode(‘文本值’)
var text = document.createTextNode('段落'); //创建一个文本节点
p.appendChild(text); //将文本节点添加到子节点末尾

​ 4、insertBefore(新节点,已有节点) 可在已有的子节点前插入一个新的子节点.
​ 父节点.insertBefor(新节点,已有节点)
​ old节点的父节点.insertBefore(new,old);
​ 需要注意的是insertBefore()方法可以给当前元素的前面创建一个节点,但却没有提供给当前元素的后面创建一个节点。

function insertAfter(newElement, targetElement) {
    //得到父节点
    var parent = targetElement.parentNode;
    //如果最后一个子节点是当前元素,那么直接添加即可
    if (parent.lastChild === targetElement) {
        parent.appendChild(newElement);
    } else {
        //否则,在当前节点的下一个节点之前添加
        parent.insertBefore(newElement, targetElement.nextElementSibling);
    }
}

​ 5、repalceChild()​ 可将某个子节点替换为另一个。
​ ​ 父节点.insertBefor(新节点,旧节点)

parentDiv.replaceChild(p,box); //把<div>换成了<p>

​ 6、cloneNode()​ 复制节点
​ ​ 元素节点.cloneNode(Boolean)
​ ​ 可选。该方法将复制并返回调用它的节点的副本。如果传递给它的参数是 true,它还将递归复制当前节点的所有子孙节点。否则,它只复制当前节点。

​ 7、removeChild()​ 删除父节点下指定的子节点
​ ​ 父节点.removeChild(子节点)

注:无论是插入到节点之前还是替换节点,节点本身自己不能操作,需要通过父节点来完成。

九、JavaScript操作表格

1、HTML DOM中,给table操作提供了一些属性和方法。table的独有属性和方法:

属性或方法说明
caption保存着<caption>元素的引用
tBodies保存着<tbody>元素的HTMLCollection 集合
tFoot保存着对<tfoot>元素的引用
tHead保存着对<thead>元素的引用
createTHead()创建<thead>元素,并返回引用
createTFoot()创建<tfoot>元素,并返回引用
createTBody()创建<tbody>元素,并且返回引用
createCaption()创建<caption>元素,并返回引用
deleteTHead()删除<thead>元素
deleteTFoot()删除<tfoot>元素
deleteCaption()删除<caption>元素

2、<tbody>/<thead>/<tfoot>/<table>元素添加的属性和方法

属性或方法说明
rows保存着<tbody>元素中行的HTMLCollection
deleteRow(pos)删除指定位置的行
insertRow(pos)向rows 集合中的指定位置插入一行,并返回引用

3、<tr>元素添加的属性和方法

属性或方法说明
cells保存着<tr>元素中单元格的HTMLCollection
deleteCell(pos)删除指定位置的单元格
insertCell(pos)向cells集合的指定位置插入一个单元格,并返回引用

十、JavaScript事件

10.1、事件介绍

​ JavaScript与HTML之间的交互是通过事件来实现的,事件就是用户或浏览器自身执行的某种动作,比如click、mounseover、load……,而响应事件的函数就叫做事件处理函数

​ 事件(Event)是JavaScript应用跳动的心脏 ,也是把所有东西粘在一起的胶水。当我们与浏览器中Web页面进行某些类型的交互时,事件就发生了。事件可能是用户在某些内容上的点击、鼠标经过某个特定元素或按下键盘上的某些按键。事件还可能是Web浏览器中发生的事情,比如说某个Web页面加载完成,或者是用户滚动窗口或改变窗口大小。
在这里插入图片描述

​ 事件发生常见情况:

当鼠标点击某个地方的时候,发生了…
当鼠标移入某个地方的时候,发生了…
页面载入完毕的时候,发生了…
当输入框获取光标的时候,发生了…
当输入框失去光标的时候,发生了…
当按下某个键的时候,发生了…

​ 通过使用 JavaScript ,你可以监听特定事件的发生,并规定让某些事件发生以对这些事件做出响应。JavaScript 事件是由访问Web页面的用户引起的一系列操作,例如:用户点击。当用户执行某些操作的时候,再去执行一系列代码。

​ 注意:事件通常与函数配合使用,当事件发生时函数才会执行。

10.2、事件三种使用方式

​ 事件一般是用于浏览器和用户操作进行交互。

​ 使用JavaScript有三种方法:内联(行内)、脚本和事件侦听;

10.2.1、内联方式

​ 这种模型是最传统简单的一种处理事件的方法。在内联模型中,事件处理函数是HTML标签的一个属性,用于处理指定事件。虽然内联在早期使用较多,但它是和HTML混写的,并没有与HTML分离。

//在HTML 中把事件处理函数作为属性执行JS代码
<div id="div1" onclick="this.style.background='blue'">我是div里面的文字</div>
//在HTML 中把事件处理函数作为属性执行JS 函数1
<div id="div1" onclick="myfun1(this)">我是div里面的文字</div>
<script>
    function myfun1(t){t.style.background='blue'}
</script>

​ 注:内联可以给一个元素定义的同一事件添加多个执行函数

<div id="div1" onclick="myfun1(),myfun2()">我是div里面的文字</div>

10.2.2、脚本方式

​ 由于内联模型违反了HTML 与JavaScript 代码层次分离的原则。为了解决这个问题,我们可以在JavaScript 中处理事件。这种处理方式就是脚本模型。

1.获取元素,给其加事件,事件赋值某个函数名,切记不加括号.

var div1 = document.getElementById("div1");
function myfun1(){
  div1.style.background="blue";
}
div1.onclick=myfun1;

2.匿名函数写法:

  var div1 = document.getElementById("div1");
  div1.onclick=function(){
    div1.style.background="blue";
}

​ 通过匿名函数,可以直接触发对应的代码。

​ 注:脚本形式不可以给同一事件添加多个执行函数;

10.2.3、事件监听(侦听)方式

​ JavaScript中定义了两个方法,用于添加事件和删除事件处理程序的操作:addEventListener()和removeEventListener()。

​ 所有DOM 节点中都包含这两个方法,并且它们都接受3个参数;事件名、函数、冒泡或捕获的布尔值(true 表示捕获,false 表示冒泡)。

​ 标准的浏览器使用W3C定义的addEventListener函数绑定,函数定义如下:

​ function addEventListener(string eventType, function eventFunc, [bool useCapture=false])
​ ​ 参数eventType: 事件名称,如click、mouseover…
​ ​ eventFunc: 绑定到事件中执行的动作
​ ​ useCapture: 指定是否绑定在捕获阶段,true为是,false为否,默认为false。
​ 注:事件冒泡和捕捉在之后讲!

document.addEventListener('click', function () {
  alert('document');
});

box.addEventListener('click', function () {
  alert('Lee');
});

事件侦听的优势:

​ 1、当同一个对象使用.onclick的写法触发多个方法的时候,后一个方法会把前一个方法覆盖掉,也就是说,在对象的onclick事件发生时,只会执行最后绑定的方法。

​ 而用事件监听则不会有覆盖的现象,每个绑定的事件都会被执行。如下:

window.onload = function(){

  var btn = document.getElementById("yuanEvent");
  btn.onclick = function(){
    alert("第一个事件");
  }

  btn.onclick = function(){
    alert("第二个事件");
  }

  btn.onclick = function(){
    alert("第三个事件");
  }
}

最后只输出:第三个事件,因为后一个方法都把前一个方法覆盖掉。

原生态的事件绑定函数addEventListener:
function eventOne (){
  alert("第一个监听事件");
}

function eventTwo(){
  alert("第二个监听事件");
}

window.onload = function(){
  var btn = document.getElementById("yuanEvent");
  //addEventListener:绑定函数
  btn.addEventListener("click",eventOne);
  btn.addEventListener("click",eventTwo);
}
输出:第一个监听事件和第二个监听事件

​ 2、采用事件监听给对象绑定方法后,可以解除相应的绑定,写法如下:

var eventOne = function(){
  alert("第一个监听事件");
}
function eventTwo(){
  alert("第二个监听事件");
}
  var btn = document.getElementById("yuanEvent");
  btn.addEventListener("click",eventOne);
  btn.addEventListener("click",eventTwo);
  btn.removeEventListener("click",eventOne);
输出:第二个监听事件
解除绑定事件的时候一定要用函数的句柄,把整个函数写上是无法解除绑定的。

10.3、常用的事件类型(重点)

​ JavaScript 可以处理的事件类型为:鼠标事件、键盘事件、HTML 事件。

​ 所有的事件处理函数都会都有两个部分组成,on + 事件名称,例如click 事件的事件处理函数就是:onclick。在这里,我们主要谈论脚本的方式来构建事件,违反分离原则的内联,我们忽略掉。

鼠标事件:

1、click:当用户单击鼠标按钮[鼠标左键]
​ input.onclick = function () {alert(‘Lee’);};

2、dblclick:当用户双击主鼠标按钮时触发。[鼠标左键]
​ input.ondblclick = function () {lert(‘Lee’);};

3、mousedown:当用户按下了鼠标还未弹起时触发[鼠标左右键]。
​ input.onmousedown = function () {alert(‘Lee’);};

4、mouseup:当用户释放鼠标按钮时触发[鼠标左右键]。
​ input.onmouseup = function () {alert(‘Lee’);};

5、mouseover:当鼠标移到某个元素上方时触发。
​ input.onmouseover = function () {alert(‘Lee’);};

6、mouseout:当鼠标移出某个元素上方时触发。
​ input.onmouseout = function () {alert(‘Lee’);};

7、mousemove:当鼠标指针在元素上移动时触发。
​ input.onmousemove = function () {alert(‘Lee’);};

键盘事件:

1、keydown:当用户按下键盘上任意键触发,如果按住不放,会重复触发。
​ onkeydown = function () {alert(‘Lee’);};

2、keypress:当用户按下键盘上的字符键触发,如果按住不放,会重复触发。
​ onkeypress = function () {alert(‘Lee’);};

3、keyup:当用户释放键盘上的键触发。
​ onkeyup = function () {alert(‘Lee’);};

​ 注:键盘事件一般用在可获取焦点的元素上或doument对象上

​​​ 在发生键盘事件时,键盘事件对象的keyCode 属性中会包含一个代码,与键盘上一个特定的键对应。

keypress 和 keydown 是有区别?
​ keypress 事件在用户按下并放开任何字母数字键时发生。但是系统按钮(例如:箭头键、功能键)无法得到识别。
​ keydown 事件在用户按下任何键盘键(包括系统按钮)时发生。

具体区别:

​​ 1.keydown 先于 keypress 发生。
​​ 2.keypress 无法系统按钮。
​​ 3.keydown 捕获的 keyCode 不区分字母大小,而 keypress 区分。

​​ keypress是在用户按下并放开任何字母数字键时发生。系统按钮(例如,箭头键和功能键)无法得到识别。

​​ keyup 是在用户放开任何先前按下的键盘键时发生。

​​ keydown 是在用户按下任何键盘键(包括系统按钮,如箭头键和功能键)时发生。

HTML常用事件:

1、load:当页面完全加载后在window 上面触发,或当框架集加载完毕后在框架集上触发。
​ window.onload = function () {alert(‘Lee’);};

2、select:当用户选择文本框(input 或textarea)中的一个或多个字符触发。
​ input.onselect = function () {alert(‘Lee’);};

3、change:当文本框(input 或textarea、select)内容改变且失去焦点后触发。
​ input.onchange = function () {alert(‘Lee’);};

4、focus:当页面或者元素获得焦点时在window 及相关元素上面触发。
​ input.onfocus = function () {alert(‘Lee’);};

5、blur:当页面或元素失去焦点时在window 及相关元素上触发。
​ input.onblur = function () {alert(‘Lee’);};

6、submit:当用户点击提交按钮在<form>元素上触发。

7、reset:当用户点击重置按钮在<form>元素上触发。

<form action="" onsubmit="myFun1()" onreset="myfun2()">
    <input type="text" name="userName" placeholder="请输入您的名字" > <br>
    <input type="submit" value="提交表单"><input type="reset" value="重置表单">
</form>
<script>
    function myFun1(){
        var userName = document.getElementsByTagName("input")[0].value;
        alert("hello,"+userName);
    }
    function myfun2(){alert("您重置了表单");}
</script>

8、resize:当窗口或框架的大小变化时在window 或框架上触发。

window.onresize = function () {
  alert('Lee');
};

9、scroll:当用户滚动时触发。

window.onscroll = function () {
  alert('Lee');
};

10、input: 用户输入触发

10.4、事件的冒泡和捕获

​ 什么是事件冒泡?

​​ 在一个对象上触发某类事件(比如单击click事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事件处理程序或者事件返回true,那么这个事件会向这个对象的父级对象传播,从里到外,直至它被处理(父级对象所有同类事件都将被激活),或者它到达了对象层次的最顶层,即document对象(有些浏览器是window)。

​​ 事件的冒泡:事件按照从最特定的事件目标到最不特定的事件目标的顺序触发。

​ 事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面。也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象。

在这里插入图片描述

​ 事件的捕获:与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。

​​ 事件捕获时,父级元素先触发,子级元素后触发。

​ 可以自己选择绑定事件时采用事件捕获还是事件冒泡,方法就是绑定事件时通过addEventListener函数,它有三个参数,第三个参数若是true,则表示采用事件捕获,若是false,则表示采用事件冒泡。

​ IE9以前的版本只支持事件冒泡,不支持事件捕获,它也不支持addEventListener函数,不会用第三个参数来表示是冒泡还是捕获,它提供了另一个函数attachEvent。

​ event.stopPropagation():阻止事件冒泡
​ event.preventDefault():阻止事件的默认行为

​ 阻止事件冒泡的方法,其中event是function中的参数;

10.5、事件流

​ 很久以前有个叫Netscape的姑娘,她制订了Javascript的一套事件驱动机制(即事件捕获)。后来又有一个叫“IE”的小子,这孩子比较傲气,他认为“凭什么我要依照你的规则走”,于是他又创造了一套自己的规则(事件冒泡)。再后来,有个叫W3C的媒婆,想撮合这两个孩子,将他们的特点融合在了一起,这下,事件产生的顺序变成:事件从根节点开始,逐级派送到子节点,若节点绑定了事件动作,则执行动作,然后继续走,这个阶段称为“捕获阶段(Capture)”;执行完捕获阶段后,事件由子节点往根节点派送,若节点绑定了事件动作,则执行动作,然后继续走,这个阶段称为“冒泡阶段(Bubble)”。

事件流是描述的从页面接受事件的顺序,当几个都具有相同事件的元素层叠在一起的时候,比如点击事件,那么你点击其中一个元素,并不是只有当前被点击的元素会触发事件,而层叠在你点击范围的所有元素都会触发事件。事件流包括两种模式:冒泡和捕获(捕捉)

​​ 事件冒泡,是从里往外逐个触发。事件捕获,是从外往里逐个触发。那么现代的浏览器默认情况下都是冒泡模型,而捕获模式则是早期的Netscape 默认情况

​ 当我们在 DOM 树的某个节点发生了一些操作(例如单击、鼠标移动上去),就会有一个事件发射过去。这个事件从 Window 发出,不断经过下级节点直到目标节点。在到达目标节点之前的过程,就是捕获阶段(Capture Phase)。所有经过的节点,都会触发这个事件。捕获阶段的任务就是建立这个事件传递路线,以便后面冒泡阶段顺着这条路线返回 Window。

​​ 监听某个在捕获阶段触发的事件,需要在事件监听函数传递第三个参数 true。

在这里插入图片描述

在这里插入图片描述

10.6、正则表达式

​ JavaScript的正则和java正则基本一致,只是在判断上有略微不同。

​ 语法:正则对象.test(字符串值)​ 如果符合要求,那么返回true,否则返回false

定义正则表达式对象: var reg = /^正则规则$/;

​​ 正则表达式相关内容:

1.字符类:

  • [abc]​ ​ 只能是a b c中的任意一个,也就是说[]里面的内容只能选择任意一个
  • [^abc​] ​ 任何字符,除了 a、b 或 c(否定)
  • [a-z]​ ​ a 到 z 中的任意一个
  • [a-zA-Z]​ ​ a 到 z 或 A 到 Z,两头的字母包括在内(范围)
  • [0-9]​ ​ 0-9之间的任意一个
  • [\u4e00-\u9fa5]​ 表示汉字的取值范围

2.预定义类:

  • \d​ 数字:[0-9]
  • \D​ 非数字: [^0-9]
  • \w​ 单词字符:[a-zA-Z_0-9]从大写字母小写字母 0-9和_之间的任意一个
  • \W​​ 非单词字符:[^\w]

3.数量类:

  • X{n}​ X,恰好 n 次
  • X{n,}​​ X,至少 n 次,大于等于n次
  • X{n,m}​ X,至少 n 次,但是不超过 m 次 ,大于等于n次,小于等于m次

4.逻辑类:

  • 与​ 并且
  • |​ 或者
  • ()​ 整体

5.条件:

  • (?![0-9]+$)​ 不能全是数字
  • (?![a-zA-Z]+$)​ 不能全是字母

常见正则规则:

用户名:必须由6-12位字母、数字组成,不能全是数字:

var userName_reg = /^(?![0-9]+$)[a-zA-Z0-9]{6,12}$/;

密码:必须由6-20位字母、数字、下划线组成,不能全是字母,也不能全是数字:

var userPwd_reg = /^(?![0-9]+$)(?![a-zA-Z]+$)\\w{6,20}$/;

昵称:必须由3-5位大写字母或2-5位汉字组成:

var nickName_reg = /^[A-Z]{3,5}|[\u4e00-\u9fa5]{2,5}$/;

性别:必须是男或女:

var sex_reg = /^[男女]$/;

年龄:必须在15-32之间的数值:

var age_reg = /^[1][5-9]|[2][0-9]|[3][0-2]$/;  

十一、JavaScript操作CSS样式

11.1、使用style访问样式(重点)

11.1.1、使用规则

​ 任何HTML元素标签都会有一个通用的属性:style,它会返回CSSStyleDeclaration对象。其语法格式为HTML元素.style.样式属性="值"。但是需要注意的是,JavaScript样式属性的写法和CSS写法有点不同,比如字体的大小,CSS代码为font-size,而JavaScript的代码为fontSize。

​ 以下两张表格都是JavaScript写样式属性的,注意和CSS代码的区别。

在这里插入图片描述

在这里插入图片描述

11.1.2、简单动画案例

效果1:点击改变div的颜色:

在这里插入图片描述

在这里插入图片描述

效果2:点击改变div的颜色,再次点击返回原样:

在这里插入图片描述

在这里插入图片描述

效果3:鼠标移入列表改变背景图片,移出恢复原样:

在这里插入图片描述

在这里插入图片描述

11.1.3、CSSStypeDeclaration的属性和方法

​ 正如上面提到的,HTML元素.style返回的是返回CSSStypeDeclaration对象,该对象中定义了一些属性和方法,可以在JavaScript中操作HTML元素的样式。

属性或方法说明
cssText访问或设置CSS 代码
length获取样式属性的数量
getPropertyValue(name)返回包含给定属性值的CSSValue 对象
item(index)返回指定位置CSS 属性名称
removeProperty(name)从样式中删除指定属性
setProperty(name,v)给属性设置为相应的值
<div style="font-size: 30px;" id="div1"></div>
<script>
  var div1Ele = document.getElementById("div1");

//  alert(div1Ele.style);
//  var cssStyle = div1Ele.style.cssText;//只能获取到style里面的属性
//  alert(div1Ele.style.cssText);

  div1Ele.style.cssText="width: 170px;height: 100px;background: red;font-size: 20px;";

  for(var i=0;i<div1Ele.style.length;i++){
    document.write(div1Ele.style.item(i)+"<br>"); //item获取CSSStypeDeclaration对象的每一个css属性名称
  }

  var heightVal = div1Ele.style.getPropertyValue("height");
//  lert(heightVal);100px
  
  div1Ele.style.removeProperty("font-size");

  div1Ele.style.setProperty("background","yellow");
</script>

11.2、使用className访问样式

​ 除了使用HTML元素.style.样式属性="值"来访问元素的样式外,这种方法只能对元素的样式一个一个的访问,如果样式设置比较多,就比较繁琐。还可以使用HTML元素.className=’类样式名’来设置元素的样式,这时可以把多个样式写在同一个类样式中。

案例: 用className实现菜单制作:

​ 实现思路:
​ 1、设置每一个li标签的初始状态。
​ 2、设置两个样式over和out,表示鼠标移至菜单和移出菜单的效果。
​ 3、统一为每一个li标签设置onmouseover事件和onmouseout事件效果

在这里插入图片描述

在这里插入图片描述

11.3、操作内部CSS样式(了解)

​ 之前我们使用style 属性,仅仅只能获取和设置行内的样式,如果是通过内联<style>或链接<link>提供的样式规则就无可奈何了,CSSStyleSheet 类型表示通过<link>元素和<style>元素包含的样式表。

通过代码document.getElementsByTagName('link')[0]; 获取一个HTMLLinkElement对象;

通过document.getElementsByTagName('style')[0];获取一个HTMLStyleElement。

这两个元素本身返回的是HTMLLinkElement 和HTMLStyleElement 类型,但CSSStyleSheet 类型更加通用一些。

通过sheet属性,可以把 HTMLLinkElement 和 HTMLStyleElement 对象转换为CSSStyleSheet 类型

常见CSSStyleSheet属性和方法:

属性或方法说明
disabled获取和设置样式表是否被禁用
cssRules样式表包含样式规则的集合
deleteRule(index)删除cssRules 集合中指定位置的规则
insertRule(rule, index)向cssRules 集合中指定位置插入rule 字符串,IE也可以用addRule(选择器名, 属性名:属性值, 索引)
<script>
  var img1=document.getElementById("img");

  var link = document.getElementsByTagName('link')[0];

  var sheet = link.sheet || link.styleSheet; //得到CSSStyleSheet

  sheet.insertRule("body {background-color:red}", 2);
  
  link.sheet.deleteRule(2);
</script>

​ 通过CSSRules 属性,我们可以获得样式表的规则集合列表。这样我们就可以对每个样式进行具体的操作了。

​ 通过cssRules[下标值]可以获取一个CSSStyleRule对象,通过访问CSSStyleRule对象来操作样式。

CSSStyleRule常用属性:

属性说明
cssText获取当前整条规则对应的文本,IE 不支持
selectorText获取当前规则的选择符文本
style返回CSSStyleDeclaration 对象,可以获取和设置样式
rule.cssText; //当前规则的样式文本
rule.selectorText; //#box,样式的选择符
rule.style.color; //red,得到具体样式值

11.4、操作内部或外部CSS样式

//精准操作内部和外部css样式 [这种方式就是获取到作用域元素的样式,然后再去操作]

//1. 获取到要操作样式的元素节点
var div1 = document.getElementById("div1"); //获取到div1元素节点

//2. 获取到作用与div1的所有样式 CSSStyleDecalaration
var div1Style = getComputedStyle(div1);   //window.getComputedStyle(元素节点)   获取到作用于这个元素节点的样式    
            
//只能获取到作用于元素的样式
document.write("div1的宽:"+div1Style.width+"<br>");
document.write("div1的字体大小:"+div1Style.fontSize+"<br>");

 // div1Style.width = "500px";

十二、动画效果

12.1、动态时间显示

在这里插入图片描述

需求:

  1. 当页面打开的时候,显示系统时间,并且每1s发生一次变化;
  2. 月日时分秒必须确保是2位数

12.2、随页面滚动的广告/侧边栏

在这里插入图片描述

亚马逊广告效果:

  1. 固定在页面底部,而且居中
  2. 点击右上角的X,可以关闭这个广告

在这里插入图片描述

document.documentElement.scrollTop 获取内容距离顶部的距离;

京东侧边栏回到顶部:

1.固定在右侧的一个小导航

2.当我们点击回到顶部的时候,可以过渡回滚到顶部(不能使用锚点,因为锚点是瞬间回到顶部)

12.3、点击显示菜单

在这里插入图片描述

需求如下:
1、每张图片都有一个与之对应的内容块,但是这些内容块都是隐藏的

2、当我们点击哪张图片,那么对应的内容块显示,但是其他的内容块隐藏

3、如果点击图片,它是隐藏的,则显示;如果是显示的则隐藏;

个人资料修改
修改资料
账号申诉

12.4、无缝滚动

需求:
1、四张图片的循环滚动

在这里插入图片描述

12.5、轮播图

在这里插入图片描述

常见轮播图分类:

  1. 普通轮播图(无过渡效果)
  2. 滑动轮播图
  3. 淡入淡出轮播图

12.6、tab切换

在这里插入图片描述

在这里插入图片描述

12.7、表单的客户端检测

在这里插入图片描述

12.8、省市级联

需求:
1、如果没有选择第一个,那么就第二个下拉框就没有内容
2、如果选择了第一个,那么显示第一个对应的内容

在这里插入图片描述

12.9、购物车操作

需求:
1、修改数量,下面的总价和节省金额发生变化
2、删除商品,提示是否删除,如果确定删除,那么才删除
3、删除之后更新总价和节省金额

在这里插入图片描述

12.10、模拟京东导航

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JTZ001

你的鼓励是我创作的最大动力?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值