客户端js(BOM&DOM)

一.BOM

1.认识BOM

什么是BOM

浏览器对象模型, Brower Object Model。

 

为什么需要BOM

我们的html,css都是在浏览器中进行解析的。

当我们想要实现一些特殊的效果,希望html和css的样式能够动态的改变。

js是一门浏览器端的脚本语言。

我们需要让js和html,css之间架起一个桥梁。就js能够与浏览器进行交互。在这种情况下:BOM就出现了。

 

浏览器对象模型使用JS有能力与浏览器进行“对话”。

 

 

BOM的组成

只要打开浏览器,就可以看到当前的窗口,它的构成如下:

 

当前窗口,就是window对象,而window对象,又包含了6个子对象:

ü  navigator

ü  frames

ü  location

ü  histroy

ü  docuemnt

ü  screen

 

2.window对象

双重角色:

在ECMAScript语言中的一个全局对象

js访问浏览器的一个接口。是一个对象,对象提供了一些属性和方法。

 

常用的一些window的方法:alert,confirm,prompt,settimeout,setinterval,cleartimeout,clearinterval,open,close

 

alert

弹出一个警告框,输出相应信息

window有一个特点:就是在调用window的方法时,可以把window省略掉。

 

confirm

弹出一个确认框,提醒用户是否确认当前的操作

如果点击了确定,那就进行相关操作。

如果点击了消失,那就什么也不做。

 

prompt

弹出一个输入框,允许用户输入内容

 

open

打开一个新窗口

 

具体应用:

执行代码效果

HTML结构:

JS行为:

 

3.frames对象

和HTML中的框架有关系(frameset frame iframe)

 

前提:如果页面没有frameset frameiframe,那么frames这个对象就是空的,没有意义。

 

 

父页面访问子页面,使用frames[‘frame的name值’]或frames[索引]

4.其它对象

location

地址,定位

在编程语言中,表示重定位

和a标签类比,a标签里面有个href属性,可以跳转到相应的页面

 

在实际开发中,有时候,我们不需要a标签,那么这个时候,location也能完成跳转功能:

注意:

1,a链接可以控制是在当前窗口打开,还是在新窗口打开

2,对于location只能在当前窗口打开

3,location还有一个reload方式,重新加载当前页面(了解)

 

history

表示历史

在js中,它是用来管理历史记录。如图:

有三个方法:

ü  forward()

ü  back()

ü  go()

 

 

go可以灵活指定是向前还是后退

go(1) 等价于 forward()

go(-1) 等价于 back()

 

注意:

在使用history时,必须保证history里面有历史纪录,否则肯定就不能使用。类似于浏览器前进和后退是一个灰色的状态,如图:

 

代码看课堂代码。

 

navigator,   screen

ü  navigator,在开发时,基本不用,只是在某些框架中的底层代码中才有使用

ü  在js中,screen没有任何作用

ü  不讲啦

二.DOM(重点)

需求:以开心网为例

 

当我们去点击立既注册时,需要去用户输入的信息进行一个验证?

 

要验证用户填写的信息是否正确?

ü  1,第一步,先得到相应的元素

ü  2,第二步,根据元素得到元素相应的内容,根据内容的不同,我们又分为两种情况,得到标签里面的内容,或得到标签中的属性。

 

以上需要如何满足?

这个时候,DOM出现了。

1.什么是DOM

DOM:Document Object Model  文档对象模型

 

DOM,文档对象模型,是一组用来描述脚本怎样与结构化文档进行交互和访问的web标准,它定义了一系列对象、方法和属性,用于访问、操作和创建文档中的内容、结构、样式和行为。

 

ü  JavaScript是ECMA的产物,只是一门语言而已

ü  DOM 则是W3C的标准,只是提供了一个处理页面的标准而已

ü  二者的完美结合,可实现web开发中的任何需求。正所谓 1+1>2

ü  好比演员和剧本的关系

 

DOM的发展历史:

2.DOM 0

W3C组织成立之前,DOM0就出现了,形成了一个所谓的标准。

 

ü  在W3C定义DOM标准之前,Netscape2支持一个简单的DOM,它提供了仅仅对于链接/图像和表单这样的特殊文档元素的访问。

ü  这一遗留的DOM被所有浏览器厂商采用,并且已经作为“0级别”DOM正式纳入到W3C标准中。它所有浏览器中有效。

ü  0级DOM其实就是定义的一些Document对象的属性和方法。

 

 

简单了解:

 

为什么还要了解这个DOM0呢?

DOM确实提供了一些简单的方式来获取页面中的元素,而且的有浏览器都支持DOM0.

 

3.DOM1

98年10月,W3C推出了DOM 1.0,作为推荐标准的第一个版本正式发布,主要包括两个子规范:

ü  DOM Core(核心部分),把xml文档设计为树形节点结构,并为这种结构的运行机制制订了一套规范化标准。同时定义了创建、编辑、操纵这些文档结构的属性和方法。

ü  DOM HTML,针对HTML文档、标签集合,以及与个别HTML标签相关的元素定义了对象、属性和方法。

 

重点是DOM Core,其中的核心思想:

ü  树形结构

ü  相关的属性和方法

 

(1).树形节点结构

 

对于如下这个文档:

 

其对形结构,如下:

更进一步了解,火狐浏览器有一个插件--DOMinpector, 可以查看DOM的详细结构

 

在DOM形成的树形结构中,都有哪些类型的节点?

实际上,在html树形结构中,每一个组成元素的都是节点(node),根据节点的信息不同,可以分成如下三种常见的节点:

ü  元素节点

ü  属性节点

ü  文本节点

 

 

完整的节点分类如下:

 

节点类型,测试如下:

 

注意:

属性节点,不会出现要树形结构模型中。

 

 

 

 

节点之间的关系:

既然所有的节点(元素节点和文本节点)都在树模型中,那么他们之间应该存在某种关系。

我们可以利用这个关系快速找到某个元素,然后进行操作。

 

针对如下代码,我们看一下,它们之间的关系:

 

关系如图:

 

我们可以通过它们之间的关系,来互相获取相应的目标元素:

ü  parentNode:父节点

ü  childNodes:得到的是个数组,我们可以通过索引来访问就可以

ü  firstChild:第一个孩子节点

ü  lastChild:最后一个孩子节点

ü  nextSibling: 下一个兄弟节点

ü  previousSibling:上一个兄弟节点

 

 

对于如下关系,代码如下:

 

切记一点:

如果使用了节点之间的关系,有的是要考虑空白节点(换行符)

 

一般是不使用节点关系去获取元素,原因有二:

ü  写起来费劲

ü  还可能会出错,不同的浏览器,处理机制不一样,ie对节点关系处理很正常

 

注意细节:

ü  1,有一个属性没有问题:parentNode

ü  2,针对某些兄弟节点,如果没有换行,使用nextSibling和prviousSibling也没有问题

ü  3,对于childNodes,firstChild, lastChild这三个节点关系不推荐使用

 

(2).DOM1 标准方法

在DOM中,可以使用节点之间的关系,来获取某个元素,但是关系关系使用的话,效果不太理想。

 

所以, DOM1,它提供了一些其它的标准方法用来获取页面中的元素,有两个:

ü  getElementById       通过元素的ID属性,来获取元素

ü  getElementByTagName   通过标签的名称来获取元素

 

 

基本使用:

 

 

 

 

注意细节:

1,在使用这两个标准方法时,对于代码的解析是自上到下。

解决办法:

1,将script代码放到body最后

2,在headk ,添加onload事件, 如下:

 

2,id属性是当前页面中是唯一的。 针对getElementByTagName,不管有多少个标签,得到的结果是一个数组。

4.选取文档元素

选取页面中的元素有如下几种方式:

ü  1,直接使用DOM0级方式

ü  2,节点之间的关系

ü  3,标准方法

 

代码如下:

 

问:还有没有其它的方式?

答案:有

 

getElementByName

根据name属性来获取元素

这个方法是可以获取到的,但是有兼容性问题,在ie9中不兼容。

 

getElementByClassName

也不推荐使用,有兼容性问题或不支持

 

h5中也有对应的新的方法,讲到h5时再说

 

 

5.DOM2 和 DOM3

DOM2增加了如下功能:

ü  对样式表的操作

ü  事件绑定

 

DOM3的变化:

ü   验证功能

6.操作元素

ü  创建  createElement

ü  插入  appendChild,insertBefore

ü  复制  cloneNode

ü  删除  removeChild

ü  替换  replaceChild

 

(1).创建

document.createElement(标签的名称)

      

 

 

 

 

 

 

注意:创建元素后,只能确保在当前的文档中有这么一个h1元素,但是它并没有补放到文档树里。

(2).插入操作

appendChild: 在父元素的最后来追加,追加的元素作为父元素的最后一个节点

insertBefore: 在父元素的某一个子元素之前插入新的元素

 

appendChild方法使用如下:

 

 

它就相当于将刚才孤立的h1,放到了树模型中,具体来说是作为body的最后一个元素进行放置:

 

 

insertBefore方法使用如下:

(3).删除

理解删除的过程:父元素可以删除子元素

针对如下结构:

 

我们需要删除h2元素,分析如下:

 

使用如下:

 

分析,上述方法我们可以获取父元素div和子元素h2.

它们之间存在父子关系,只需要找到子元素,通过parentNode找到父元素。

(4).复制

cloneNode: clone是克隆的意思

格式:要复制的元素.cloneNode(布尔值)

布尔值取值如下:

ü  false,表示浅拷贝,、、

 

 

(5).替换

 

在父元素中,将一个新的元素替换其子元素

格式:父元素.replaceChild(new,old);

 

基本使用:

在实际开发中,replaceChild使用较少。

 

 

 

(6).实际案例

案例:首页弹广告并消失

 

 

7.操作属性

元素 = 标签+属性+内容

 

在DOM树形结构中,节点主要有三种:

ü  元素节点

ü  属性节点

ü  文本节点

 

首先,需要注意的是:在我们的DOM中,属性节点并没有作为节点出现。在DOM树中,并没有列出属性节点。

所以,我们不能通过节点关系去找到属性节点,此路不通。

 

找其它出路:

属性节点比较特殊,是依赖于标签存在的,必须和某个具体的元素挂钩。

我们可以根据这个特点,找到我们想要的属性节点。

 

获取属性节点,有两种方式:

ü  直接使用对象.属性

ü  使用DOM中提供一个方法:getAttribute()

 

使用如下:

 

上述两种的区别:

1,直接使用属性,是DOM0级提出的方法,getAttribute()是DOM1级提出的标准方法

2,直接使用属性,只能获取HTML中定义的标准属性,如果是自定义属性,是不能获取,但是getAttribute()可以获取任何属性:

 

 

 

在实际开发中,如果是html中的标准属性,那么我们可以使用对象.属性来获取,也可以使用getAttribute()来获取,但是如果是自定义属性,只能通过getAttribute()来获取。

 

还有一个细节:

ü  如果属性名是关键字或保留字,使用属性获取时,需要换一个名称

ü  如果使用getAttribute(),则不会出现这个问题

 

基本上就有两个需要换名字:

ü  class  ---->   className (比较多)

ü  for   ----->   htmlFor (用的少)

 

设置

也有两种方式:

ü  直接使用属性的方式格式: 元素.属性 = 值

ü  使用标准方法setAttribute, 格式:元素.setAttribute(属性名,属性值)

 

 

删除

使用DOM中提供的标准方法,removeAttribute

格式:元素.removeAttribute(属性名)

 

实际开发中,获取和设置属性常用,删除属性不常用。

 

注意细节:

1,在DOM树中,属性节点并没有作为主要的嘉宾列席,无法通过父节点的childNode对象的列表中找到属性节点。

2,使用getAttribute和setAttribue可以读写自定义属性。

3,使用对象的属性来获取属性时,有些名称需要特殊对待,class--->className

for--->htmlFor

 

 

小星星评分案例:

 

最终要达到的效果:

 

分析,总共用到了4种图片:

 

搭建HTML结构如下:

 

显示效果如下:

 

最终js代码如下:

 

 

8.操作文本

在DOM树形结构中,所有元素的内容都是一个文本节点。

 

如何获取文本节点?

只要能获取元素节点,就可以获取文本节点。

 

 

 

文本节点和文本节点中的内容不是一个概念,我们是要得到文本节点的内容,然后对内容进行操作,这样才有意义。得到文本节点本身是没有用的,在开发中,我们真正关心是的节点中的内容。

 

如何得到文本节点的内容?

 

方式一:通过文本节点的nodeValue属性获取

这种方式,效率很低,一般不用。

 

方式二:innerHTML, 是IE浏览器提出的,直接可以获取元素中的内容

 

innerHTML功能比较强大,除了可以得到节点的内容之年,它还可以设置内容:

 

innerHTML也可以进行设置:

 

createTextNode(了解)  :创建文本节点

 

9.操作表格(了解)

针对表格操作,完全可以使用DOM中标准方法来完成。

由于表格操作涉及到的标签较多,所以操作相对比较麻烦。

 

W3C, 针对表格操作又提供了一个新的方式,专用于操作表格。

 

案例:创建一个两行两列的表格,分别用传。统的方式和新方式来实现

 

传统的方式:

 

新的方式:

 

对于表格的操作,在开发中,并没有那么频繁。了解就好。

 

10.DOM总结

D :

Document,文档,说白了就是我们的HTML文档本身

 

O:

Object, 对象,有具体的操作中,我们使用了大量的对象,比如docuemnt, element(具体的每一个标签对应的就是一个对象),利用对象的属性和方式,完成相应的操作。

 

M:

Model,模型,就是树模型,当页面载入完毕之后,就会构建我们的树模型,在构建树模型的时候,将文档中的元素,转成了结构中的对象。

 

三.脚本化CSS

换句话说,就是通过js去操作css

1.脚本化行内样式

如何使用js来控制行内样式。

所谓的行内样式,说白了,就是元素的style属性。

说白了,就是操作元素的属性, 只不过这里的属性是style. 但是style本身比较特殊,它本身也是个对象。里面有很多属性.

 

针对这样的情况,一般我们是去掉-,然后采用小驼峰命名法:

 

获取行内样式

 

 

设置行内样式

 

 

 

经典案例:

 

注意细节:

ü  CSS中的连字符命名方式,在js中,使用小驼峰命名方式与之对应。

ü  当一个CSS属性在js中对应的名字是保留字时,加上css即可,如cssFloat。

ü  在js中设置样式属性,单位是必需的。

ü  使用style属性只能读取通过style声明的样式。

 

 

2.脚本化CSS类

 

需求:

对一个元素设置多种样式

 

功能是可以实现的,有弊端:

1,js代码啰嗦,冗余度高

2,没有重用性,如果其它元素也需要设置同样的样式,只能再写一遍。

 

我们可以使用第二种方式,通过css类来批量设置样式,如下:

 

删除样式时,这个时候,我们需要给class赋为空:

3.查询计算出的样式

我想去获得下面的盒子的宽度:

 

 

我们试图用style属性,来获取,如下:

 

原因:使用style只能获取通过style属性设置的样式。

 

使用CSS类,也不行,我们现在使用是ID,和类没有一点关系。

 

针对这种情况,我们可以使用如下两个方法:

ü  标准浏览器:使用window.getComputedStyle

ü  IE浏览器:使用currentStyle属性

 

所谓的计算出的样式,可以利用开发者工具查看,如下:

 

先查看通过window.getComputedStyel,能得到如下的内容:

 

结果是一个对象,我们可以利用对象的访问方式来获取样式:

 

 

在ie浏览器下,测试:

 

使用currentStyle,测试如下:

 

上面,我们使用getComputedStyle和currendStyle来获取元素的最终样式,感觉有如下问题:

ü  1,比较麻烦

ü  2,要考虑兼容性,需要写出兼容性代码

 

在实际开发中,我们很少会直接使用上面的方法,对于上面的两个方法,是在框架的底层可能会用到。

 

问题来了:上面的方法我们不用,我们怎么去获取一些元素的常见样式?比如元素的大小,位置,等等。这个时候,W3C给我们提供了快捷的方式,专门用来获取常见的样式。

4.获取元素尺寸

offsetWidth、offsetHeight

表示元素的大小:

offsetWidth =border+padding+widht

offsetHeight =border+padding+height

 

 

scrollLeft、scrollTop

表示滚动条滚动的距离

scrollLeft,表示滚动条在水平方向上的滚动的距离

scrollTop,表示滚动条在垂直方向上的滚动的距离

 

请问:哪些地方会用到滚动条?

整个页面是有滚动条的,也是滚动条出的频率最高的地方。

 

针对scrollTop, scrollLeft,我们只需要掌握一种就可以--页面滚动条的垂直滚动距离,就是scrollTop

 

获取页面滚动条的垂直滚动距离:

对于谷歌浏览器,我们是使用document.body.scrollTop来获取垂直方向上的滚动距离

但是狐火浏览器不认这document.body.scrollTop, 它认document.documentElement.scrollTop

 

对于火狐浏览器,写法如下:

 

这个时候,我们要去考虑一个兼容的写法:

我们需要去判断浏览器,根据浏览器来使用不同的代码。

 

根据判断浏览器去写兼容,我们不推荐,这个时候,我们通常会使用---能力检测

 

 

使用能力检测之后的代码:

 

简化之后的代码:

 

5.获取元素位置

offsetLeft   offsetTop

 

对于前面所学的,我们可以使用学过的内容来获得元素位置,有如下两个问题:

1,使用getComputedStyle或currentStyle来获取元素的位置比较麻烦

2,就算获取到了left和top,那也不能反应出元素的真实位置

所以,需要有一种新的方式来获取元素的位置---offsetLeft,offsetTop

 

 

给div添加position:absolue,如下:

 

不管在哪一种情况下,使用offsetLeft和offsetTop都可以准确获取相对于父定位元素的位置

 

ü  表示对象元素边界的左上角顶点相对于offsetParent的左上角顶点的水平偏移量。

ü  如果当前元素的父级元素没有进行CSS定位(position为absolute或relative),offsetParent为body。

ü  如果当前元素的父级元素中有CSS定位(position为absolute或relative),offsetParent取最近的那个父级元素。

四.事件模型

事件在现实生活中指一件事,学习js中的事件,指一个行为。

html -->   内容

css  -->   样式

js   -->   行为

1.事件入门

a.认识JavaScript事件

JS是一门运行在浏览器端的脚本语言,它也是一门事件驱动的语言。任何地方其实都带着事件,那们能感受到的事件有:

ü  鼠标点击

ü  鼠标悬停

ü  鼠标挪开

ü  键盘敲击

 

正是有了事件,我们才能给网页进行一个交互。

 

b.事件三要素(事件源、事件、监听器)

任何一个事件(模型),都必须包含三要素:

ü  事件源,在哪个元素上发生的

ü  事件,具体发生了什么事件,点击,悬停,键盘....

ü  监听器,当事件发生了,做什么事,在js中,通常用函数进行表示

 

事件三要素:

 

如何理解事件三要素,以生活当中为例:

 

 

c.准确理解事件概念

1,我们学习的是事件,但是这里的事件是不事件模型,不是指事件,真正的事件就是一个单纯行为。

2,事件不是以on打头,如果onclick不是一个事件,click才是一个事件。onclick引用的是一个元素对象的属性,它指向click事件类型绑定的实际处理函数。

 

2.事件绑定

在实际开发中,需要对事件源进行事件绑定(绑定有时候也叫做注册),有多种方式可以进行绑定?

ü  HTML事件处理程序

ü  DOM0级事件处理程序

ü  DOM1级事件处理程序

ü  IE事件处理程序

 

为什么要进行事件绑定?

以摩托车安装报警器为例,它一定有两个过程:

ü  在摩托车的安装了报警器

ü  有人触摸了摩托车,发出报警

 

回到我们的js事件中,期望某个事件会发生,那么我们也需要两个过程:

ü  绑定事件(注册事件)

ü  触发事件

 

 

 

(1).HTML事件绑定方式

格式:直接作为元素的属性,写在行内的。

 

基本使用,如下:

对于这种方式,现在不推荐使用,但是在掌握,能看到别人写的代码就行。

(2).DOM 0级事件处理程序

将html代码和js代码相分离:

这种方式,得到了所有浏览器的支持。

在实现一些简单的开发时,使用这种方式,非常好。

(3).DOM 2级事件处理程序

一旦我们的需求变得更加复杂时,此时使用DOM0级方式就显的有些吃力了。无法满足特定的开发场景,如下:

 

多个程序员在开发同一个页面时,但是每个人完成的具体功能不一样,但是它们操作相同的元素。如图:

在这种情况下,最后一个onclick事件绑定会覆盖前面所有的onclick绑定。显然这些不是我们想看到的。

 

在DOM2中,提供了一个标准的方式,对事件进行绑定:

有两个:

ü  addEventListener:绑定事件

ü  removeEventListener:解绑事件

 

格式:

事件源.addEventListener(事件,监听器);

事件源.removeEventListener(事件,监听器);

 

注意:事件是不带on, 如click就是click,不是onclick

 

绑定的基本使用:

 

解绑的基本使用:

我们尝试这样解绑:

发现不能解绑

 

实际上,针对解绑,是有如下要求的:

ü  确保绑定和解绑的事件类型是相同的

ü  确保监听器是完全一样

 

 

注意细节:

1,对于DOM2级方式,事件名称是没有on的

2,对于removeEventListener,必须确保事件名称和监听器完全一至。

 

 

(4).IE事件处理程序

使用DOM2级方式来绑定,非常好用,功能也强大,但是IE浏览器不支持,如图所示:

ie8中测试

实际上,IE有自己的想法,它也提供了两个方法:

ü  attachEvent 绑定

ü  detachEvent 解绑

 

格式:

ü  事件源.attachEvent(事件,监听器);

ü  事件源.detachEvent(事件,监听器);

 

基本使用:

 

 

 

 

 

 

解绑:

 

注意细节:

ü  1,在ie事件绑定方式中,事件名称是要加on

ü  2,在js中,所有事件的名称,都是全小写,有on或没有on都要遵循全小写这个规则。

 

 

封装跨浏览器的事件绑定函数(事件处理程序的兼容处理):

 

分析:

要从事件的三要素下手:

ü  事件源

ü  事件

ü  监听器

 

要写一个函数,函数要素:

ü  函数名

ü  形参

 

分析过程如下:

需要去判断浏览器,浏览器可以不判断,用能力检测:

 

 

 

 

var e ;

if(addEventListener){

e =addEventListener;

}else{

e = attachEvent;

}

 

封装如下:

第一步:对于谷歌浏览器,它是认识这个addEventListener

对于IE浏览器,情况如下:它不认识这个addEventLisener

 

 

 

最终代码:

 

解绑最终代码如下:

3.事件流及事件传播

针对如下结构:

 

给p, div, body, document分别绑定上click事件,如下:

 

通过上面这个现象,我们得出一个结论:

ü  在DOM中,任何事件都具备传播性。

ü  传播是有条件的,通常就是父子关系中传播。

 

这就是事件流和传播的概念。

 

既然这事件具有传播性,那么这旨怎么传播的?

ü  默认情况下,遵循的是一个冒泡型,自下向上。

ü  还有一种方式,捕获型,自上向下,和冒泡刚好相好。

 

 

capture:捕获

bubble:冒泡

 

如果是捕获:document-->html->body->div

如果是冒泡:div-->body-->html-->document

 

在DOM2中,addEventListener,还可以有第三个参数,是一个布尔值:

ü  true, 捕获型

ü  false冒泡型,默认值

 

捕获型代码如下:

 

在实际开发中,建议使用冒泡,以确保所有浏览器都能很好的支持,这也是为什么addEventListner将第三个参数的默认值设置为false的原因。

 

那事件流,对我们有用吗?

1,可以更好的理解dom中的事件绑定机制

事件必须先要绑定,然后在触发的时候才可以执行

事件具有传播性

2,可以利用事件流实现事件委托(先不说)

4.事件类型

在我们的DOM中,具体有哪些事件?

 

学习方法:

针对每一个事件,我们都要从两个方面去学习:

ü  怎么用

ü  在实际开发的典型用法

(1).焦点事件

ü  focus:获取焦点

ü  blur:失去焦点

 

使用范围:input, a, select

使用最多的就是input

 

 

经典应用:

以开心网为例,获取焦点时,弹出提示信息:

 

失去焦点时,提示信息也消失:

 

 

案例:判断用户名不能为空:

 

(2).鼠标事件

ü  click,单击

ü  mouseover,  mouseout 鼠标悬停,鼠标离开,使用最多

ü  mousedown,  mousemove,   mouseup鼠标按下去,鼠标移动,鼠标松开

 

基本使用:

 

具体应用比较多,比如:下拉菜单,多级菜单等等都会用到鼠标事件。

(3).键盘事件

keydown和keypress:键按下去

keyup: 键松开

 

键盘事件,可以绑定到某个具体的元素上,也可以绑定到document上。

 

keydown和keypress都表示按下去,它们两者有细微的区别:

keydown,可以响应所有键的按下

keypress, 只能响应字符键(字母,数字,符号),控制键和功能键不响应。

 

如果你按着键盘上的键不放的话,那么就重复执行keydown和keyup操作。

 

 

应用场景:

在网站开发中,使用比较少

在网页游戏开发中,使用比较多

(4).表单事件

表单事件:

ü  submit 提交事件,在点击submit这个按钮时所触发的事件

ü  reset 重置事件,在点击reset这个按钮时所触发的事件

ü  change  change事件,内容发生改变时,所触发的事件,通常用于input框和select

 

submit reset需要对form进行绑定

在一些早期的网站中,当点击了提交按钮时,去判断用户填写的信息是否正确,如果正确,则提交,否则不提交。

 

代码如下:

 

注意:submit是在点击了submit按钮时触发,但是绑定的时候需要对form进行绑定。

 

Change是指内容发生改变了的时候,触发事件,通常有如下两种表单元素:

ü  input 文本框,使用较少,了解即可

ü  select  下拉菜单  使用较比,需要掌握

 

特点:并不是每次有变化时都会触发,而是整体输入完成后,失去焦点才触发,所以实用价值不大。

 

有一个事件,可以实现,内容每次变化时都会触发。——input事件

但是,它的兼容性不好,在ie8下面不支持。

 

针对select的使用

在实际开发中,经常使用。

 

注意:在使用下拉列表时,如果选项没有改变,还是选择了原来的选项,则不会触发change事件。

 

(5).ui事件

ui: user interface 用户界面

 

ü  load 是指加载完毕 它只可以用于图片的加载,针对整个页面

ü  unload 是卸载

ü  beforeunload 卸载之前

 

常见用法,是针对window,如下:

window.onload = function(){}

 

发现并没有找到h2元素。

原因:因为浏览器在解析页面时,是按照书写的顺序自上而下依次执行(包括js)所以在执行js代码时,我们的h2还没有载入到页面中。

 

我们可以两种方式解决:

ü  1,将js代码写在body后面

ü  2,将js代码放到load事件中

 

 

 

 

 

 

过程如下:

ü  页面的解析顺序是没有变化的,仍然是自上而下

ü  但是,此处我们给了window绑定了一个load事件,绑定时并不会立即执行。

ü  继续解析后续的内容,当页面所有的内容截入完毕后,触发load事件,此时执行监听器中的js代码。

ü  然后,使用获取元素的方法就可以正确获取相应的元素。

 

unload

指页面卸载,说白了,就是指页面关闭的那一个瞬间。

这个顺间很难捕捉到

 

beforeunload

指页面卸载之前,可以捕捉到。

 

 

实际上,我们只需要掌握load事件就可以。

 

select

选中文本事件

通常是对input框而言

 

 

可以这么用:

 

resize

是指窗口的大小发生变化时触发

通常主要针对window窗口

 

scroll

是指滚动事件

有滚动的地方,都可以触发scroll事件

但是使用最多是页面中的滚动条

 

 

需要重点掌握的:

 

5.事件对象

先看两个问题:

1,当我点击了一个盒子,我要得到点击这个盒子上的具体坐标。

2,我们要实现一个游戏上面的上下左右移动的功能,怎么去获取用户按了哪个键?

 

当出现上述类似的问题时,我们就要使用事件对象。

事件对象:可以为我们提供在事件触发时的一些详细参数。我们有了这些参数,就可以实现各种需求。

 

 

事件对象从什么地方来?

ü  在标准浏览器中,事件对象是作为监听器函数的一个参数。参数名没有任何要求。

ü  在ie浏览器中,事件对象作为window的个event属性来存在,属性名是固定不变。就是是event,用window.event来表示。

 

看一下,事件对象究竟是什么? 代码如下

 

 

 

 

 

在低版本的ie浏览器中,测试如下:

 

在低版本的浏览器中,我们要使用window.event来获取,如下:

 

 

如何编写兼容性代码:

 

可以使用三元运算符简化:

 

更为出彩的代码为:

 

不同类型的事件,事件对象所提供的参数也不一样:

比如:键盘事件,里面就有不同的键码:

 

 

 

模拟游戏中的上下左右操作:

 

6.事件中的this

this在js中非常特殊。

目前我们讨论this,只在监听器中讨论。

 

DOM0级方式事件绑定中的this

 

 

 

 

DOM2级方式事件绑定中的this

 

HTML方式事件绑定中的this

 

注意,在HTML绑定事件中,监听器中的this并不总是指向当前的事件源,有的时候指向window。

 

对于DOM0,DOM2级时,可以使用this来简化我们代码,但是对于HTML级的事件绑定,不要用this。

 

对于HTML级事件绑定,怎么让this代码当前事件源呢?

 

最终,只需要把握两点:

ü  1,在事件监听函数中,可以使用this,表示事件源

ü  2,如果是使用HTML方式来绑定的话,this并不总是指向事件源,需要通过参数进行传递。

 

7.阻止默认事件

在HTML中,有些标签有默认事件,和我们绑定的事件有可能会发生冲突。

ü  a标签,它有默认点击的动作,就是跳到href指定的url上面。

ü  form标签,它的默认动作就是提交到服务器,进行处理。

 

如图:

 

阻止默认事件,有两种方式:

ü  在监听器中,在代码最后使用return false。针对DOM0与HTML的事件绑定。

ü  使用事件对象中preventDefault或returnValue属性,针对DOM2级与IE方式。

 

代码如下:

 

 

 

 

如果是通过HTML方式绑定,需要注意:

 

 

f1函数,有返回值,返回了false,但是这个值并有返回给onclick事件。需要在绑定事件时候,加上return关键字,如下:

 

类似的事件,在confirm的时候,也会发生,如下:

6.经典案例

(1).Tab选项卡

 

我们要实现任何一个效果,需要从如下三个方面下手:

ü  HTML结构

ü  CSS样式

ü  JS行为

 

首先,编写HTML结构如下:

 

其次,编写CSS样式

 

效果如下:

 

JS行为如下:

 

分析:只需要使用mouseover事件

当发生mouseover的时候,需要做两件事:

ü  标题部分,把有on的上标题,去掉,在当前的标题上面加上on

ü  内容部分,把所有的ul都隐藏起来,当前标题对对应的那个ul显示出来

 

最终代码如下:

 

注意细节:

如何获取当前元素的索引值,不要试图使用循环i来获取,因为它每次得到的值都是i的最终值,我们需要使用index来保存每一次循环时的i的值。

 

(2).拖拽

结构和样式如下:

 

分析:

首先,分析我们需要用到哪些事件:mousedown, mouseover, mouseup

其次,我们需要知道在事件中完成哪些任务:

ü  1,mousedown 需要开户开关,用来表示可以拖动

ü  2,mouseover 改变div的位置

ü  3,mouseup 关闭开关

 

最终代码如下:

 

首先定义全局变量,如下:

 

注册mousedown事件,如下:

 

 

 

注册mouseover事件:

 

注册mouseup事件:

 

在体验拖动时,出现了问题:

一旦拖动过快时,就会出现卡顿

所以我们需要改进

 

需要扩大mouseover和mouseup的捕捉范围,

利用前面事件冒泡,直接绑定到document上面。

 

 

 

 

 

 

 

 

(3).导航条吸顶

目的:为了提高用户体验

 

编写HTML和CSS:

 

 

分析

我们观察实际效果,进行如下分析:

当我们拖动滚动条时,找出变化的和不变化的。

变化的:

ü  滚动条滚动的距离(scrolltop)发生了变化(不断增大)

ü  导航条和页面顶端的距离在不断的缩小,肯定有一个时刻,导航条会和页面顶端相遇。

 

不变的:

ü  导航条相对于body的垂直方向上的距离(offsetTop)

 

 

最终代码,如下:

 

(4).图片延迟加载

图片,和img有关

所谓的懒加载,就是一个网站,当用户有继续往下看的需求时,再加载图片,否则就不加载。

 

结构和样式如下:

 

分析:

既然图片是懒加载,那么在默认情况下,图片不应该加载。

怎么让它不加载?第一种方式,让src属性为空,第二种方式,将src设置为一个别名。

 

我需要保存图片的路径,但是我们还不能使用src。

就是使用其它属性来保存图片的路径:src---> data-src

 

 

 

在这个找临界点过程中:

变化的量有:scrollTop

不变的量有:offsetTop

 

clientWidth:元素的可视部分的宽度,是width和padding之和,不包含边框和滚动条,也不包含任何的可能滚动区域。

 

clientHeight:元素的可视高度,及height和padding之和,不包含边框和滚动条,也不包含任何的可能滚动区域。

 

(5).placeholder效果

结构和样式实现:

 

功能实现:还是有一点小问题,下去思考一下?

 

 

 

 

六.动画

1.动画原理

什么是动画?

会动的画面,画面就是一张图片。

动起来的图片,就是动画。

 

如何实现动画?

帧:可以理解成一张图片(画面)

频率:以一定频率来切换这些帧(图片)

 

如何在网页中实现动画?

ü  页面中的某一个元素(img),作为一帧,然后多个相同的元素进行排列

ü  以一定的频率,让这些帧组成的整体进行位置的变化

 

在实现第二点,以一定频率进行变化,需要用到定时器函数

2.定时器函数

一共有两组,共4个:

ü  setTimeout()和clearTimeout()

ü  setInterval()和clearInterval()

 

这四个函数是属性window对象的,window对象可以省略。

 

 

 

setTimeout, setInterval

 

setTimeout和setInterval的使用格式:

setTimepout(函数,时间);

setInterval(函数,时间);

ü  其中,时间是以毫米作为单位,如果要写1s, 需要写成1000

ü  函数,可以写在外面,传入函数名,也可以直接写在参数列表

 

clearTimeout, clearInterval

表示清除定时器。

定时器使用setTimepout时,那么清除时必须使用clearTimeout,如果定时器使用setInterval,那么清除时,也要使用clearInterval

 

setTimeout 一般称为定时函数。在指定时间到的时候,执行一次函数

setInterval 一般称为间歇函数,按指定的时间频率,重复执行函数

 

 

利用定时器,实现时间的显示:

 

3.图片轮播

HTML结构:

CSS样式:

实际上,我们把big-pic作来整体,然后进行移动。

 

图片规格:730*454

 

JS功能实现:

整个功能的实现分两部分:

ü  大图片的实现

ü  导航的实现

 

对于大图片的切换,按照一定的频率,向左移动,每次移动730px. 如果移到了最后一张,下次就要回到第一张。

 

先实现基本的图片切换效果:

 

功能继续完善:

针对图上的轮播,一般有如下逻辑:

ü  1,当鼠标放到大图片上时,立即停止当前的动画

ü  2,当鼠标离开时,继续动画

 

对处理轮播逻辑封装:

 

立即调用:

 

还有一个功能:

当鼠标悬停到数字导航上面时,切换图片,大图和导航都要切换。

 

 

 

 

 

 

 

 

4.滑动效果实现

结构和样式代码:

 

js代码如下:

 

基本的滑动实现了,它的使用价值并不高,我们需要一个封装的能够重用的滑动效果:

 

 

5.淡入淡出

本质就是使用js去控制元素的透明度。

ü  针对标准浏览器,opacity, 取值范围为:0~1

ü  IE浏览器, 使用alpha函数,它的取值0~100

 

这一次,我们只针对标准浏览器:

 

结构与样式如下:

 

 

js功能实现如下:

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值