❀本篇来自尚硅谷老师的听课笔记
练习:95、101-114、116、118-119、120-19:38、123钟表、124魔方立体旋转效果、132导航条、135淘宝导航、141-142移动端页面、145-148美图手机
服务器开发语言:❀Java、PHP、C#、Python、❀Node.js
客户端形式:文字客户端、图形化界面、网页(B/S架构)
网页中使用的语言:HTML、CSS、JavaScript
所有数据在计算机中均以二进制形式存储,文字也不例外。
编码:将字符转换为二进制码的过程
解码:将二进制码转换为字符的过程
字符集:编码和解码所采用的规则
常见的字符集:ASCII、ISO88591、GB2312、GBK、❀UTF-8(万国码)
//声明UTF-8:通过meta标签
如果编码和解码所采用的字符集不同就会出现乱码问题
❗️ 在网页中编写的多个空格默认情况会自动被浏览器解析为一个空格。
空格 |   ; |
---|---|
大于号 | > ; |
小于号 | < ; |
版权符号 | © ; |
meta主要用于设置网页中的一些元数据,元数据不是给用户看。
//❀❀❀keywords表示网站的关键字(网页搜索关键字可查询相关网页的)。可以同时指定多个关键字,关键字之间使用英文,隔开。
//❀❀❀description用于指定网站的描述,网站的描述会显示在搜索引擎的搜索结果中。
//将页面重定向到另一个网站,比如3秒后跳转至百度
title标签的内容会作为搜索结果的超链接上的文字显示。
【块元素】h1~h6 一共有六级标题
〰️从h1~h6重要性递减。
〰️h1在网页中重要性仅次于title标签,一般情况下一个页面中只会有一个h1。
〰️一般情况下标题标签只会使用到h1 ~ h3,h4 ~ h6很少用。
hgroup标签用来为标题分组,可以将一组相关的标题同时放入到hgroup。
回乡偶书二首
其一
【块元素】p标签表示页面中的一个段落。
【行内元素】em:用于表示语音语调的一个加重。即倾斜
strong表示强调重要内容。即加粗
【块元素】blockquote表示一个长引用。效果显示为首行空2字符。
鲁迅说:
这句话我是从来没有说过的!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EISBaLWS-1646239243780)(C:\Users\小半\AppData\Roaming\Typora\typora-user-images\image-20220116213144956.png)]
【行内元素】q表示一个短引用。效果为自动加引号。
子曰
学而时习之,不亦说乎
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9WGhtmLo-1646239243781)(C:\Users\小半\AppData\Roaming\Typora\typora-user-images\image-20220116213250568.png)]
br:页面中的换行。
可以有多个header。可以是网页的也可以是部分的。
一个页面中只会有一个main。
可以有多个footer。可以是网页的也可以是部分的。
表示网页中的导航。
和主体相关的其他内容,即侧边栏。
表示一个独立的文章。
表示一个独立的区块,上边的标签都能不能表示时使用section。
用来表示一个区块,主要的布局元素。
【行内元素】,一般用于在网页中选中文字。
【自结束标签】img:用于向当前页面中引入一个外部图片。
属于替换元素,既有块元素特点,也有行内元素特点。
src:指定外部图片的路径。
alt:对图片的描述,这个描述默认情况下不会显示,有些浏览器会在图片无法加载时显示。搜索引擎会根据alt中的内容来识别图片。如果不写alt属性则图片不会被搜索引擎所收录。
width:图片的宽度。单位是像素px。
height:图片的高度。单位是像素px。
宽度和高度中如果只修改了一个,则另一个会等比例缩放。
❗️注意:一般情况在pc端,不建议修改图片的大小。需要多大的图片就裁多大。但是在移动端,经常需要对图片进行缩放(大图缩小)。
效果一样,用小的;效果不一样,用效果好的。
用于向当前页面中引入一个其他页面(作为窗口的形式引入)。
1️⃣在网页中一般通过块元素来对页面进行布局。
2️⃣一般情况下在块元素中放行内元素,而不会在行内元素中放块元素。
3️⃣块元素中基本什么都能放。
4️⃣p元素中不能放任何的块元素。
1️⃣行内元素主要用来包裹文字。
超链接可以从一个页面跳转到另一个页面,或者是当前页面的其他位置。
【行内元素】使用a标签定义。
在a标签中可以嵌套除了自身外的任何元素。
超链接
超链接
可以直接将超链接的href属性设置为#。这样点击超链接以后页面不会发生跳转,而是转到当前页面的顶部位置。
回到顶部
给要去的位置加上id属性(唯一不重复的)。
每一个标签都可以添加一个id属性
同一个页面中不能出现重复的id属性。
id属性有大小写之区别
//给要去的位置添加id属性
//去往指定位置的链接
去指定位置
1️⃣在开发中可以将#作为超链接的占位符使用。
空链接(未指定具体链接时)
2️⃣可以使用javascript:;来作为href属性,此时点击超链接什么也不会发生。
空链接(未指定具体链接时)
当需要跳转到一个服务器内部的页面时,一般都会使用相对路径。
相对路径都会使用 . 或 … 开头
./ 可以省略不写。如果不写 ./ 和 …/ 则默认写了 ./
audio:向页面中引入一个外部的音频文件。
▶️音视频文件引入时,默认情况下不允许用户自己控制播放停止。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HVJR24Su-1646239243781)(C:\Users\小半\AppData\Roaming\Typora\typora-user-images\image-20220117001959289.png)]
除了通过src来指定外部文件的路径外,还可以通过source来指定文件【此写法友好性更强】
embed老版本浏览器引入音频文件
video:引入一个视频。
使用方式和audio基本一样。
可以在腾讯视频等生成复制代码,然后通过内联框架移入网页中。
html中列表一共有三种:
⛵️列表之间可以互相嵌套。
使用ol标签,使用li表示列表项。
- 结构
- 表现
- 行为
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C8QvGjBY-1646239243783)(C:\Users\小半\AppData\Roaming\Typora\typora-user-images\image-20220116220615346.png)]
使用ul标签,使用li表示列表项。
- 结构
- 表现
- 行为
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dGr4lFH2-1646239243784)(C:\Users\小半\AppData\Roaming\Typora\typora-user-images\image-20220116220544790.png)]
使用dl标签创建一个定义列表,使用dt表示定义的内容,使用dd来对内容进行解释说明。
结构
- 结构表示网页的结构
- 结构表示网页的结构
- 结构表示网页的结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lg2Wop4C-1646239243785)(C:\Users\小半\AppData\Roaming\Typora\typora-user-images\image-20220116220953518.png)]
⛺️通过table标签来创建一个表格。
⛺️在table中使用tr表示表格中的一行,有几个tr就有几行。
⛺️在tr中使用td表示一个单元格,有几个td就有几个单元格。
⛺️可以将一个表格分成三个部分:头部 thead、主体 tbody、底部 tfoot。
⛺️th 表示头部的单元格【有加粗、居中的效果】
日期
收入
支出
合计
2000.1.1
500
200
300
2000.1.1
500
200
300
2000.1.1
500
200
300
2000.1.1
500
200
300
合计
300
A2
B2
C2
D2
A4
B4
C4
border-spacing: 0px;
border-collapse: collapse;
如果表格中没有使用tbody而是直接使用tr,那么浏览器会自动创建一个tbody,并且将tr全都放到tbody中。【tr不是table的子元素】
//❀逐行变色
tbody > tr:nth-child(odd){
background-color: #bfa;
}
默认情况下元素在td中是垂直居中的 可以通过 vertical-align 来修改。vertical-align:middle;
使用form标签来创建一个表单。
数据要提交到服务器中,必须要为元素指定一个name属性值。
value的值为文本框上显示的提示文字。
属性
写完后是隐藏状态。
数据要提交到服务器中,必须要为元素指定一个name属性值。
type属性值为submit,按钮上显示的文字默认是“提交”。
value的值可指定按钮上的提示文字。
相同组的name属性值必须相同(才能实现多选一效果)。
像这种选择框,必须要指定一个value属性,value属性最终会作为用户的填写的值传递给服务器。
checked 可以将单选按钮设置为默认选中。
可以通过JS添加效果
可以同时选择多个。
相同组的name属性值必须相同。
需指定name属性、value属性
selected把某个选项设置为默认选中。
兼容性不太好。
网页实际上是一个多层的结构,通过CSS可以分别为网页的每一个层来设置样式。
标签内部通过style属性设置。【不推荐使用】
问题:使用内联样式,样式只能对一个标签生效。如果希望影响到多个元素必须在每一个元素中都复制一遍。并且当样式发生变化时,必须要一个一个修改,非常不方便。
my css
将样式编写在head中的style标签里,然后通过css的选择器来选中元素并为其设置各种样式。
可以同时为多个标签设置样式,并且修改时只需要修改一处即可。
更加方便对样式进行复用。
问题:只能对一个网页起作用,不能跨页面进行复用。
可以将CSS样式编写到一个外部的CSS文件中,通过link标签来引入外部的CSS文件。【开发常用】
只要想使用这些样式的网页都可以对其进行引用,使样式可以在不同页面之间进行复用。
将样式编写到外部的CSS文件中,可以使用到浏览器的缓存机制,从而加快网页的加载速度,提高用户的体验。
//1.CSS文件
p{
color:red;
font-size:12px;
}
//引入,写在head中
/* */
CSS选择器练习:尚硅谷“餐厅练习”
相关答案即练习地址入口https://blog.csdn.net/qq_44910948/article/details/106444049?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.pc_relevant_paycolumn_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.pc_relevant_paycolumn_v2&utm_relevant_index=2
样式的冲突:当我们通过不同的选择器选中相同的元素,并为相同的样式设置不同的值时,此时就发生了样式的冲突。
从高到低依次为:【优先级越高的优先显示】
!important
内联样式 1,0,0,0
id选择器 0,1,0,0
类和伪类选择器 0,0,1,0
元素选择器 0,0,0,1
通配选择器 0,0,0,0
继承的样式 没有优先级
比较优先级时,需要将所有的选择器的优先级相加计算,最后优先级越高的优先显示。【注意:分组选择器是单独计算的】
选择器的累加不会超过其最大的数量级,如类选择器最高也不会超过id选择器。
如果计算后的优先级相同,此时优先使用靠下的样式。
.d1{
background-color: purple !important;
}
作用:根据标签名选中指定的元素。
语法:标签名{}
p{
color:red;
}
h1{
color:green;
}
作用:根据元素的id属性值选中一个元素。
语法:#id属性值{}
id选择器
#red{
color:red;
}
class是一个标签的属性,它和id类似,不同的是class可以重复使用。
作用:根据class属性值选中一组元素。
语法:.class属性值
可以通过class属性来为元素分组。
可以同时为一个元素指定多个class属性。多个属性使用空格隔开。
1
2
.blue{
color:blue;
}
.abc{
font-size:12px;
}
作用:选中页面中的所有元素。
语法:*{}
*{
color:pink;
}
作用:选中同时符合多个条件的元素。
语法:选择器1选择器2选择器3…选择器n{ }
❗️交集选择器中如果有元素选择器,必须使用元素选择器开头
//将class为red的div字体设置为红色
div.red{
color:red;
}
.a.b.c {
color:blue;
}
//不建议这样写,因为#box1就能找到指定的
div#box1{}
作用:同时选中多个选择器对应的元素。
语法:选择器1,选择器2…选择器n{ }
h1,span{
color:pink;
}
#b1,.p1,h1,div,.red{
color:blue;
}
我是一个div
我是div中的p
我是p中的span
我是div中的span
作用:选中指定父元素的指定子元素
语法:父元素>子元素
//为div直接包含的span设置一个字体颜色
div>span{
color:orange;
}
div.box>span{
color:blue;
}
div>p>span{
color:red;
}
作用:选中指定元素内的指定后代元素。
语法:祖先 后代{ }
div span{
color:blue;
}
1️⃣作用:选择下一个兄弟(紧挨着的那个)。
语法:前一个+下一个
2️⃣作用:选择下边所有的兄弟
语法:兄 ~ 弟
p + span{
color:gray;
}
p ~ span{
font-size:19px;
}
给标签添加title:网页中鼠标放在对应内容上会出现title值的内容。
结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k45ENMjF-1646239243787)(C:\Users\小半\AppData\Roaming\Typora\typora-user-images\image-20220117153912469.png)]
应用:
[属性名]:选择含有指定属性的元素。
[属性名=属性值]:选择含有指定属性和属性值的元素。
[属性名^=属性值]:选择属性值以指定值开头的元素。
[属性名$=属性值]:选择属性值以指定值结尾的元素。
[属性名*=属性值]:选择属性值中含有某值的元素。
p[title]{
color:yellow;
}
p[title=abc]{
color:yellow;
}
p[title^=abc]{
color:yellow;
}
p[title$=abc]{
color:yellow;
}
p[title*=abc]{
color:yellow;
}
一个:开头
伪类用来描述一个元素的特殊状态,比如第一个元素、被点击的元素、鼠标移入的元素等。
伪类一般情况下都是使用: 开头。
以下这些伪类都是根据所有的子元素进行排序。
:first-child 选择第一个子元素
:nth-child( ) 选择第n个子元素
特殊值:
n:表示第n个范围,即0~正无穷
2n:表示选中偶数位的元素,即2、4、6…
even:表示选中偶数位的元素
2n+1:表示选中奇数位的元素
odd:表示选中奇数位的元素
//将ul里的第一个li设置为红色
ul>li:first-child{
color:red;
}
以下几个伪类的功能和上述类似。不同点是他们是在同类型元素中进行排序。
:first-of-type:选中同类型的第一个元素
:last-of-type
:nth-of-type
:not() 否定伪类。将符合条件的元素从选择器中去除。
ul>li:not(:nth-of-type(3)){
color:blue;
}
#####a元素的伪类
:link 用来表示没访问过的链接(正常的链接)。
:visited 用来表示访问过的链接。
:hover 表示鼠标移入的状态。
:active 表示鼠标点击的状态。
a:link{
color:red;
}
a:visited{
color:blue;
}
a:hover{
color: aqua;
font-size: 50px;
}
a:active{
color: yellowgreen;
}
两个: 开头
伪元素表示页面中一些特殊的并不真实存在的元素(特殊的位置)。
p::first-letter{
font-size:50px;
}
div::after{
content:'abc'; //其中值可更改
color:red;
}
样式的继承:我们为一个元素设置的样式同时也会应用到它的后代元素上。
继承是发生在祖先和后代之间的。
利用继承可以将一些通用的样式统一设置到共同的祖先元素上,这样只需设置一次即可让所有的元素都具有该样式。
❗️不是所有样式都会被继承
像素
百分比
em
rem
屏幕是由一个一个发光的小点构成,这一个个的小点就是像素。
分辨率:1920 x 1080 说的就是屏幕中小点的数量。
在前端开发中像素要分成两种情况讨论:CSS像素 和 物理像素。
物理像素:上述所说的小点点就属于物理像素。
CSS像素:编写网页时,我们所用像素都是CSS像素。如:
.box1{
width: 100px;
height: 100px;
}
视口就是屏幕中用来显示网页的区域。
可以通过查看视口的大小,来观察CSS像素和物理像素的比值。
我们可以通过改变视口的大小,来改变CSS像素和物理像素的比值。
网页是一个多层的结构,一层摞着一层。通过CSS可以分别为每一层来设置样式。作为用户来讲只能看到最顶上一层。这些层中,最底下的一层称为文档流,文档流是网页的基础。我们所创建的元素默认都是在文档流中进行排列。
对于我们来元素主要有两个状态:在文档流中、不在文档流中(脱离文档流)。
脱离文档流以后,不需要再区分块和行内了。
CSS将页面中的所有元素都设置为了一个矩形的盒子。
将元素设置为矩形的盒子后,对页面的布局就变成将不同的盒子摆放到不同的位置。
内容区、内边距、边框决定盒子的大小(计算盒子大小时,需要将这三个区域加到一起计算),外边距决定盒子的位置。
每一个盒子都由以下几个部分组成:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iMSJHnmH-1646239243789)(C:\Users\小半\AppData\Roaming\Typora\typora-user-images\image-20220117174414106.png)]
内容区(content)
内边距(padding)
边框(border)
border: solid 10px orange;
设置边框,需要至少设置三个样式:
边框的宽度 border-width:用来指定四个方向的边框的宽度。默认值一般是 3个像素。
值的情况:
四个值:上 右 下 左
三个值:上 左右 下
两个值:上下 左右
一个值:上下左右
border-xxx-width
xxx可以是 top right bottom left,用来单独指定某一个边的宽度。
border-width: 10px;
边框的颜色 border-color
用来指定边框的颜色,同样可以分别指定四个边的边框。规则和border-width一样。
border-color也可以省略不写,如果省略了则自动使用color的颜色值。
border-color: orange;
边框的样式 border-style。默认值是none,表示没有边框
指定边框的样式。同样可以分别指定四个边的边框。规则和border-width一样。
值: solid 表示实线、dotted 点状虚线、dashed 虚线、double 双线
border-style: solid;
外边距(margin)
外边距不会影响盒子可见框的大小,但是会影响盒子的位置(即盒子实际占用空间)。
一共有四个方向的外边距:
margin也可以设置负值,如果是负值则元素会向相反的方向移动。
元素在页面中是按照自左向右的顺序排列的,所以默认情况下如果我们设置的左和上外边距则会❀移动元素自身❀,而设置下和右外边距会❀移动其他元素❀。
margin的简写属性:可以同时设置四个方向的外边距 ,用法和padding一样。
margin: 100px;
不懂看尚硅谷P49https://www.bilibili.com/video/BV1XJ411X7Ud?p=49
元素在其父元素中水平方向的位置由以下几个属性共同决定:
一个元素在其父元素中,水平布局必须要满足以下的等式:
margin-left + border-left + padding-left + width + padding-right + border-right + margin-right = 其父元素内容区的宽度 (必须满足)
没写的属性值默认是0。
以上等式必须满足,如果相加结果使等式不成立,则称为过度约束,则等式会自动调整。
调整的情况:
如果这七个值中没有为 auto 的情况,则浏览器会自动调整margin-right值以使等式满足(调整的值也可以为负值)。
这七个值中有三个值和设置为auto:width、margin-left、 maring-right。如果某个值为auto,则会自动调整为auto的那个值以使等式成立。
//所以我们经常利用这个特点来使一个元素在其父元素中水平居中。
//示例:
width:10px;
margin:0 auto;
默认情况下父元素的高度被其中内容(子元素)撑开。
子元素是在父元素的内容区中排列的,如果子元素的大小超过了父元素,则子元素会从父元素中溢出。
使用 overflow 属性来设置父元素如何处理溢出的子元素
〰️可选值:
〰️overflow-x: 、overflow-y:
相邻的垂直方向外边距会发生重叠现象。
兄弟元素
兄弟元素间的相邻垂直外边距会取两者之间的较大值(两者都是正值)。
特殊情况:
兄弟元素之间的外边距的重叠,对于开发是有利的,所以我们不需要进行处理。
父子元素
父子元素间相邻外边距,子元素的会传递给父元素(上外边距)。【父随子动】
父子外边距的折叠会影响到页面的布局,必须要进行处理。
#️⃣行内元素的盒模型的特点:
#️⃣display 用来设置元素显示的类型
可选值:
#️⃣visibility 用来设置元素的显示状态
可选值:
默认情况下,盒子可见框的大小由内容区、内边距和边框共同决定。
box-sizing 用来设置盒子尺寸的计算方式(设置width和height的作用).
可选值:
content-box 默认值,宽度和高度用来设置内容区的大小。
border-box 宽度和高度用来设置整个盒子可见框的大小。
width 和 height 指的是内容区 和 内边距 和 边框的总大小。
box-sizing: border-box;
.box1:hover{
outline: 10px red solid;
}
box-shadow 用来设置元素的阴影效果,阴影不会影响页面布局。
属性值参数:
box-shadow: 0px 0px 50px rgba(0, 0, 0, .3) ;
border-radius: 用来设置圆角。圆角设置的圆的半径大小
方位:
//圆角是圆形
border-top-left-radius:50px;
//圆角是椭圆
border-top-left-radius:50px 100px;
简写方式:
应用
//设置椭圆
border-radius: 20px / 40px;
//将元素设置为一个圆形
border-radius: 50%;
通常情况,浏览器都会为元素设置一些默认样式。默认样式的存在会影响到页面的布局,通常情况下编写网页时必须要去除浏览器的默认样式(PC端的页面)。
如:li标签前面自带小圆点;初始网页自带边距等。
不同的浏览器默认样式也可能不同。
清除样式:
1️⃣方式1
//清除默认样式
*{
margin: 0;
padding: 0;
}
2️⃣方式2 重置样式表:专门用来对浏览器的样式进行重置的。
【二选一,推荐reset.css】
通过浮动可以使一个元素向其父元素的左侧或右侧移动。
使用 float 属性来设置于元素的浮动。
可选值:
元素设置浮动以后,水平布局的等式便不需要强制成立。
元素设置浮动以后,会完全从文档流中脱离,不再占用文档流的位置。所以元素下边的且还在文档流中的元素会自动向上移动。
简单总结:浮动目前来讲它的主要作用就是让页面中的元素可以水平排列,通过浮动可以制作一些水平方向的布局。
元素设置浮动以后,将会从文档流中脱离,从文档流中脱离后,元素的一些特点也会发生变化。
####(2)脱离文档流的特点
见3.3.1文档流的(2)
在浮动布局中,父元素的高度默认是被子元素撑开的,当子元素浮动后,其会完全脱离文档流,子元素从文档流中脱离,将会无法撑起父元素的高度,导致父元素的高度丢失。父元素高度丢失以后,其下的元素会自动上移,导致页面的布局混乱。
所以高度塌陷是浮动布局中比较常见的一个问题,这个问题我们必须要进行处理!
解决方法:
1️⃣把父元素高度写死。(但是我们希望内容将其撑开)
2️⃣BFC(Block Formatting Context) 块级格式化环境
BFC是一个CSS中的一个隐含的属性,可以为一个元素开启BFC。开启BFC该元素会变成一个独立的布局区域。
元素开启BFC后的特点:
可以通过一些特殊方式来开启元素的BFC:
设置元素的浮动(不推荐)。即父子元素均设置浮动,但是此时脱离文档流了。
将元素设置为行内块元素(不推荐)。即父子元素设置为行内块元素,但是行内块元素不适合做外部的容器,并且宽度也没了。
将元素的overflow设置为一个非visible的值。(有副作用但比较小)
常用的方式 为元素设置 overflow:hidden 开启其BFC 以使其可以包含浮动元素。
Document
3️⃣clear
如果我们不希望某个元素因为其他元素浮动的影响而改变位置,可以通过clear属性来清除浮动元素对当前元素所产生的影响。
clear: both;
4️⃣after伪元素。【完美方式!基本没有副作用。】
//给父元素盒子加after伪元素(尚硅谷零基础入门HTML5+CSS3 P67)
.box1::after{
content: '';
clear: both;
/* 默认after是行内元素,得转换成块元素,撑起父元素高度。*/
display: block;
}
5️⃣clearfix 这个样式可以同时解决高度塌陷和外边距重叠的问题,当在遇到这些问题时,直接使用clearfix这个类即可。【最完美方式!基本没有副作用】
.clearfix::before,
.clearfix::after{
content: '';
display: table;
clear: both;
}
定位是一种更加高级的布局手段,通过定位可以将元素摆放到页面的任意位置。
使用position属性来设置定位。
可选值:
当元素开启了定位以后,可以通过偏移量来设置元素的位置(不影响其他元素)。
定位元素垂直方向的位置由top和bottom两个属性来控制,通常情况下我们只会使用其中一。
top值越大,定位元素越向下移动;bottom值越大,定位元素越向上移动。
定位元素水平方向的位置由left和right两个属性控制,通常情况下只会使用一个。
left越大元素越靠右;right越大元素越靠左。
当元素的position属性值设置为relative时则开启了元素的相对定位。
特点:
当元素的position属性值设置为absolute时,则开启了元素的绝对定位。
特点:
开启绝对定位后,如果不设置偏移量,元素的位置不会发生变化。
开启绝对定位后,元素会从文档流中脱离。
绝对定位会改变元素的性质,行内变成块,块的宽高会被内容撑开。
绝对定位会使元素提升一个层级。
绝对定位元素是相对于其包含块进行定位的。
♀包含块( containing block ):
正常情况下:包含块就是离当前元素最近的祖先块元素。
//中间div的包含块就是外面的div
//span的包含块是div;em的包含块是div(因为span是行内元素)
hello
绝对定位的包含块:包含块就是离它最近的开启了定位的祖先元素,如果所有的祖先元素都没有开启定位则根元素就是它的包含块。
html(根元素、初始包含块)
绝对定位元素的布局
开启绝对定位后,水平布局的公式为:
left + margin-left + border-left + padding-left + width + padding-right + border-right + margin-right + right = 包含块的内容区的宽度
水平方向的布局等式就需要添加left 和 right 两个值。此时规则和之前一样只是多添加了两个值:
垂直方向布局的等式的也必须要满足:
top/bottom + margin-top/bottom + padding-top/bottom + border-top/bottom + height = 包含块的高度
//通过绝对定位设置水平垂直居中(主要代码为两模块的空格以下的)
.box1{
width: 500px;
height: 500px;
background-color: #bfa;
position: relative;
}
.box2{
width: 100px;
height: 100px;
background-color: orange;
position: absolute;
margin: auto;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
将元素的position属性设置为fixed则开启了元素的固定定位。
固定定位也是一种绝对定位,所以固定定位的大部分特点都和绝对定位一样。
唯一不同的是固定定位永远参照于浏览器的视口进行定位。固定定位的元素不会随网页的滚动条滚动。
当元素的position属性设置为sticky时则开启了元素的粘滞定位。(兼容性不是很好)
粘滞定位和相对定位的特点基本一致,不同的是粘滞定位可以在元素到达某个位置时将其固定。
//开启粘滞定位
position: sticky;
top: 0;
对于开启了定位元素,可以通过z-index属性来指定元素的层级。
z-index需要一个整数作为参数,值越大元素的层级越高。
1️⃣让图片叠在一起。即让所有图片脱离文档流。
position: absolute;
2️⃣通过修改元素的层级来显示指定的图片。
//简单轮播图布局
京东的轮播图
1️⃣
/* 设置项目符号 */
list-style: square;
2️⃣
.news-list li::before {
content: '■';
color: rgb(218, 218, 218);
font-size: 12px;
}
字体的简写属性
font 可以设置字体相关的所有属性。
语法:
font: 自重 字体风格 字体大小/行高 字体族
【自重 、字体风格、行高可以省略不写,如果不写使用默认值】
font: 50px/2 微软雅黑, 'Times New Roman', Times, serif;
font: bold italic 50px/2 微软雅黑, 'Times New Roman', Times, serif;
color 用来设置字体颜色。
font-size 设置字体的大小。
font-family 设置字体族(字体的格式)。
(用此设置字体不会涉及到版权问题)
♥️可选值:【指定字体的类别,浏览器会自动使用该类别下的字体】
♥️font-family 可以同时指定多个字体,多个字体间使用,隔开。(字体生效时优先使用第一个,第一个无法使用则使用第二个…以此类推)
一般可选值的那几个写在最后,是为了保证字体正常显示。如Microsoft YaHei,Heiti SC,tahoma,arial,Hiragino Sans GB,“\5B8B\4F53”,sans-serif
font-family: 'Courier New', Courier, monospace;
font-weight 设置字重,即字体的加粗
♥️可选值:
font-style 设置字体的风格
♥️可选值:
normal 正常的。
italic 斜体。
font-face可以将服务器中的字体直接提供给用户去使用 。
@font-face {
/* 指定字体的名字 */
font-family:'myfont' ;
/* 服务器中字体的路径 */
src: url('./font/ZCOOLKuaiLe-Regular.ttf') format("truetype");
}
//引用字体
font-family: myfont;
在网页中经常需要使用一些图标,可以通过图片来引入图标。但是图片大小本身比较大,并且非常的不灵活。所以在使用图标时,我们还可以将图标直接设置为字体,然后通过font-face的形式来对字体进行引入。这样我们就可以通过使用字体的形式来使用图标。
1️⃣下载fontawesome https://fontawesome.com/
2️⃣解压
3️⃣将css和webfonts移动到项目中(必须在同一级目录下)
4️⃣将all.css引入到网页中
5️⃣使用图标字体
使用:
//前缀一般为fas或fab,后面是在找到自己要用的图标前对应的名字
通过伪元素来设置图标字体
找到要设置图标的元素通过before或after选中。
在content中设置字体的编码。
设置字体的样式
fab
font-family: 'Font Awesome 5 Brands';
fas
font-family: 'Font Awesome 5 Free';
font-weight: 900;
通过实体来使用图标字体
图标的编码;
1️⃣下载所需图标文件
3️⃣将下载的内容移动到项目中(可以删除demo.html和demo.css)
4️⃣将iconfont.css引入到网页中
5️⃣使用图标字体(同上)
i.iconfont{
font-size: 100px;
}
p::before{
content: '\e625';
font-family: 'iconfont';
font-size: 100px;
}
Hello
行高指的是文字占有的实际高度。
可以通过line-height来设置行高。
行高经常还用来设置文字的行间距。
行间距 = 行高 - 字体大小
☎️可以将行高设置为和高度一样的值,使单行文字在一个元素中垂直居中
line-height: 200px;
字体框:字体存在的格子,设置font-size实际上就是在设置字体框的高度。
行高会在字体框的上下平均分配。
可选值:
可选值:
可选值:
//IE不支持
text-decoration: underline red dotted;
可选值:
//将溢出的内容设置成省略号【缺一不可】
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
背景相关简写属性:所有背景相关的样式都可以通过该样式来设置,并且该样式没有顺序要求,也没有哪个属性是必须写的。
:happy:background-size必须写在background-position的后边,并且使用/隔开。即background-position/background-size。
:happy:background-origin background-clip 两个样式 ,orgin要在clip的前边。
background: url('./img/2.jpg') #bfa center center/contain border-box content-box no-repeat ;
引入:图片属于网页中的外部资源,外部资源都需要浏览器单独发送请求加载,浏览器加载外部资源时是按需加载的,用则加载,不用则不加载。
案例08背景练习2-按钮可看出,若同时用很多小图完成一个效果,可能出现图片闪烁的问题。
解决图片闪烁的问题:
可以将多个小图片统一保存到一个大图片中,然后通过调整background-position来显示的图片。这样图片会同时加载到网页中 就可以有效的避免出现闪烁的问题。这个技术在网页中应用十分广泛,被称为CSS-Sprite,这种图我们称为雪碧图。
1️⃣先确定要使用的图标。
2️⃣测量图标的大小。
3️⃣根据测量结果创建一个元素。
4️⃣将雪碧图设置为元素的背景图片。
5️⃣设置一个偏移量以显示正确的图片。【利用background-position】
.box1 {
width: 42px;
height: 30px;
background: url(./img/amazon-sprite_.png);
background-position: -58px -338px;
}
一次性将多个图片加载进页面,降低请求的次数,加快访问速度,提升用户的体验。
通过渐变可以设置一些复杂的背景颜色,可以实现从一个颜色向其他颜色过渡的效果。
!!渐变是图片,需要通过background-image来设置。
线性渐变:颜色沿着一条直线发生变化。
linear-gradient(red,yellow) 红色在开头,黄色在结尾,中间是过渡区域
//方位组合
background-image: linear-gradient(to top left,red,yellow);
//度数
background-image: linear-gradient(90deg,red,yellow);
//圈
background-image: linear-gradient(.25turn,red,yellow);
//默认情况下平均分布
background-image: linear-gradient(red,yellow,#bfa,orange);
//手动指定渐变的分布情况
background-image: linear-gradient(red 50px,yellow 100px, green 120px, orange 200px);
background-image: repeating-linear-gradient(red 50px, yellow 50px);
background-image: repeating-linear-gradient(to right ,red, yellow 50px);
径向渐变:放射性的效果。
默认情况下径向渐变的形状根据元素的形状来计算的。如正方形 --> 圆形、长方形 --> 椭圆形。
语法:
radial-gradient(大小 at 位置, 颜色 位置 ,颜色 位置 ,颜色 位置)
我们也可以手动指定径向渐变的大小:
background-image: radial-gradient(100px 100px, red , yellow)
大小可取值:
也可以指定渐变的位置
位置可取值:
background-image: radial-gradient(100px 100px at 100px 100px, red , #bfa)
background-image: radial-gradient(at top, red , #bfa)
background-image: radial-gradient(at 100px 100px, red , #bfa)
background-image: radial-gradient(farthest-corner at 100px 100px, red , #bfa)
background-color: #bfa;
✳️可以同时设置背景图片和背景颜色,这样背景颜色将会成为图片的背景色。
✳️如果背景的图片小于元素,则背景图片会自动在元素中平铺将元素铺满;
如果背景的图片大于元素,将会一个部分背景无法完全显示;
如果背景的图片大于元素,将会一个部分背景无法完全显示。
background-image: url("./img/1.png");
✳️可选值:
✳️设置方式:
1️⃣通过 top left right bottom center 几个表示方位的词来设置背景图片的位置。
background-position: top right;
background-position: center;
2️⃣通过偏移量来指定背景图片的位置:水平方向的偏移量、垂直方向变量。
background-position: -50px 300px;
✳️可选值:
background-clip: content-box;
✳️可选值:
background-origin: border-box;
第一个值表示宽度;第二个值表示高度。【如果只写一个,则第二个值默认是 auto】
background-size:200px 200px;
background-size:200px auto;
background-size:100% auto;
✳️可选值:
background-size: contain;
✳️可选值:
通过过渡可以指定一个属性发生变化时的切换方式。
通过过渡可以创建一些非常好的效果,提升用户的体验。
简写属性:
transition 可以同时设置过渡相关的所有属性,只有一个要求,如果要写延迟,则两个时间中第一个是持续时间,第二个是延迟。
transition:2s margin-left 1s cubic-bezier(.24,.95,.82,-0.88);
多个属性间使用,隔开。
如果所有属性都需要过渡,则使用all关键字。
大部分属性都支持过渡效果(如宽度、颜色等),注意过渡时必须是从一个有效数值向另外一个有效数值进行过渡(auto不是一个有效数值)。
transition-property: height,width;
transition-property: all;
时间单位:s 和 ms 【1s = 1000ms】
分别给过度的属性指定时间,使用,隔开。
transition-duration: 2s;
transition-duration: 100ms, 2s;
指定过渡的执行的方式。
可选值:
transition-timing-function: cubic-bezier(.24,.95,.82,-0.88);
transition-timing-function: steps(2, start);
ransition-delay: 2s;
动画和过渡类似,都是可以实现一些动态的效果。
不同的是过渡需要在某个属性发生变化时才会触发,动画可以自动触发动态效果。
设置动画效果,必须先要设置一个关键帧,关键帧设置了动画执行每一个步骤。
@keyframes test {
/* from表示动画的开始位置 也可以使用 0% */
from{
margin-left: 0;
background-color: orange;
}
/* to动画的结束位置 也可以使用100%*/
to{
background-color: red;
margin-left: 700px;
}
}
###3.8.1 属性
简写属性:
animation:test 2s 2 1s alternate;
animation-name: test;
animation-duration: 4s;
animation-delay: 2s;
animation-timing-function: ease-in-out;
可选值:
animation-iteration-count: 1;
可选值:
animation-direction: alternate-reverse;
可选值:
animation-play-state: paused;
可选值:
animation-fill-mode:both;
变形就是指通过CSS来改变元素的形状或位置。transform 用来设置元素的变形效果。
变形不会影响到页面的布局,不会脱离文档流。
只能给一个元素设置transform。
默认值 center。
transform-origin:20px 20px;
平移元素,百分比是相对于自身计算的。
transform: translateY(-100px);
//平移元素,百分比是相对于自身计算的。
transform: translateX(100%);
//应用:水平垂直居中
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
z轴平移,调整元素在z轴的位置,正常情况就是调整元素和人眼之间的距离,距离越大,元素离人越近。
z轴平移属于立体效果(近大远小),默认情况下网页是不支持透视,如果需要看见效果,必须要设置网页的视距。
html{
/* 设置当前网页的视距为800px,人眼距离网页的距离 */
perspective: 8000px;
}
//测试效果
Document
通过旋转可以使元素沿着x y 或 z旋转指定的角度。
如果需要看见效果,最好要设置网页的视距。
//按度数旋转
transform: rotateY(180deg);
//按圆旋转
transform: rotateZ(.25turn);
transform: rotateY(180deg) translateZ(400px);
旋转一般有个透视效果。可以设置是否显示元素的背面:
backface-visibility: hidden;
对元素进行缩放的函数:
【对Z进行缩放,得是三维的图像,效果是拉伸】
transform:scale(2);
transform:scale(1.2);
flex是CSS中的又一种布局手段,它主要用来代替浮动来完成页面的布局。
flex可以使元素具有弹性,让元素可以跟随页面的大小的改变而改变。
要使用弹性盒,必须先将一个元素设置为弹性容器。我们通过 display 来设置弹性容器。
弹性容器的子元素是弹性元素(弹性项)。
弹性元素可以同时是弹性容器。
可选值:
主轴:弹性元素的排列方向称为主轴。
侧轴:与主轴垂直方向的称为侧轴。
flex-direction: row;
可选值:
flex-wrap: wrap-reverse;
flex-flow: row wrap;
如何分配主轴上的空白空间(即主轴上的元素如何排列)。
可选值:
justify-content: center;
设置元素间的关系。
可选值:
//居中对齐
justify-content: center;
align-items: center;
align-content: space-between;
/* align-self: 用来覆盖当前弹性元素上的align-items */
align-self: stretch;
flex 可以设置弹性元素所有的三个样式。
有顺序要求:flex 增长 缩减 基础;
可取值
flex: initial;
即当父元素有多余空间时,子元素如何伸展。
父元素的剩余空间,会按照比例进行分配。
//设置后,父元素的多余空间将给各子元素按比例分配
li:nth-child(1){
flex-grow: 0;
}
li:nth-child(2){
flex-grow: 2; */
}
li:nth-child(3){
flex-grow: 3;
}
即当父元素中的空间不足以容纳所有的子元素时,如何对子元素进行收缩。值越大,收缩得越多。
缩减系数的计算方式比较复杂。缩减多少是根据 缩减系数 和 元素大小来计算。
flex-shrink: 0;
如果主轴是 横向的 则 该值指定的就是元素的宽度;如果主轴是 纵向的 则 该值指定的是就是元素的高度。
flex-basis: auto;
order: 2;
不同的屏幕,单位像素的大小是不同的,像素越小屏幕会越清晰。(24寸 1920x1080)
查看各产品屏幕尺寸:https://screensiz.es/
智能手机的像素点 远远小于 计算机的像素点。因此有个问题:一个宽度为900px的网页在iphone6中要如何显示呢?【i6 4.7寸 750 x 1334 】 (750是物理像素、900px是CSS像素)。
默认情况下,移动端的网页都会将视口设置为980像素(css像素)。
移动端默认的视口大小是980px(css像素)。
默认情况下,移动端的像素比就是 980/移动端宽度 (iphone6 980/750)。
如果我们直接在网页中编写移动端代码,这样在980的视口下,像素比是非常不好,导致网页中的内容非常非常的小。
编写移动页面时,必须要确保有一个比较合理的像素比,如1css像素 对应 2个物理像素、1css像素 对应 3个物理像素等。
//❀【写移动端的页面必须写】设置视口大小 device-width表示设备的宽度(完美视口)
每一款移动设备设计时,都会有一个最佳的像素比,一般我们只需要将像素比设置为该值即可得到一个最佳效果,将像素比设置为最佳像素比的视口大小我们称其为完美视口。
不同的设备完美视口的大小是不一样的。由于不同设备视口和像素比不同,所以同样的375个像素在不同的设备下意义是不一样,所以在移动端开发时,就不能再使用px来进行布局了。
vw 表示的是视口的宽度(viewport width)。(vw这个单位永远相当于视口宽度进行计算)
常见移动端设计图:750px 1125px
VM适配
⚠️网页中字体大小最小是12px,不能设置一个比12像素还小的字体。如果我们设置了一个小于12px的字体,则字体自动设置为12。
响应式布局:网页可以根据不通的设备或窗口大小呈现出不同的效果。使用响应式布局,可以使一个网页适用于所有设备
响应布局的关键就是 媒体查询。通过媒体查询,可以为不同的设备,或设备不同状态来分别设置样式。
@media 查询规则{}
可以使用,连接多个媒体类型,这样它们之间就是一个或的关系。
可以在媒体类型前添加一个only,表示只有。only的使用主要是为了兼容一些老版本浏览器。
//所有设备的背景颜色都为#bfa
@media all{
body{
background-color: #bfa;
}
@media print,screen{
body{
background-color: #bfa;
}
//表示只要屏幕时,背景颜色为#bfa
@media only screen {
body{
background-color: #bfa;
}
}
//当视口宽度是500px时,背景颜色为#bfa
@media (max-width: 500px){
body{
background-color: #bfa;
}
样式切换的分界点,我们称其为断点,也就是网页的样式会在这个点时发生变化。
一般比较常用的断点:
//大于500或小于300
@media only screen and (min-width: 500px) ,(max-width:300px){
body{
background-color: #bfa;
}
}
//500到700之间
@media only screen and (min-width: 500px) and (max-width:700px){
body{
background-color: #bfa;
}
}
//非
@media not screen and (min-width: 500px) and (max-width:700px){
body{
background-color: #bfa;
}
}
这种居中方式,只适用于元素的大小确定。
top:0;
left:0;
bottom:0;
right:0;
margin:auto;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
justify-content: center;
align-items: center;
less是一门css的预处理语言。less是一个css的增强版,通过less可以编写更少的代码实现更强大的样式。
在less中添加了许多的新特性:像对变量的支持、对mixin的支持… …
less的语法大体上和css语法一致,但是less中增添了许多对css的扩展,所以浏览器无法直接执行less代码,要执行必须向将less转换为css,然后再由浏览器执行。
VSCode中easy less插件可以自动将less文件转换为css文件。
css原生也支持变量的设置。但是兼容性不好。
html{
/* css原生也支持变量的设置 */
--color:#ff0;
}
.box1{
background-color: var(--color);
}
width: calc(200px*2);
//less中的单行注释,注释中的内容不会被解析到css中。
/* */ css中的注释,内容会被解析到css文件中。
import用来将其他的less引入到当前的less。
@import "syntax2.less";
在变量中可以存储一个任意的值,并且我们可以在需要时任意的修改变量中的值。
语法: @变量名
使用:
注意:
@a:200px;
@b:#bfa;
@c:box6;
.box5{
//使用变量时,如果是直接使用则以 @变量名 的形式使用即可
width: @a;
color:@b;
}
//作为类名,或者一部分值使用时必须以 @{变量名} 的形式使用
.@{c}{
width: @a;
background-image: url("@{c}/1.png");
}
直接引用样式的值:
div{
width: 300px;
// 新版的语法
// height: $width;
}
在less中所有的数值都可以直接进行运算。
.box1{
// 在less中所有的数值都可以直接进行运算
// + - * /
width: 100px + 100px;
height: 100px/2;
background-color: #bfa;
}
& 就表示外层的父元素。
.box1{
.box2{
color: red;
}
//设置一个子元素
>.box3{
color: red;
//此处&表示box1>box3
&:hover{
color: blue;
}
}
//为box1设置一个hover
//& 就表示外层的父元素,此处&表示box1
&:hover{
color: orange;
}
div &{
width: 100px;
}
}
:extend() 对当前选择器扩展指定选择器的样式(选择器分组)。
.p1{
width: 100px;
height: 200px;
}
.p2:extend(.p1){
color: red;
}
//对应的CSS如下:
.p1,
.p2 {
width: 100px;
height: 200px;
}
.p2 {
color: red;
}
.p3{
//直接对指定的样式进行引用,这里就相当于将p1的样式在这里进行了复制
.p1();
}
//对应的CSS如下:
.p3 {
width: 100px;
height: 200px;
}
// 使用类选择器时可以在选择器后边添加一个括号,这时我们实际上就创建了一个mixins,即混合函数(专门给别人用而自己不用)。
.p4(){
width: 100px;
height: 100px;
}
.p5{
.p4;
}
//对应的CSS如下:
.p5 {
width: 100px;
height: 100px;
}
在混合函数中可以直接设置变量。
.test(@w:100px,@h:200px,@bg-color:red){
width: @w;
height: @h;
border: 1px solid @bg-color;
}
div{
//调用混合函数,按顺序传递参数
// .test(200px,300px,#bfa);
.test(300px);
// .test(@bg-color:red, @h:100px, @w:300px);
}
设置,扩展,Easy LESS configuration,在setting.json中编辑,在原有里面的最后一行代码加入一个,然后输入以下代码:
"less.compile": {
"compress": false, //是否压缩
"sourceMap": true, //是否生成源码(less和css映射文件)
"out": true // 是否生成CSS文件
}
JavaScript是高级语言。
JavaScript诞生于1995年,它的出现主要是用于处理网页中的前端验证。前端验证即检查用户输入的内容是否符合一定的规则,如用户名长度、密码长度、邮箱格式等。
ECMAScript是JavaScript标准。
一个完整的JavaScript实现应该由以下三部分构成:ECMAScript、DOM、BOM。
特点:
//我的第一个JS代码
在字符串中使用转义字符\输入Unicode编码。
//在JS中使用
console.log("\u0031"); //输出1
//在网页中使用:编码;【这里的编码需要采用十进制】
$#1
在JS中,
16进制数字以0x开头;
8进制以0开头;
2进制以0b开头(不是所有浏览器都支持);
//二进制
a=0b10;
像"070"这种字符串,有些浏览器会当成八进制解析,有些浏览器会当成十进制解析。
a="070";
可以在parseInt();中传递一个 第二个参数,用于指定数字的进制。
var a = "070";
//指定为八进制解析
a = parseInt(a,8);
console.log(typeof a);
console.log(a);
程序运行过程中也会产生垃圾。积攒过多,会导致程序运行的速度过慢。
当一个对象没有任何的变量或属性对它进行引用,此时将无法对它进行操作,
此时这种对象就是一个垃圾,过多会占用大量的内存空间,导致程序运行变慢。
JS中有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁。
我们需要做的只是将不再使用的对象设置null即可。
虽然可以写在标签的属性中,但是他们属于结构与行为耦合,不方便维护,不推荐使用。
将JS代码编写在外部JS文件中,然后通过script标签引入。
写到外部文件中可以在不同的页面中同时引用,也可以利用到浏览器的缓存机制。【推荐使用】
script标签一旦引入外部文件了,就不能再编写代码了,即使编写了浏览器也会忽略。如果需要,可以再创建一个新的script标签用于编写内部代码。
<script src="js/script.js"></script>
<script type="text/javascript">
alert("hello");
</script>
多行注释/**/
单行注释//
程序是由一条一条语句构成的。
语句是按照自上向下的顺序一条一条执行的。
在JS中可以使用{}来为语句进行分组。同一个{}中的语句称为一组语句,它们要么都执行要么都不执行。
JS中的代码块,只具有分组的作用,没有其他的用途。
{
alert("hello");
document.write("world");
console.log("hello world");
}
字面量都是一些不可改变的值,比如1、2、3、4
字面量都是可以直接使用,但是我们一般都不会直接使用字面量。
变量可以用来保存字面量,而且变量的值是可以任意改变的。
在开发中都是通过变量区保存一个自变量,而很少直接使用字面量。
可以通过变量名对字面量进行描述。如 var age=21;
使用var关键字来声明一个变量。
//声明变量
var a;
//为变量赋值
a=123;
//再控制台输出变量a的值
console.log(a);
//声明和赋值同时进行
var b=789;
console.log(b);
//不写var,就相当于window.a
a=123;
console.log("a="+a);
使用var关键字声明的变量,会在所有的代码执行之前被声明(但是不会赋值)。
但是如果声明变量时,不使用var关键则,则变量不会被声明提前。
console.log("a="+a);
var a=123;
其实相当于:
var a;
console.log("a="+a);
a=123;
//于是输出为:a=undefined
在JS中所有的可以由我们自主命名的都可以称为标识符。例如变量名、函数名、属性名。
命名一个标识符时需要遵守如下规则:
JS底层把保存标识符时实际上时采用的Unicode编码。所有理论上讲,所有的utf-8含有的内容都可以作为标识符。中文也可以用,但是最好不用。
数据类型指的是字面量的类型。
在JS中一共有六种数据类型:String 字符串、Number数值、Boolean布尔值、Null空值、Undefined未定义、Object对象。
在JS中使用字符串时需要使用引号引起来。使用双引号或单引号都可以。
var str="hello";
console.log(str);
console.log("hello");
str="我说:\"今天天气真不错!\"";
可以使用一个运算符typeof检查一个变量的类型。如检查字符串时返回"string",检查数值时返回"number"。
console.log(typeof b);
在JS中所有的数值都是Number类型,包括整数和浮点数(小数)。
JS中可以表示的数字的最大值:Number.MAX_VALUE。即1.7976931348623157e+308。
大于0(正值)的最小值:Number.MIN_VALUE。即5e-324。
console.log(Number.MAX_VALUE);
【❀特殊值:】
J如果使用Number表示的数字超过了最大值,则会返回一个Infinity,表示正无穷。-Infinity表示负无穷
NaN是一个特殊的数字,表示Not A Number。
运算:
在JS中整数的运算基本可以保证精确。
var c=1837874+34787;
console.log(c);
在JS中浮点数运算可能得到一个不精确的结果。所以千万不用使用JS进行对精度要求比较高的运算。
var c=0.1+0.2;
console.log(c);
//运算结果显示为0.30000000000000004
布尔值主要用来进行逻辑判断,布尔值只有两个:
var bool=true;
console.log(bool);
使用typeof检查一个布尔值时,会返回"boolean"。
Null类型的值只有一个,即null。
null这个值专门用来表示为空的对象。
使用typeof检查一个Null类型的值时会返回"object"。
Undefined类型的值只有一个,即undefined。
如果声明一个变量但是没有为变量赋值此时变量的值就是undefined。
var b;
console.log(b);
var b=undefined;
console.log(b);
使用typeof检查一个undefined时会返回"undefined"。
指将一个数据类型强制转换为其他的数据类型。
1️⃣调用被转换数据类型的toString()方法。
//该方法不会影响到原变量,它会将转换的结果返回。
var a=123;
//调用a的toString()方法
a.toString();
console.log(typeof a);
console.log(a);
//运算结果显示为:
// number
// 123
//因此此处我们将转换后的值赋值给变量b
var a = 123;
//调用a的toString()方法
var b = a.toString();
console.log(typeof b);
console.log(b);
//运算结果显示为:
// string
// 123
//也可以直接将转换后的值传给变量a
var a = 123;
//调用a的toString()方法
a = a.toString();
console.log(typeof a);
console.log(a);
//运算结果显示为:
// string
// 123
2️⃣调用String()函数,并将被转换的数据作为参数传递给函数。
使用String()函数做强制类型转换时,对于Number和Boolean实际上就是调用的toString()方法。
但是对于null和undefined,就不会调用toString()方法,而是直接将null直接转换为"null"(字符串)、undefined直接转换为"undefined"。
var a = 123;
//调用a的String()函数
a = String(a);
console.log(typeof a);
console.log(a);
//运算结果显示为:
// string
// 123
3️⃣隐式的类型转换:为任意数据类型+一个""即可将其转换为String。
由浏览器自动完成,实际上它也是调用了String()函数。
1️⃣调用Number()函数。
var s = "123";
s = Number(s);
console.log(typeof a);
console.log(a);
//运算结果显示为:
// number
// 123
var a = "abc";
a = Number(a);
console.log(typeof a);
console.log(a);
//运算结果显示为:
// number
// NaN
2️⃣调用parseInt()或parseFloat()
专门用来对付字符串。
var a = "123a789";
a = parseInt(a);
console.log(typeof a);
console.log(a);
//运算结果显示为:
// number
// 123
var a = "b123a789";
a = parseInt(a);
console.log(typeof a);
console.log(a);
//运算结果显示为:
// number
// NaN
var a = "123.789px";
a = parseFloat(a);
console.log(typeof a);
console.log(a);
//运算结果显示为:
// number
// 123.789
var a = "123.789.567px";
a = parseFloat(a);
console.log(typeof a);
console.log(a);
//运算结果显示为:
// number
// 123.789
如果对非String使用parseInt()或parseFloat(),它会先将其转换为String,然后再操作。
3️⃣隐式类型转换:通过为一个值-0或 *1或/1来将其转换为Numebr。
原理和Number()一样。
4️⃣可以对一个其他的数据类型使用+(表正号),来将其转换为number。
原理和Number()一样。
1️⃣调用Boolean()函数。
2️⃣为一个任意数据类型取两次反,即!!a。
原理和Boolean()一样。
JS中的变量都是保存到栈内存中的。
基本数据类型的值直接在栈内存中存储。值与值之间是独立存在,修改一个变量不会影响其他的变量。
对象是保存到堆内存中的。每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(即对象的引用)。如果两个变量保存的是同一个对象引用,当一个通过一个变量修改属性时,另一个也会受到影响。【指针】
(相当于对象是把变量和值的地址存放在栈内存中,而对象的值存储于堆内存中,最后通过指针读取数据)
var obj = new Object();
obj.name = "孙悟空";
var obj2 = obj;
//修改obj的name属性
obj.name = "猪八戒";
//当一个通过一个变量修改属性时,另一个也会受到影响。以下两个显示结果均为 猪八戒
console.log(obj.name);
console.log(obj2.name);
//设置obj2为null
obj2 = null;
//obj2链接对象的值的指针断开,但是obj1的指针没有影响。所以obj仍是object,obj2为null。
console.log(obj);
console.log(obj2);
当比较两个基本数据类型的值时,就是比较值。
而比较两个引用数据类型时,它是比较的对象的内存地址,如果两个对象是一摸一样的,但是地址不同,它也会返回false。
var obj3 = new Object();
var obj4 = new Object();
obj3.name = "沙和尚";
obj4.name = "沙和尚";
console.log(obj3 == obj4);
//运行显示结果为
//false
通过运算符可以对一个或多个值进行运算或操作。
typeof运算符:获得一个值的数据类型。它会将该值的类型以字符串的形式返回。
先级越高的越优先计算;优先级相同的,从左往右计算。
在下面优先级列表中越靠上的优先级越高:
可使用()来改变优先级。
####(1)算术运算符
当对非Number类型的值进行运算时,会将这些值转换为Number然后再运算。【除了字符串的+运算】
任何值和NaN做运算都得NaN。
任何值和字符串相加都会转换为字符串并做拼串操作。(可以利用这一特点将一个任意的数据类型转换为String:为任意数据类型+一个""即可将其转换为String——隐式的类型转换)。
任何值做-*/运算都会自动转换为Number(可以利用这一特点做隐式类型转换:通过为一个值-0或 *1或/1来将其转换为Numebr。原理和Number()一样)。
result = 1 + 2 + "3";
console.log("result=" + result);
// 运算结果显示为:
// result=33
result = "1" + 2 + 3;
console.log("result=" + result);
// 运算结果显示为:
// result=123
只需要一个操作数。
对于非Number类型,会先转换为Number类型,再运算。
可以对一个其他的数据类型使用+,来将其转换为number。他的原理和Number()一样。
自增++:可以使变量在自身的基础上加1。
//注意自增后原变量的值就变了
var d=20;
var result=d++ + ++d +d; //20+22+22
console.log("result="+result);
// 运算结果显示为:
// result=64
自减:可以使变量在自身的基础上减1。(同自增)
♍️!非:对一个值进行非运算。非运算即值对一个布尔值进行取反操作(true变false、false变true)。
♍️&&与:对符号两侧的值进行与运算并返回结果。
♍️||或:对符号两侧的值进行或运算并返回结果。
♍️&& ||非布尔值的情况:
//与运算:如果两个值都为true,则返回后边的值。
var d=5&&4;
console.log("d="+d);
// 运算结果显示为:
// d=4
=:可以将符号右侧的值赋值给符号左侧的变量。
+=:a=a+5即可表示为a+=5。
-=
*=
/=
%=
通过关系运算符可以比较两个值之间的大小关系。如果关系成立会返回true,如果不成立返回false。
包括>、>=、<、<=
✴️非数值的情况:对于非数值情况,会将其转换成数字,再进行比较。
任何值和NaN做任何比较都是false。
如果符号两侧的值都是字符串,不会将其转换为数字比较,而会分别比较字符串中字符的Unicode编码。
比较字符编码时是一位一位进行比较,若相同才比较下一位。(可以借用它来对英文进行排序。。比较中文没有意义。。如果比较的两个字符串型的数字,可能会得到不可预期的效果,因此一定一定一定要转型)
//"hello"转换为数字为NaN。任何值和NaN做任何比较都是false。
console.log(10<="hello");
// 运算结果显示为:
// false
//比较字符串中字符的Unicode编码
console.log("11" < "5");
// 运算结果显示为:
// true
//比较字符串中字符的Unicode编码
console.log("a" < "b");
// 运算结果显示为:
// true
//比较字符编码时是一位一位进行比较,若相同才比较下一位
console.log("abc" < "b");
// 运算结果显示为:
// true
==:相等运算符用来比较两个值是否相等,若相等返回true,不相等返回false。
!=:不相等运算符用来比较两个值是否不相等,若不相等返回true,相等返回false。
===:全等,用来判断两个值是否全等,它和相等类似,但是全等不会进行类型转换。如果两个值的类型不同,直接返回false。
!==:不全等,用来判断两个值是否不全等,它和不相等类似,但是不全等不会进行类型转换。如果两个值的类型不同,直接返回true。
条件运算符也叫三元运算符。
语法: 条件表达式?语句1:语句2;
执行的流程:首先对条件表达式进行求值,如果该值为true,则执行语句1并返回结果;若该值为false,则执行语句2并返回执行结果。
var a=30;
var b=45;
var c=23;
//获取a和b中的最大值
var max=a>b ? a : b;
//获取a、b和c中的最大值
max =max>c ? max : c;
//获取a、b和c中的最大值。不推荐
var max= a>b ? (a>c ? a : c ) : (b>c ? b : c);
使用,可以分割多个语句,一般可以在声明多个变量时使用。
通过流程控制语句可以控制程序执行流程,使程序可以根据一定的条件来选择执行。
使用条件判断语句可以在执行某个语句之前进行判断,如果条件成立才会执行语句,条件不成立则语句不成立。
if语句
语法:
1️⃣if(条件表达式){
语句
}
2️⃣if(条件表达式){
语句…
}else{
语句…
}
3️⃣if(条件表达式){
语句…
}else if(条件表达式){
语句…
}else if(条件表达式){
语句…
}else if(条件表达式){
语句…
}else{
语句…
}
自上至下依次对条件表达式进行求值判断:
如果判断结果为true则执行当前if后的语句,执行完成后语句结束;
如果判断结果为false,则继续向下判断,直到找到为true的为止;
如果所有的条件表达式都是false,则执行else后的语句。
该语句中只会有一个代码块被执行,一旦被执行了,则语句结束。
练习1:键入成绩并判断对应的奖品
练习2:键入3个整数,对其排序并按从小到大输出。
//思路可如下
条件分支语句也叫switch语句。
switch语句
语法:
switch(条件表达式){
case 表达式:
语句…
break;
case 表达式:
语句…
break;
case 表达式:
语句…
break;
default:
语句…
break;
}
switch语句和if语句的功能实际上有重复的,使用switch可以实现if的功能,同样使用if也可以实现switch的功能,所以使用时可以根据自己的习惯选择。
练习1:对于成绩大于60分的,输出’合格’。低于60分的,输出’不合格’。
//法一:
//法二
通过循环语句可以反复地执行一段代码多次。
创建一个循环,往往需要三个步骤:
1️⃣创初始化一个变量
2️⃣在循环中设置一个条件表达式
3️⃣定义一个更新表达式,每次更新初始化变量
//1.创初始化一个变量
var i = 11;
//2.在循环中设置一个条件表达式
while(i <= 10){
//3.定义一个更新表达式,每次更新初始化变量
document.write(i++ +"
")
}*/
语法:
while(条件表达式){
语句…
}
执行流程:先对条件表达式进行求值判断,如果值为true则执行循环体,循环体执行完毕后继续对表达式进行判断,如果为true仍继续执行循环体,依次类推…如果值为false则终止循环。
死循环:向条件表达式写死为true的循环。该循环不会停止,除非浏览器关闭。(在开发中慎用)。
while(true){
alert(n++);
}
可以使用break终止循环。
while(true){
alert(n++);
//判断n是否是10
if(n == 10){
//退出循环
break;
}
语法:
do{
语句…
}while(条件表达式)
执行流程:do…while语句在执行时,会先执行循环体,循环体执行完毕以后,在对while后的条件表达式进行判断,如果结果为true,则继续执行循环体,执行完毕继续判断以此类推…如果结果为false,则终止循环。
实际上这两个语句功能类似,不同的是while是先判断后执行,而do…while会先执行后判断。do…while可以保证循环体至少执行一次,而while不能。
练习1:假如投资的年利率为5%,试求从1000块增长到5000块,需要花费多少年?
练习2:从键盘输入小明的期末成绩:当成绩为100时,‘奖励一辆BMW’;当成绩为[80-99]时,‘奖励一台iphone15s’;当成绩为[60-80]时,‘奖励一本参考书’;其他时,什么奖励也没有。
for语句,也是一个循环语句,也称为for循环。
在for循环中,为我们提供了专门的位置用来放三个表达式:初始化表达式、条件表达式、更新表达式。
//创建一个执行10次的while循环
for(var i = 0 ; i < 10 ; i++ ){
alert(i);
}
语法:
for(①初始化表达式;②条件表达式;④更新表达式){
③语句…
}
执行流程:
for循环中的三个部分都可以省略,也可以写在外部。
//死循环
for(;;){
alert("hello");
}
练习1:打印1-100之间所有奇数之和。
练习2:打印1-100之间所有7的倍数的个数及总和。
练习3:水仙花数是指一个3位数,它的每个位上的数字的3 次幂之和等于它本身。(例如:1^3 + 5^3 + 3^3 = 153),请打印三位数所有的水仙花数。
练习4:在页面中接收一个用户输入的数字,并判断该数是否是质数。
质数:只能被1和它自身整除的数,1不是质数也不是合数,质数必须是大于1的自然数。
练习1:阶级*号的显示。
练习2:九九乘法表
练习3:打印1-100之间所有的质数。
不能在if语句中使用break和continue。
//注意此处是正确的。因为break实际上是对for循环起作用。
for(var i=0 ; i<5 ; i++){
console.log(i);
if(i == 2){
break;
}
}
break关键字可以用来退出switch或循环语句。
continue关键字可以用来跳过当次循环。同样continue也是默认只会对离他最近的循环循环起作用。
可以为循环语句创建一个label标签,用于来标识当前的循环。
语法:label:循环语句
使用break语句时,可以在break后跟着一个label,这样break将会结束指定的循环,而不是最近的。【continue同样适用】
outer:
for(var i=0 ; i<5 ; i++){
console.log("@外层循环"+i)
for(var j=0 ; j<5; j++){
//outer终止的是外层循环
break outer;
console.log("内层循环:"+j);
}
}
不属于基本数据类型的值全是对象。
基本数据类型都是单一的值"hello" 123 true,值和值之间没有任何的联系。
对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。
1️⃣内建对象
由ES标准中定义的对象,在任何的ES的实现中都可以使用。比如:Math、String、Number、Boolean、Function、Object…
2️⃣宿主对象
由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象。比如 BOM、DOM
3️⃣自定义对象
由开发人员自己创建的对象。
创建对象:使用new关键字调用的函数,是构造函数constructor。构造函数是专门用来创建对象的函数。【使用typeof检查一个对象时,会返回object】
//空对象
var obj = new Object();
向对象添加属性:(在对象中保存的值称为属性)
//向obj中添加一个name属性
obj.name = "孙悟空";
//向obj中添加一个gender属性
obj.gender = "男";
//向obj中添加一个age属性
obj.age = 18;
读取对象中的属性:
console.log(obj.gender);
//如果读取对象中没有的属性,不会报错而是会返回undefined
console.log(obj.hello);
修改对象的属性值:
obj.name = "tom";
删除对象的属性:
delete obj.name;
属性名:对象的属性名不强制要求遵守标识符的规范。(但是我们使用时还是尽量按照标识符的规范去做)
如果要使用特殊的属性名,不能采用.的方式来操作,需要使用另一种方式:(读取时也需要采用这种方式)
语法:对象[“属性名”] = 属性值
obj["nihao"] = "你好";
使用[]这种形式去操作属性,更加的灵活。在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性。
var n = "nihao";
console.log(obj["123"]);
//控制台打印出 你好
函数也可以作为对象的属性:如果一个函数作为一个对象的属性保存,那么我们称这个函数是这个对象的方法;调用函数就说调用对象的方法。
【但是他只是名称上的区别,其他没有区别】
//调方法
obj.sayName();
//调函数
fun();
属性值:JS对象的属性值,可以是任意的数据类型(可以是个函数,也可以是一个对象)。
//函数可以作为属性值
var obj = new Object();
obj.name = "孙悟空";
obj.sayName=function(){
console.log(obj.name);
};
obj.sayName();
<也可以如下写>
var obj2={
name:"猪八戒";
age:18;
sayName:function(){
console.log(obj2.name);
};
};
in 运算符:通过该运算符可以检查一个对象中是否含有指定的属性。如果有则返回true,没有则返回false。
语法:
“属性名” in 对象
console.log("name" in obj);
使用对象字面量,可以在创建对象时,直接指定对象中的属性。
var obj2 = {
name:"猪八戒",
age:13,
gender:"男",
test:{name:"沙僧"}
};
使用for…in语句
语法:
for(var 变量 in 对象){
}
for…in语句:对象中有几个属性,循环体就会执行几次;每次执行时,会将对象中的一个属性的名字赋值给变量
var obj={
name:"猪八戒",
age:13,
gender:"男",
};
//n即属性名
for(var n in obj){
console.log("属性名:"+n);
//打印出对应的属性值
console.log("属性值"+obj[n]);
}
通过该方法可以大批量创建对象。
function create Person(name,age,gender){
//创建一个新的对象
var obj=new Object();
//向对象中添加属性
obj.name=name;
obj.age=age;
obj.gender=gender;
obj.sayName=function(){
alert(this.name);
};
//将新的对象返回
return obj;
}
var obj2=create Person("孙悟空",18,"男");
console.log(obj2);
使用工厂方法创建的对象,使用的构造函数都是Object,所有创建的对象都是Object类型,无法区分出多种不同类型的对象。
我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype。
prototype属性对应着一个对象,这个对象就是原型对象。
❗【原型对象里还有一个原型】
如果函数作为普通函数调用,prototype没有任何作用。
如果函数以构造函数的形式调用,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象。我们可以通过__proto__来访问该属性。
function MyClass(){
}
var mc=new MyClass();
console.log(mc.__proto__==MyClass.prototype);
原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象。我们可以将对象中共有的内容,统一设置到原型对象中。
当我们访问对象的一个属性或方法时,会现在对象【自身】中寻找,如果直接使用;如果没有则会去【原型对象】中寻找,如果找到则直接使用;如果还没有,则去【原型的原型】中寻找,直到找到【Object对象的原型】。
❗Object对象的原型没有原型,如果在Object中依然没有找到,则返回undefined。
function MyClass(){
}
//向MyClass的原型中添加属性a
MyClass.prototype.a=123;
//向MyClass的原型中添加一个方法sayHello
MyClass.prototype.sayHello=function(){
alert("hello");
};
var mc=new MyClass();
console.log(mc.__proto__==MyClass.prototype);
console.log(mc.a);
mc.sayHello();
因此创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中。
使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true。
可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性。
返回true或者false。
只有当对象自身中含有属性时,才会返回true。
console.log(mc.hasOwnProperty("name"));
hasOwnProperty在原型的原型里。
测试:
console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));
当我们直接在页面中打印一个对象时,事件上是输出的对象的toString()方法的返回值。
如果希望在输出对象时不输出[object Object],可以为对象添加一个toString()方法。
per.toString=function(){
return "person"
};
var result=per.toString();
console.log("result="+result);
表示一个时间。
创建一个Date对象
var d=new Date();
console.log(d);
创建一个指定的时间对象
需要在构造函数中传递一个表示时间的字符串作为参数。
日期的格式 月/日/年/ 时:分:秒(年份注意写完整的,避免歧义)
var d2=new Date("12/03/2022 11:12:12");
console.log(d2);
getDate()获取当前日期是几日。
var date=d.getDate();
getDay()获取当前日期对象是周几。会返回0-6的值,0表示周日,1表示周一…
getMonth()获取当前日期对象的月份,会返回一个0-11的值,0表示一月。
getFullYear()获取当前日期对象的年份。
getHours()
getMinutes()
getTime()获取当前日期对象的时间戳。
//获取当前的时间戳
time =Date.now();
//利用时间戳来测试代码的执行性能
var start=Date.now();
for(var i=0;i<100;i++){
console.log(i);
}
var end=Date.now();
console.log("执行了:"+(end-start)+"毫秒");
它不是一个构造函数,属于一个工具类。不用创建对象,它里面封装了数学运算相关的属性和方法。
Math.PI表示圆周率。
abs()计算一个数的绝对值。
ceil()对一个数进行向上取整,(小数位有值则自动进1)。
floor()对一个数向下取整,(小数部分会被舍掉)。
round()四舍五入取整
random()生成0-1之间的随机数。
//生成一个0-10的随机数
Math.round(Math.random()*10)
//生成一个0-x的随机数
Math.round(Math.random()*x)
//生成一个1-10的随机数
Math.round(Math.random()*9)+1
//生成一个x-y的随机数
Math.round(Math.random()*(y-x))+x
max()获取多个数中最大值
min()最小值
Math.pow(x,y)返回x的y次幂
sqrt()开方
函数也是一个对象。
函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码)。
函数中可以保存一些代码在需要的时候调用。
使用typeof检查一个函数对象时,会返回function。
创建一个函数对象
var fun = new Function("console.log('Hello 这是我的第一个函数');");
调用函数
fun();
语法:
function 函数名([形参1,形参2…形参N]){
语句…
}
function fun2(){
console.log("这是我的第二个函数~~~");
alert("哈哈哈哈哈");
document.write("~~~~(>_<)~~~~");
}
//调用fun2
fun2();
语法:
var 函数名 = function([形参1,形参2…形参N]){
语句…
}
var fun3 = function(){
console.log("我是匿名函数中封装的代码");
};
fun3();
可以在函数的()中来指定一个或多个形参(形式参数)。
在调用函数时,可以在()中指定实参(实际参数)。
//定义一个用来求两个数和的函数
//在函数的()中指定形参
function sum(a,b){
console.log("a = "+a);
console.log("b = "+b);
console.log(a+b);
}
//调用函数时,在()中指定实参
sum(123,456);
解析器在调用函数时每次都会向函数内部传递进一个隐含的参数,即this
可以使用 return 来设置函数的返回值。
语法:
return 值
return后的值将会会作为函数的执行结果返回,可以定义一个变量,来接收该结果。
在函数中return后的语句都不会执行。
如果return语句后不跟任何值就相当于返回一个undefined;如果函数中不写return,则也会返回undefined;return后可以跟任意类型的值
返回值可以是任意的数据类型,可以是一个对象。也可以是一个函数。
立即执行函数:函数定义完立即被调用。往往只执行一次
//
(function(){
alert("我是一个立即执行函数");
})();
(function(a,b){
console.log("a="+a);
console.log("b="+b);
})(123,456);
使用函数声明形式创建的函数:function 函数(){}
使用函数表达式创建的函数,不会声明提前,因此不可以在函数声明之前调用函数。
作用域:一个变量的作用的范围。
直接编写在script标签中的JS代码,都在全局作用域。
全局作用域中的变量都是全局变量,在页面的任意的部分都可以访问到。
在函数中访问全局变量可以使用window对象。
在函数作用域中也有声明提前的特性,使用var关键字声明的变量,也会在函数中所有的代码执行之前被声明。函数声明也会在函数在所有的代码执行之前执行。
❗在函数中,不使用var声明的变量都会成为全局变量。
var c=33;
function fun5(){
c=10;
}
fun5();
console.log("c="+c);
//输出结果:c=10
function fun6(){
d=100;
}
fun6();
console.log("d="+d);
//输出结果:d=100
定义形参就相当于在函数作v 用域中声明了变量。
function fun7(a){
a=456;
}
构造函数习惯上首字母大写。
构造函数和普通函数的区别就是调用方式的不同:
构造函数的执行流程:
①立刻创建一个新的对象;
②将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建的对象;
③逐行执行函数中的代码
④将新建的对象作为返回值返回
使用同一构造函数创建的对象,成为一类对象;也称一个构造函数称为一个类。
将通过一个构造函数创建的对象称为该类的实例。
function Person(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
//向对象中添加一个方法
this.sayName=function(){
alert(this.name);
};
}
var per = new Person("孙悟空",12,"男");
console.log(per);
在Person构造函数中,为每一个对象都添加了一个sayName方法。
在构造函数内部创建的:每执行一次构造函数,就会创建一个新的sayName方法。
所有实例的sayName都是唯一的。这样就导致了构造函数执行一次就会创建一个新的方法,而这些方法都是一样的。----------->这是没有必要的,因此可以使所有的对象共享同一个方法。
因此优化修改如下:(将sayName方法在全局作用域中定义)
function Person(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
//向对象中添加一个方法
this.sayName=fun;
};
}
//将sayName方法在全局作用域中定义
function fun(){
alert(this.name);
};
var per = new Person("孙悟空",12,"男");
console.log(per);
这样写的坏处:将函数定义在全局作用域,污染了全局作用域的命名空间,而且定义在全局作用域中也不安全。
因此修改优化如下:(向原型中添加sayName方法)
function Person(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
}
//向原型中添加sayName方法
Person.prototype.sayName=function(){
alert(this.name);
};
var per = new Person("孙悟空",12,"男");
console.log(per);
使用instanceof可以检查一个对象是否是一个类的实例。
所有的对象都是Object的后代;
所以任何对象和Object做instanceof检查时都会返回true
函数对象的方法,需要通过函数对象来调用。
可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行时的this。
可以将实参在对象之后依次传递
fun.call(obj,2,3);
函数对象的方法,需要通过函数对象来调用。
可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行时的this。
需要将实参封装到一个数组中统一传递。
fun.apply(obj,[2,3]);
在调用函数时,浏览器每次都会传递两个隐含的参数
①函数的上下文对象this
②封装实参的对象arguments
数组也是一个对象。
区别:
PS:索引即从0开始的整数。
向数组中添加元素
读取数组中元素
//创建数组对象
var arr=new Array();
//向数组中添加元素
arr[0]=10;
//读取数组中元素
console.log(arr[0]);
使用构造函数创建数组时,也可以同时添加元素,将要添加的元素作为构造函数的参数传递。
var arr=new Array(10,20,30);
获取数组的长度length属性
❗尽量不要创建非连续的数组
修改length:
如果修改的length大于原长度,则多出部分会空出来;
若小于原长度,则多出的元素会被删除。
arr[arr.length]=70;
使用字面量来创建数组
var arr=[];
使用字面量创建数组时,可以在创建时就指定数组中的元素。
var arr=[1,2,3,4,5,10];
区别:
- arr=[10]; //创建一个数组元素中只有一个元素10
- var arr=[10]; //创建一个长度为10的数组
数组中的元素可以是任意的数据类型。
如
arr=["hello",1,true,null,undefined];
也可以是对象。
var obj={name:"孙悟空"};
arr[arr.length]=obj;
arr=[{name:"孙悟空"},{name:"猪八戒"}];
也可以是一个函数。
arr=[function(){alert(1)},function(){alert(2)}];
数组中也可以放数组,如下这种称为二维数组。
arr=[[1,2,3],[4,5,6]];
该方法可以向数组的末尾添加一个或多个元素,并返回数组的新的长度。
可以将要添加的元素作为方法的参数传递,这样这些元素将会自动添加到数组的末尾。
arr.push("孙悟空","猪八戒","沙和尚");
该方法删除数组的最后一个元素,并将删除的元素作为返回值返回。
arr.pop();
该方法向数组开头添加一个或多个元素,并返回新的数组长度。
向前边插入元素以后,其他元素的索引会依次调整。
arr.unshift("牛魔王","红孩儿");
删除并返回数组的第一个元素
arr.shift();
该方法用于遍历数组。
❗需要一个函数作为参数。
var arr=["孙悟空","猪八戒","红孩儿"];
function fun(){
}
arr.forEach(fun());
一般像如下写:
var arr=["孙悟空","猪八戒","红孩儿"];
arr.forEach(function(){
console.log("hello");
});
像上述函数,由我们创建但是不由我们调用的(浏览器调用),称为回调函数。
数组中有几个元素,函数就会执行几次。每次执行时,浏览器会将遍历到的元素以实参的形式传递进来
var arr=["孙悟空","猪八戒","红孩儿"];
arr.forEach(function(a){
console.log("a="+a);
});
(我们可以定义形参来读取这些内容)
浏览器会在回调函数中传递三个参数:
①当前正在遍历的元素
②当前正在遍历的元素的索引
③正在遍历的数组
var arr=["孙悟空","猪八戒","红孩儿"];
arr.forEach(function(value,index,obj){
console.log(value);
});
从某数组中提取出指定元素。
该方法不会改变元素数组,而是将截取到的元素封装到一个新数组中返回。
参数:
①截取开始的位置的索引
②截取结束的位置的索引(可以省略不写,此时会截取从开始索引到以后的所有元素)
索引可以传递一个负值。如果传递一个赋值,则从后往前计算。(如-1即倒数第一个)
var arr=["孙悟空","猪八戒","红孩儿"];
var result= arr.slice(0,2);
console.log(result);
删除数组中的指定元素。
会影响到原数组,会将指定元素从原数组中删除,并将被删除的元素作为返回值返回。
参数:
①开始位置的索引
②删除的数量
③及以后:可以传递一些新的元素,这些元素将会自动插入到开始位置索引的前面
arr.splice(0,2,"牛魔王","红孩儿","铁扇公主");
连接两个或多个数组,并将新的数组返回。
不会对原数组产生影响。
可以传数组,也可以传单一元素
var result=arr.concat(arr2,arr,"牛魔王");
将数组转换为一个字符串。
不会对原数组产生影响,而是将转换后的字符串作为结果返回。
指定一个字符串作为参数,这个字符串将会成为数组中元素的连接符。
如果不指定连接符,则默认使用,作为连接符。
arr=["牛魔王","红孩儿","铁扇公主"];
result=arr.join("@");
反转数组(前边的去后边,后边的去前边)。
会直接修改原数组。
对数组中的元素进行排序。
会影响原数组,默认会按照Unicode编码进行排序。
【纯数字,也会按照Unicode编码进行排序。(因此可能得到错误结果)】
我们可以自己指定排序规则。
—在sort()添加一个回调函数,来指定排序规则。
升序排列
return a-b;
降序排列
return b-a;
arr=[5,4];
arr.sort(function(a,b){
if(a>b){
return 1;
}else if(a
arr=[5,4];
arr.sort(function(a,b){
//升序排列
return a-b;
//降序排列
return b-a;
});
遍历数组即将数组中所有的元素都取出来。
for(var i=0;i
JS提供三个包装类,可以将基本数据类型的数据转换为对象。
String()将基本数据类型字符串转换为String对象
var str= new String("hello");
Number()将基本数据类型的数字转换为Number对象
var num= new Number(3);
//向num中添加一个属性
num.hello="nihao";
Boolean()将基本数据类型的布尔值转换为Boolean对象
var bool= new Boolean(true);
❗注意:在实际应用中不会使用基本数据类型的对象。如果使用基本数据类型的对象,在做一些比较时可能会带来一些不可预期的结果。
❗方法和属性只能添加给对象,不能添加给基本数据类型。
当我们对一些基本数据类型的值去调用属性和方法时,浏览器会临时使用包装类将其转换为对象,然后再调用对象属性和方法,调用完以后,再将其转换为基本数据类型。
字符串在底层是以字符数组的形式保存的。
如[“H”,“e”,“l”];
创建一个字符串
var str="hello";
length获取字符串长度
charAt()返回字符串中指定位置的字符。根据索引获取指定的字符。
charCodeAt()获取指定位置字符的字符编码(Unicode编码)。
fromCharCode()根据字符编码获取字符。
concat()连接两个或多个字符串。
indexOf()检索一个字符串中是否含有指定内容。【从前往后找】
str="abc,bcd,efg,hij";
result=str.split("d");
//也可以传递一个空串作为参数,则会将每个字符都拆分为数组中的一个元素
result=str.split("");
toLowerCase()将一个字符串转换为小写并返回。
toUpperCase()将一个字符串转换为大写并返回。
正则表达式用于定义一些字符串的规则。
计算机可以根据正则表达式,检查一个字符串是否符合规则,获取将字符串中符合规则的内容提取出来。
语法:
var 变量=new RegExp(“正则表达式”,“匹配模式”);
【使用typeof检查,会返回object】
//检查一个字符串中是否含有a
var reg=new RegExp("a","i");
语法:
var 变量=/正则表达式/匹配模式
reg=/a/i;
|表示或
[]里的内容也是或的关系
[ab]==a|b
[a-z]任意小写字母
[A-Z]任意大写字母
[A-z]任意字母
[^ ]表示除了
//检查一个字符串中是否有a或b
reg=/a|b/;
//检查是否有字母
reg1=/[A-z]/;
//检查是否含有abc或adc或aec
reg2=/a[bde]c/;
//检查是否含有任意数字。
reg3=/[0-9]/;
量词:设置一个内容出现的次数。
❗两次只对它前面的一个内容起作用
{n} 正好出现n次
{m,n} 出现m-n次
{m,} 出现m次以上
+ 至少一个,相当于{1,}
* 0个或多个,相当于{0,}
? 0个或1个,相当于{0,1}
^ 表示开头
[^ ] 表示除了
$ 表示结尾
. 表示任意字符
ps:如果在正则表达式中同时使用^ $,则要求字符串必须完全符合正则表达式。
❗注意:使用构造函数时,由于它的参数是一个字符串,而\是字符串中转义字符,如果要使用 \ 则需要使用 \ 来代替。
如:reg=new RegExp(“\.”);
//a出现3次
var reg=/a{3}/;
//ab出现3次
var reg=/(ab){3}/;
//b出现1到3次
var reg=/ab{1,3}c/;
//是否以a开头
reg=/^a/;
//是否以a结尾
reg=/a$/;
//是否含有.
// 正则表达式中\作为转义字符,用\.表示.
var reg=/\./;
//使用构造函数时,要使用 \ 需要使用 \\ 来代替。
reg=new RegExp("\\.");
\w 任意字母、数字、下划线_
\W 除了字母、数字、下划线_
\d 任意数字[0-9]
\D 除了任意数字[^0-9]
\s 空格
\S 除了空格
\b 单词边界
\B 除了单词边界
//检查一个字符串中是否含有单词child
reg = /\bchild\b/;
console.log(reg.test("hello child"));
去除字符串空格就是用""代替空格
//去除字符串开头和结尾任意个空格
str=str.replace(/^\s*|\s*$/g,"");
手机号规则(11位)
//检查一个字符串是否是一个合法的手机号
var phoneStr="13098321231";
var phoneReg=/^1[3-9][0-9]{9}$/;
console.log(phoneReg.test(phoneStr));
格式:
任意字母数字下划线 . 任意字母数字下划线 @ 任意字母数字 . 任意字母(2-5位) . 任意字母(2-5位)
\w{3,} (.\w+)* @ [A-z0-9]+ (.[A-z]{2,5}){1,2}
var emailReg=/^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;
test()检查一个字符串是否符合正则表达式的规则。符合则返回true,否则返回false。
将一个字符串拆分为一个数组。
这个方法即使不指定全局匹配,也会全部拆分
//根据任意字母将字符串拆分-方法中可以传递一个正则表达式作为参数
var str="1h2h312h314h1";
var result=str.split(/[A-z]/);
搜索字符串中是否含有指定内容。
❗只会查找第一个,即使设置全局匹配也没用。
根据正则表达式,从一个字符串中将符合条件的内容提取出来。
默认情况下match只会找到第一个符合要求的内容,找到后就停止检索。
match()会将匹配到的内容封装在一个数组中返回,即使只查询到一个结果。
将字符串中指定内容替换为新的内容。
参数:
①被替换的内容,可以接受一个正则表达式作为参数
②新的内容
默认只会替换第一个。
浏览器已经提供文档节点,这个对象是window属性。可以在页面中直接使用,文档节点代表的是整个网页。
在事件对应的属性中设置js代码,当事件被触发时,这些代码将会执行。
可以为按钮的对应事件绑定处理函数的形式来响应事件,这样当事件被触发时,其对应的函数将会被调用。
为单击事件绑定的函数,称为单击响应函数。
<button id="btn">按钮button>
//获取按钮对象
<script>
var btn=document.getElementById("btn");
//绑定一个单击事件,为单击事件绑定的函数,称为单击响应函数
btn.onclick=function(){
alert("点击按钮");
};
script>
onload事件会在整个页面加载完成之后才触发。
该事件对应的响应函数将会在页面加载完成之后执行,这样可以确保代码执行时所有的DOM对象已经加载完毕。
window.οnlοad=function(){
var btn=document.getElementById("btn");
btn.οnclick=function(){
alert("点击按钮");
};
};
innerHTML这个属性可以获取到元素内部的html代码。
如果需要读取元素节点的属性,直接使用【元素.属性名】
innerText获取元素内部的文本内容。和innerHTML类似,不同的是它会自动将html去除。
ps:getElementsByTagName()会返回一个类数组对象,所有查询到的元素都会封装到对象中。(即使查询到的元素只有一个,也会封装到数组中返回)
ps:
①childNodes会获取包括文本节点在内的所有节点。根据DOM标签标准,标签间空白也会当成文本节点。【注意IE8即以下的浏览器中,不会吧空白文本当成子节点】
②firstChild可以获取到当前元素的第一个子节点(包括空白文本节点)。
③firstElementChild获取当前元素的第一个子元素。(不支持IE8即以下的浏览器)
previousSibling也可能获取到空白的文本。
previousElementSibling获取前一个兄弟元素。(不支持IE8即以下的浏览器)
document.body 获取页面中的body元素。
document.documentElement 获取html根标签。
document.all 获取页面中所有的元素。
getElementsByClassName() 可以根据元素的class属性值查询一组元素节点对象。(不支持IE8即以下的浏览器)
var box1=document.getElementsByClassName("box1");
<div class="box1">div>
document.querySelector() 可以根据一个css选择器来查询一个元素节点对象。
document.querySelectorAll()
document.createElement(“TagName”) 创建元素节点对象。
appendChild() 向父节点中添加指定的子节点
insertBefore() 在指定的子节点前插入新的子节点
replaceChild() 使用一个新的节点去替换旧节点
removeChild() 删除指定的子节点
ps:先获取到父节点,再删除
使用innerHTML也可以实现DOM的增删改的相关操作。如:
(一般会两种方式结合使用,见下方代码2)
city.innerHTML += "<li>广州li>";
myClick("btn07",function(){
//向city中添加广州
var city = document.getElementById("city");
/*
* 使用innerHTML也可以完成DOM的增删改的相关操作
* 一般我们会两种方式结合使用
*/
//创建一个li
var li = document.createElement("li");
//向li中设置文本
li.innerHTML = "广州";
//将li添加到city中
city.appendChild(li);
});
通过style属性设置的样式都是内联样式,而内联样式有较高的优先级,所以通过JS修改的样式往往会立即显示。
但是如果在样式中写了【!important】,则此时样式会有最高的优先级,即使通过JS也不能覆盖改样式,此时将会导致JS修改样式失效。所以尽量不要为样式添加!important。
通过JS修改元素的样式
ps:如果CSS的样式名中含有-,这种名称在JS在是不合法的(比如background-color),需要将这种样式名修改为驼峰命名法(去掉-,然后将-后的字母大写)。
读取元素的样式
getComputedStyle()获取元素当前显示的样式。
//定义一个函数,用来获取指定元素的当前的样式(保证浏览器兼容)
//参数:obj要获取样式的元素 name要获取的样式名
function getStyle(obj,name){
//注意这里必须要加window,否则ie8中会报错
if(window.getComputedStyle){
//正常浏览器的方式
return getComputedStyle(obj,null)[name];
}else{
//IE8的方式
return obj.currentStyle[name];
}
}
currentStyle
❗通过currentStyle和getComputedStyle()读取到的样式都是只读的,不能修改。
如果要修改只能通过style属性
clientWidth和clientHeight 可以获取元素的可见宽度和高度。
offsetWidth和offsetHeight 获取元素的整个的宽度和高度,包括内容去、内边距、边框。
offsetParent 获取当前元素的定位父元素
scollWidth和scollHeight 可以获取元素整个滚动区域的宽度高度。
scollLeft 获取水平滚动条滚动的距离。
当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数。
在事件对象中封装了当前事件相关的一切信息,比如鼠标的坐标、键盘哪个键被按下等。
//解决事件对象兼容性问题
元素.事件 = function(event){
event = event || window.event;
};
元素.事件 = function(e){
e = e || event;
};
onmousemove 该事件将会在鼠标在元素中移动时被触发。
clientX 获取鼠标指针的水平坐标
clientY 获取鼠标指针的垂直坐标
事件的冒泡指的是事件向上传导,当后代元素上的事件被触发时,将会导致其祖先元素上的同类事件也会触发。
事件的冒泡大部分情况下都是有益的,如果需要取消冒泡,则需要使用事件对象来取消冒泡。
元素.事件 = function(event){
event = event || window.event;
event.cancelBubble = true;
};
指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。
target
使用【对象.事件=函数】的形式绑定响应函数,只能同时为一个元素的一个事件绑定一个响应函数。
addEventListener() 为元素绑定响应函数
参数:
①事件的字符串,注意不要on。【如btn01.addEventListener(“click”);】
②回调函数,当事件触发时该函数会被调用
③是否在捕获阶段触发事件,需要一个布尔值,一般都传false
使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数。这样当事件被触发时,响应函数将会按照函数的绑定顺序执行。
(这个方法不支持IE8及以下的浏览器)
btn01.addEventListener("click",function(){
alert(1);
},false);
btn01.addEventListener("click",function(){
alert(2);
},false);
attachEvent() 在IE8中可以用来绑定事件
btn01.attachEvent("onclick",function(){
alert(1);
});
btn01.attachEvent("onclick",function(){
alert(2);
});
//定义一个函数,用来为指定元素绑定响应函数
/*
* addEventListener()中的this,是绑定事件的对象
* attachEvent()中的this,是window
* 因此需要统一两个方法this
*/
/*
* 参数:
* obj 要绑定事件的对象
* eventStr 事件的字符串(不要on)
* callback 回调函数
*/
function bind(obj , eventStr , callback){
if(obj.addEventListener){
//大部分浏览器兼容的方式
obj.addEventListener(eventStr , callback , false);
}else{
/*
* this是谁由调用方式决定
* callback.call(obj)
*/
//IE8及以下
obj.attachEvent("on"+eventStr , function(){
//在匿名函数中调用回调函数
callback.call(obj);
});
}
}
关于事件的传播网景公司和微软公司有不同的理解:
W3C综合了两个公司的方案,将事件传播分成了三个阶段:
如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true
一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false
(IE8及以下的浏览器中没有捕获阶段)
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>图片切换练习title>
head>
<body>
<div id="content">
<p id="info">当前是第1张图片,一共3张p>
<img src="./img/pic1.jpg">
<br />
<button type="button" id="prev">上一张button>
<button type="button" id="next">下一张button>
div>
body>
html>
<script type="text/javascript">
// 点击按钮切换图片
var prev = document.getElementById("prev");
var next = document.getElementById("next");
// 获取info
var info = document.getElementById("info");
// 注意方法返回的是类数组
var img = document.getElementsByTagName("img")[0];
console.log(img)
// 使用数组保存图片路径
var imglist = ["./img/pic1.jpg","./img/pic2.jpg","./img/pic3.jpg"]
// 正在显示图片的索引
var temp = 0;
prev.onclick = function(){
temp--;
// 实现循环
if(temp<0)
temp+=imglist.length;
console.log(temp);
// 修改src值
img.src = imglist[temp];
console.log(img.src);
info.innerText = "这是第"+(temp+1)+"张图片,一共"+imglist.length+"张";
}
next.onclick = function(){
temp++;
if(temp == imglist.length)
temp-=imglist.length;
console.log(temp);
img.src = imglist[temp];
console.log(img.src);
info.innerText = "这是第"+(temp+1)+"张图片,一共"+imglist.length+"张";
}
script>
<style type="text/css">
#content{
width: 37.5rem;
margin: 3.125rem auto;
background-color: #f5f5f5;
text-align: center;
}
button{
width: 6.25rem;
margin: 0.3125rem;
padding: 0.3125rem;
color: #333333;
border-radius:0.3125rem ;
background-color: #f2f2f2;
border:0.0625rem solid #d4d4d4;
}
style>
按钮描述
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>全选练习title>
head>
<body>
<p>你爱好的运动是?p>
<input id="chooseall" type="checkbox" name="chooseall" value="全选" />
全选
<br />
<div id="sportslist">
<input type="checkbox" name="sports" value="篮球" />
篮球
<input type="checkbox" name="sports" value="足球" />
足球
<input type="checkbox" name="sports" value="羽毛球" />
羽毛球
<input type="checkbox" name="sports" value="乒乓球" />
乒乓球
div>
<br />
<button type="button" id="btn01">全选button>
<button type="button" id="btn02">全不选button>
<button type="button" id="btn03">反选button>
<button type="button" id="btn04">提交button>
body>
html>
<script type="text/javascript">
var btn01 = document.getElementById("btn01");
btn01.onclick = function(){
var sports = document.getElementsByName("sports");
console.log(sports);
for(var i = 0;i < sports.length;i++){
//设置4个多选框变成选中状态
sports[i].checked = true
}
var chooseall = document.getElementById("chooseall");
chooseall.checked = true;
}
var btn02 = document.getElementById("btn02");
btn02.onclick = function(){
var sports = document.getElementsByName("sports");
console.log(sports);
for(var i = 0;i < sports.length;i++){
sports[i].checked = false
}
var chooseall = document.getElementById("chooseall");
chooseall.checked = false;
}
//在反选时也需要判断四个多选框是否全都选中
var btn03 = document.getElementById("btn03");
btn03.onclick = function(){
var sports = document.getElementsByName("sports");
var chooseall = document.getElementById("chooseall");
console.log(sports);
for(var i = 0;i < sports.length;i++){
sports[i].checked = !sports[i].checked;
// 判断是否全选
// 进入判断前将chooseall状态设置为true
chooseall.checked = true;
for(var j = 0;j < sports.length;j++){
console.log(sports[j].checked)
// 只要有一个没选上chooseall状态为false
if(!sports[j].checked){
chooseall.checked = false;
}
}
}
}
var btn04 = document.getElementById("btn04");
btn04.onclick = function(){
var result =[]
var sports = document.getElementsByName("sports");
console.log(sports);
for(var i = 0;i < sports.length;i++){
if(sports[i].checked == true)
result.push(sports[i].value)
}
alert(result)
}
// 为chooseall绑定响应函数
var chooseall = document.getElementById("chooseall")
chooseall.onclick = function(){
var sports = document.getElementsByName("sports");
for(var i = 0;i < sports.length;i++){
sports[i].checked = this.checked
}
}
// 如果多选框全部选中,chooseall选中
// 如果多选框全部没选中,chooseall不选中
var sports = document.getElementsByName("sports");
var chooseall = document.getElementById("chooseall");
for(var i = 0;i < sports.length; i++){
sports[i].onclick = function(){
// 进入判断前将chooseall状态设置为true
chooseall.checked = true;
for(var j = 0;j < sports.length;j++){
console.log(sports[j].checked)
// 只要有一个没选上chooseall状态为false
if(!sports[j].checked){
chooseall.checked = false;
}
}
}
}
script>
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>添加删除记录练习title>
<script type="text/javascript">
/**
* 删除tr的响应函数
*/
function delA(){
/**
*点击超链接以后需要删除超链接所在的那行
*/
/*点击那个超链接,this便是谁*/
var tr=this.parentNode.parentNode;
/*获取要删除的员工的名字*/
var name=tr.getElementsByTagName("td")[0].innerHTML;
//删除之前弹出提示框
/**
*confirm()用于弹出一个带有确认和取消按钮的提示框
* confirm需要一个字符串作为参数,该字符串作为提示文字显示
* 用户点击确认返回true,点击取消返回false
*/
var flag=confirm("确认删除"+name+"吗?");
if(flag==true) tr.parentNode.removeChild(tr);
/**
* 点击超链接之后 超链接会跳转页面, 但是此时不希望出现默认行为
*/
return false;//取消超链接的默认行为
};
/*
*添加员工的功能:
*点击按钮以后,将员工的信息添加到表格中
*/
window.onload=function(){
//为提交按钮绑定单机响应函数
var addEmpButton=document.getElementById("addEmpButton");
addEmpButton.onclick=function(){
//获取用户添加的员工信息
//获取员工的名字
var name=document.getElementById("empName").value;
//获取员工的email
var email=document.getElementById("email").value;
//获取员工的salary
var salary=document.getElementById("salary").value;
//将获取到的信息保存到tr和td中
//创建一个tr
var tr=document.createElement("tr");
//创建四个td
var nameTd=document.createElement("td");
var emailTd=document.createElement("td");
var salaryTd=document.createElement("td");
var aTd=document.createElement("td");
//创建一个a元素
//超链接a 超链接里面的字aTd
var a=document.createElement("a");
//创建文本节点
var nameText=document.createTextNode(name);
var emailText=document.createTextNode(email);
var salaryText=document.createTextNode(salary);
var delText=document.createTextNode("Delete");
//将文本添加到td中
nameTd.appendChild(nameText);
emailTd.appendChild(emailText);
salaryTd.appendChild(salaryText);
//向a中添加文本
a.appendChild(delText);
//将a添加到dt中
aTd.appendChild(a);
//将td添加到tr中
tr.appendChild(nameTd);
tr.appendChild(emailTd);
tr.appendChild(salaryTd);
tr.appendChild(aTd);
//向a中添加href属性
a.href="javascript:;";
//为新添加的a绑定单击响应函数
a.onclick=delA;
//将td添加到table中
//获取table
var employeeTable=document.getElementById("employeeTable");
//tbody是浏览器自动加的
//获取employeeTable中的tbody
var tbody=employeeTable.getElementsByTagName("tbody")[0];
//将tr添加到table中
tbody.appendChild(tr);
};
//获取所有的超链接
var allA=document.getElementsByTagName("a");
//为每个超链接都绑定一个删除tr的响应函数
for(var i=0;allA.length;i++){
allA[i].onclick=delA;
}
};
script>
head>
<body>
<table id="employeeTable">
<tr>
<th>Nameth>
<th>Emailth>
<th>Salaryth>
<th> th>
tr>
<tr>
<td>Tomtd>
<td>[email protected]td>
<td>5000td>
<td><a href="deleteEmp?id=001">Deletea>td>
tr>
<tr>
<td>Jerrytd>
<td>[email protected]td>
<td>3000td>
<td><a href="deleteEmp?id=002">Deletea>td>
tr>
<tr>
<td>Bobtd>
<td>[email protected]td>
<td>6000td>
<td><a href="deleteEmp?id=003">Deletea>td>
tr>
table>
<div id="formDiv">
<h4>添加新员工h4>
<table>
<tr>
<td class="word">name:td>
<td class="inp">
<input type="text" name="empName" id="empName"/>
td>
tr>
<tr>
<td class="word">email:td>
<td class="inp">
<input type="text" name="email" id="email"/>
td>
tr>
<tr>
<td class="word">salary:td>
<td class="inp">
<input type="text" name="salary" id="salary"/>
td>
tr>
<tr>
<td colspan="2" align="center">
<button id="addEmpButton">Submitbutton>
td>
tr>
table>
div>
body>
html>
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>霸王条款title>
head>
<body>
<h3>用户注册h3>
<p id="info">
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
亲爱的用户,这是霸王协议,如果不看到底就不能提交
p>
<input type="checkbox" id="checkbox" disabled="true" />
我已仔细阅读以上协议
<br />
<button type="button" id="btn" disabled="true" >提交button>
body>
html>
<script type="text/javascript">
var btn = document.getElementById("btn");
var info = document.getElementById("info");
var checkbox = document.getElementById("checkbox");
// onscroll事件在滚动条滚动时触发
//为info绑定一个滚动条滚动事件
info.onscroll = function(){
// alert(info.scrollHeight - info.scrollTop);
// alert(info.clientHeight)
//检查垂直滚动条是否滚动到底
if((info.scrollHeight - info.scrollTop) == info.clientHeight){
// disabled设置元素是否禁用,禁用为true
//若滚动到底,则使表单项可用
checkbox.disabled = false;
btn.disabled = false;
}
}
btn.onclick = function(){
if(checkbox.checked == true)
alert("下一步");
else
alert("请确认以上协议");
}
script>
<style type="text/css">
#info{
height: 31.25rem;
background-color: #F2F2F2;
overflow: auto;
}
button{
padding: 0.3125rem;
}
body{
text-align: center;
}
style>
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>使div跟随鼠标移动title>
head>
<body style="height: 1000px;width: 2000px;">
<div id="box1">
div>
body>
html>
<script type="text/javascript">
//绑定鼠标移动事件,注意这里是给document绑定
document.onmousemove = function(e){
//解决兼容性问题
e=e||window.e;
//获取到鼠标的坐标
// clientX和clientY获取鼠标当前可见窗口坐标(使用这个一定要先开启绝对定位)
// pageX和pageY获取鼠标相对于当前页面的坐标
// console.log(document.documentElement.scrollTop)
var left = e.pageX;
var top = e.pageY;
// 设置div偏移量,注意加上px单位
box1.style.left = left+"px";
box1.style.top = top+"px";
}
script>
<style type="text/css">
#box1{
width: 3.125rem;
height: 3.125rem;
border-radius: 1.5625rem;
background-color:red ;
position: absolute;
}
style>
拖拽的流程:
注意:当拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,此时会导致拖拽功能的异常。这是浏览器提供的默认行为。如果不希望发生这个行为,则可以通过return false来取消默认行为。(但是对IE8不起作用)
setCapture()调用此方法以后,这个元素将会把下一次所有的鼠标按下相关的事件捕获到自身上。
releaseCapture()取消捕获。
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
#box2{
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
left: 200px;
top: 200px;
}
style>
<script type="text/javascript">
window.onload = function(){
/*
* 拖拽box1元素
* - 拖拽的流程
* 1.当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown
* 2.当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove
* 3.当鼠标松开时,被拖拽元素固定在当前位置 onmouseup
*/
//获取box1
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var img1 = document.getElementById("img1");
//开启box1的拖拽
drag(box1);
//开启box2的
drag(box2);
drag(img1);
};
/*
* 提取一个专门用来设置拖拽的函数
* 参数:开启拖拽的元素
*/
function drag(obj){
//当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown
obj.onmousedown = function(event){
//设置box1捕获所有鼠标按下的事件
/*
* setCapture()
* - 只有IE支持,但是在火狐中调用时不会报错,
* 而如果使用chrome调用,会报错
*/
/*if(box1.setCapture){
box1.setCapture();
}*/
//上述可以写为以下
obj.setCapture && obj.setCapture();
event = event || window.event;
//div的偏移量 鼠标.clentX - 元素.offsetLeft
//div的偏移量 鼠标.clentY - 元素.offsetTop
var ol = event.clientX - obj.offsetLeft;
var ot = event.clientY - obj.offsetTop;
//为document绑定一个onmousemove事件
document.onmousemove = function(event){
event = event || window.event;
//当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove
//获取鼠标的坐标
var left = event.clientX - ol;
var top = event.clientY - ot;
//修改box1的位置
obj.style.left = left+"px";
obj.style.top = top+"px";
};
//为document绑定一个鼠标松开事件
document.onmouseup = function(){
//当鼠标松开时,被拖拽元素固定在当前位置 onmouseup
//取消document的onmousemove事件
document.onmousemove = null;
//取消document的onmouseup事件
document.onmouseup = null;
//当鼠标松开时,取消对事件的捕获
obj.releaseCapture && obj.releaseCapture();
};
/*
* 当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,
* 此时会导致拖拽功能的异常,这个是浏览器提供的默认行为,
* 如果不希望发生这个行为,则可以通过return false来取消默认行为
*
* 但是这招对IE8不起作用
* IE8处理见上方
*/
return false;
};
}
script>
head>
<body>
我是一段文字
<div id="box1">div>
<div id="box2">div>
//注意要开启绝对定位
<img src="img/an.jpg" id="img1" style="position: absolute;"/>
body>
html>
实现功能:当鼠标滚轮向下滚动时,box1变长;当滚轮向上滚动时,box1变短。
onmousewheel鼠标滚轮滚动的事件,会在滚轮滚动时触发。(但是火狐不支持该属性)
在火狐中需要使用 DOMMouseScroll 来绑定滚动事件。注意该事件需要通过addEventListener()函数来绑定。
**bind()**方法主要就是将函数绑定到某个对象。bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()第一个参数的值。
event.wheelDelta 可以获取鼠标滚轮滚动的方向【向上滚 120 向下滚 -120】
在火狐中使用event.detail来获取滚动的方向【向上滚 -3 向下滚 3 】
需要使用event来取消默认行为event.preventDefault()。(使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false )。(IE8不支持)。
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
#box1{
width: 100px;
height: 100px;
background-color: red;
}
style>
<script type="text/javascript">
window.onload = function(){
//获取id为box1的div
var box1 = document.getElementById("box1");
//为box1绑定一个鼠标滚轮滚动的事件
/*
* onmousewheel鼠标滚轮滚动的事件,会在滚轮滚动时触发,
* 但是火狐不支持该属性
* 在火狐中需要使用 DOMMouseScroll 来绑定滚动事件
* 注意该事件需要通过addEventListener()函数来绑定
*/
box1.onmousewheel = function(event){
event = event || window.event;
//event.wheelDelta 可以获取鼠标滚轮滚动的方向 【向上滚 120 向下滚 -120】 【wheelDelta这个值我们不看大小,只看正负 】
//alert(event.wheelDelta);
//wheelDelta这个属性火狐中不支持,在火狐中使用event.detail来获取滚动的方向【向上滚 -3 向下滚 3 】
//alert(event.detail);
/*
* 当鼠标滚轮向下滚动时,box1变长
* 当滚轮向上滚动时,box1变短
*/
//判断鼠标滚轮滚动的方向(浏览器兼容考虑)
if(event.wheelDelta > 0 || event.detail < 0){
//向上滚,box1变短(每次变化10)
box1.style.height = box1.clientHeight - 10 + "px";
}else{
//向下滚,box1变长
box1.style.height = box1.clientHeight + 10 + "px";
}
/*
* 使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false
* 需要使用event来取消默认行为event.preventDefault();
* 但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错
*/
event.preventDefault && event.preventDefault();
/* 当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,这是浏览器的默认行为,如果不希望发生,则可以取消默认行为 */
return false;
};
//为火狐绑定滚轮事件
bind(box1,"DOMMouseScroll",box1.onmousewheel);
};
function bind(obj , eventStr , callback){
if(obj.addEventListener){
//大部分浏览器兼容的方式
obj.addEventListener(eventStr , callback , false);
}else{
/*
* this是谁由调用方式决定
* callback.call(obj)
*/
//IE8及以下
obj.attachEvent("on"+eventStr , function(){
//在匿名函数中调用回调函数
callback.call(obj);
});
}
}
script>
head>
<body style="height: 2000px;">
<div id="box1">div>
body>
html>
onkeydown按键被按下
❗键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document。
keyCode获取按键的编码,可以判断哪个按键被按下。
除了keyCode,事件对象中还提供了几个属性:
//console.log(event.keyCode);
//判断y和ctrl是否同时被按下
if(event.keyCode === 89 && event.ctrlKey){
console.log("ctrl和y都被按下了");
}
input.onkeydown = function(event) {
event = event || window.event;
//数字的keyCode: 48 - 57
//使文本框中不能输入数字
if(event.keyCode >= 48 && event.keyCode <= 57) {
//在文本框中输入内容,属于onkeydown的默认行为
//如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中
return false;
}
};
使div可根据不同的方向键向不同的方向移动,如按左键向左移,按右键向右移…(37左,38上,39右,40下)。
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>方向键控制divtitle>
head>
<body>
<div id="box1">div>
body>
html>
<script type="text/javascript">
window.onload=function(){
// 使div更具不同方向键向不同方向移动
var box1 = document.getElementById("box1")
document.onkeydown = function(e){
e = e || event;
//表示移动的速度
var speed = 20;
// 按下shift后速度加快
if(e.shiftKey)
speed = 50;
//也可以用switch语句
if(e.keyCode == 38){
box1.style.top = (box1.offsetTop - speed) + "px"
}
else if(e.keyCode == 40){
box1.style.top = (box1.offsetTop + speed) + "px"
}
else if(e.keyCode == 37){
//向左:left值减小
box1.style.left = (box1.offsetLeft - speed) + "px"
}
else if(e.keyCode == 39){
box1.style.left = (box1.offsetLeft + speed) + "px"
}
}
};
script>
<style type="text/css">
#box1{
width: 6.25rem;
height: 6.25rem;
background-color: red;
position: absolute;
}
style>
BOM浏览器对象模型(browser object model):
BOM对象
这些BOM对象在浏览器中都是作为window对象的属性保存的,可以通过window对象来使用,也可以直接使用。如window.navigator或navigator。
由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了。
一般我们只会使用userAgent来判断浏览器的信息,
火狐的userAgent:
Mozilla5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko20100101 Firefox50.0
Chrome的userAgent
Mozilla5.0 (Windows NT 6.1; Win64; x64) AppleWebKit537.36 (KHTML, like Gecko) Chrome52.0.2743.82 Safari537.36
IE8
Mozilla4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
IE9
Mozilla5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
IE10
Mozilla5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
IE11
Mozilla5.0 (Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko
❗在IE11中已经将微软和IE相关的标识都已经去除了,所以我们基本已经不能通过UserAgent来识别一个浏览器是否是IE了
【则通过一些浏览器中特有的对象判断】
//判断浏览器
alert(navigator.appName);
var ua = navigator.userAgent;
console.log(ua);
if(/firefox/i.test(ua)){
alert("你是火狐!!!");
}else if(/chrome/i.test(ua)){
alert("你是Chrome");
}else if(/msie/i.test(ua)){
alert("你是IE浏览器~~~");
}
//通过一些浏览器中特有的对象判断
else if("ActiveXObject" in window){
alert("你是IE11,枪毙了你~~~");
}
History对象可以用来操作浏览器向前或向后翻页。
对象属性:
length属性,可以获取到当成访问的链接数量。(即看了几个页面)
对象方法:
back() 可以用来回退到上一个页面,作用和浏览器的回退按钮一样。
forward() 可以跳转下一个页面,作用和浏览器的前进按钮一样。
go() 可以用来跳转到指定的页面。
Location对象中封装了浏览器的地址栏的信息。
//如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)
alert(location);
//如果直接将location属性修改为一个完整的路径或相对路径,则我们页面会自动跳转到该路径,并且会生成相应的历史记录。
location = "http:www.baidu.com";
location = "01.BOM.html";
对象方法:
assign() 用来跳转到其他的页面,作用和直接修改location一样。
**reload()**用于重新加载当前页面,作用和刷新按钮一样。
location.reload(true);
replace()
可以使用一个新的页面替换当前页面,调用完毕也会跳转页面。不会生成历史记录,不能使用回退按钮回退。
JS的程序的执行速度是非常快的,如果希望一段程序可以每间隔一段时间执行一次,可以使用定时调用。
setInterval() 定时调用。可以将一个函数,每隔一段时间执行一次。
//1000毫秒调用该函数
var num=1;
setInterval(function){
count.innerHTML=num++;
},1000;
clearInterval() 可以用来关闭一个定时器。
if(num==11){
clearInterval(timer);
}
setTimeout 延时调用。即一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次。
延时调用和定时调用的区别,定时调用会执行多次,而延时调用只会执行一次。
延时调用和定时调用实际上是可以互相代替的,在开发中可以根据自己需要去选择。
var timer = setTimeout(function(){
console.log(num++);
},3000);
使用**clearTimeout()**来关闭一个延时调用
clearTimeout(timer);
通过style属性来修改元素的样式,每修改一个样式,浏览器就需要重新渲染一次页面。
我们可以通过修改元素的class属性来间接的修改样式。
box.className += " b2"; //注意有空格,添加class属性
注意:可以将以下代码加入tools.js中(会常用)。
//定义一个函数,用来向一个元素中添加指定的class属性值
/*
* 参数:
* obj 要添加class属性的元素
* cn 要添加的class值
*
*/
function addClass(obj, cn) {
//添加之前先检查obj中是否有cn
if (!hasClass(obj, cn)) {
obj.className += " " + cn;
}
}
/*
* 判断一个元素中是否含有指定的class属性值
* 如果有该class,则返回true,没有则返回false
* 用正则表达式判断 \b单词边界
*/
function hasClass(obj, cn) {
//通过构造函数设置正则表达式进行判断
var reg = new RegExp("\\b" + cn + "\\b");
return reg.test(obj.className);
}
/*
* 删除一个元素中的指定的class属性
*/
function removeClass(obj, cn) {
//创建一个正则表达式
var reg = new RegExp("\\b" + cn + "\\b");
//删除class,即替换为空串
obj.className = obj.className.replace(reg, "");
}
/*
* toggleClass可以用来切换一个类
* 如果元素中具有该类,则删除
* 如果元素中没有该类,则添加
*/
function toggleClass(obj , cn){
//判断obj中是否含有cn
if(hasClass(obj , cn)){
//有,则删除
removeClass(obj , cn);
}else{
//没有,则添加
addClass(obj , cn);
}
}
JSON:JavaScript Object Notation,即JS对象表示法。
JS中的对象只有JS自己认识,其他的语言都不认识。
JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言所识别,并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互。
JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号。其他的和JS语法一致。
JSON分类:
①对象{}
②数组[]
JSON中允许的值:
①字符串
②数值
③布尔值
④null
⑤对象
⑥数组
举例:
var arr = '[1,2,3,"hello",true]';
var obj2 = '{"arr":[1,2,3]}';
var arr2 ='[{"name":"孙悟空","age":18,"gender":"男"},{"name":"孙悟空","age":18,"gender":"男"}]';
在JS中,提供了一个工具类,就叫JSON。这个对象可以将JSON字符串和JS对象互相转换。
JSON->JS对象
JSON.parse() 可以将以JSON字符串转换为js对象。
//JSON字符串
var arr = '[1,2,3,"hello",true]';
var o = JSON.parse(arr);
JS对象->JSON
JSON.stringify() 可以将一个JS对象转换为JSON字符串。
//JS对象
var obj3 = {name:"猪八戒" , age:28 , gender:"男"};
var str = JSON.stringify(obj3);
console.log(str);
注意:JSON这个对象在IE7及以下的浏览器中不支持,所以在这些浏览器中调用时会报错。
eval():这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回。
var str = '{"name":"孙悟空","age":18,"gender":"男"}';
var obj = eval("("+str+")");
eval()这个函数的功能很强大,可以直接执行一个字符串中的js代码,但是在开发中尽量不要使用,因为它的执行性能比较差且具有安全隐患。
❗如果需要兼容IE7及以下的JSON操作,则可以通过引入一个外部的js文件来处理。
//引入一个外部的js文件来处理
<script type="text/javascript" src="js/json2.js">script>
功能描述:使图片可以自动切换。
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>自动切换图片title>
head>
<body>
<div id="content">
<img id="img" src="img/pic1.jpg" >
<br />
<button type="button" id="btn01">开始button>
<button type="button" id="btn02">停止button>
div>
body>
html>
<script type="text/javascript">
//获取img标签
var img =document.getElementById("img")
// 创建一个数组保存图片路径
var imgArr = ["img/pic1.jpg","img/pic2.jpg","img/pic3.jpg"]
// 保存图片索引
var index = 0;
// 保存定时器标识
var timer;
//为btn01绑定一个单击响应函数
var btn01 = document.getElementById("btn01");
btn01.onclick = function(){
// 在开启定时器之前,需要将荡秋千元素上的其他定时器关闭
//(如果不设置此,则每点击一次按钮就会开启一个定时器,会导致图片切换速度越来越快)
clearInterval(timer);
//开启一个定时器,来自动切换图片
timer = setInterval(function(){
//使索引自增
index++;
//判断索引是否超过最大索引写法一
if(index >= imgArr.length)
index =0;
//判断索引是否超过最大索引写法二
//index%=imgArr.length;
//修改img1的src属性
img.src = imgArr[index];
},1000)
console.log(timer)
}
//为btn02绑定一个单击响应函数
var btn02 = document.getElementById("btn02");
btn02.onclick = function(){
//点击按钮以后,停止图片的自动切换,即关闭定时器
clearInterval(timer);
}
script>
<style type="text/css">
#content{
width: 37.5rem;
margin: 3.125rem auto;
background-color: #f5f5f5;
text-align: center;
}
button{
width: 6.25rem;
margin: 0.3125rem;
padding: 0.3125rem;
color: #333333;
border-radius:0.3125rem ;
background-color: #f2f2f2;
border:0.0625rem solid #d4d4d4;
}
style>
解决5.2.7(8)中div移动初始时的卡顿问题。
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>方向键控制divtitle>
head>
<body>
<div id="box1">div>
body>
html>
<script type="text/javascript">
window.onload = function () {
//表示移动的速度
var speed = 20;
//表示方向。通过修改dir影响移动的方向
var dir = 0;
//开启一个定时器,来控制div的移动
setInterval(function () {
switch (dir) {
//向左
case 37:
box1.style.left = (box1.offsetLeft - speed) + "px";
break;
//向右
case 39:
box1.style.left = (box1.offsetLeft + speed) + "px";
break;
//向上
case 38:
box1.style.top = (box1.offsetTop - speed) + "px";
break;
//向下
case 40:
box1.style.top = (box1.offsetTop + speed) + "px";
break;
}
}, 30);
//为document绑定一个按键按下的事件
document.onkeydown = function (event) {
event = event || window.event;
// 按下shift后速度加快
if (event.shiftKey){
speed = 50;
}else{
speed=10;
}
//使dir等于按键的值
dir = event.keyCode;
}
//当按键松开时,div不再移动
document.onkeyup=function(){
dir=0;
}
};
script>
<style type="text/css">
#box1 {
width: 6.25rem;
height: 6.25rem;
background-color: red;
position: absolute;
}
style>
parseInt() 把字符串中的合法数字取出来。
ps:该部分将功能js单独写为tools.js
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#box1{
width: 100px;
height: 100px;
background-color: #6495ED;
position: absolute;
left:0;
}
#box2{
width: 100px;
height: 100px;
background-color: #FFFF00;
position: absolute;
left:0;
top:200px;
}
#line{
width: 0;
height: 1000px;
border-left:1px black solid;
position: absolute;
left:800px;
top: 0;
}
style>
<script src="./js/tools.js" type="text/javascript">script>
<script type="text/javascript" >
/**
* 所有正在执行的定时器都在这个变量中保存
*/
//var timer;
window.onload=function(){
var box1=document.getElementById("box1");
var box2=document.getElementById("box2");
var btn01=document.getElementById("btn01"); //点击按钮以后box1向右移动
var btn02=document.getElementById("btn02");//点击按钮以后box1向左移动
var btn03=document.getElementById("btn03");//box1你停下来
var btn04=document.getElementById("btn04");//点击按钮以后box2向右移动
var btn05=document.getElementById("btn05");//测试按钮
var btn06=document.getElementById("btn06");//box2你停下来
btn01.onclick=function(){//点击按钮以后box1向右移动
move(box1,"left",800,10);
}
btn02.onclick=function(){//点击按钮以后box1向左移动
move(box1,"left",0,10);
}
btn04.onclick=function(){//点击按钮以后box2向右移动
move(box2,"left",800,10);
}
btn05.onclick=function(){//测试按钮
// move(box2,"width",800,10);
// move(box2,"top",800,10);
// move(box2,"height",800,10);
move(box2,"height",800,10,function(){
move(box2,"width",800,10,function(){
//这里我就不套娃了
});
});
}
//box1你停下来
btn03.onclick=function(){
stop(box1);
}
//box2你停下来
btn06.onclick=function(){
stop(box2);
}
}
script>
head>
<body>
<button id="btn01">点击按钮以后box1向右移动button>
<button id="btn02">点击按钮以后box1向左移动button>
<button id="btn04">点击按钮以后box2向右移动button>
<button id="btn05">测试按钮button>
<br /> <br />
<button id="btn03">box1你停下来button>
<button id="btn06">box2你停下来button>
<br /> <br />
<div id="box1">div>
<div id="box2">div>
<div id="line" >div>
body>
html>
tools.js
/**
* 创建一个可以执行简单动画的函数
* obj:执行对象
* attr:要执行动画的样式
* speed:移动速度(有正负)正数向右 负数向左
* target:执行动画的目标位置
* callback:回调函数 在动画执行完毕之后执行
*/
function move(obj,attr,target,speed,callback){
//开启一个定时器 执行动画效果
clearInterval(obj.timer);
//判断速度的正负 如果从0到800 移动 speed大于0 反之小于0
var current=parseInt(getStyle(obj,attr));//元素目前的位置
if(current>target) {
speed=-speed;
}
obj.timer=setInterval(function(){
// box1.style.left=box1.offsetLeft-10+"px";
var oldValue=parseInt(getStyle(obj,attr));
var newValue=oldValue+speed;
//停止条件
if((speed<0&&newValue<=target)||(speed>0&&newValue>=target)){
newValue=target;
}
obj.style[attr]=newValue+"px";
if(newValue==target){
clearInterval(obj.timer);
//动画执行完毕 调用回调函数
callback &&callback();
}
},30);
}
/**
* 你停下来函数
*/
function stop(obj){
clearInterval(obj.timer);
}
/**
* 定义一个函数用来获取指定元素当前的样式
*/
function getStyle(obj,name){
if(window.getComputedStyle){
return getComputedStyle(obj,null)[name];// //正常浏览器的方式 // return getComputedStyle(obj,null)[name];
}else{
return obj.currentStyle[name]; // //IE8的方式 // return obj.currentStyle[name];
}
}
注意同样需要引入(3)中的tools.js文件。
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#outer {
width: 520px;
height: 333px;
margin: 50px auto;
background-color: greenyellow;
padding: 10px 0;
/*子绝父相*/
position: relative;
/* 裁剪溢出的内容*/
overflow: hidden;
}
#imgList {
/*去除项目符号*/
list-style: none;
/*设置ul宽度*/
width: 2100px;
position: absolute;
/* 每向左移动520 就会显示下一张 */
left: 0px;
}
#imgList li {
/* 设置浮动 */
float: left;
margin: 0 10px;
}
/* 设置导航按钮 */
#navDiv {
position: absolute;
/*开启绝对定位*/
bottom: 15px;
/* 设置位置 */
}
#navDiv a {
float: left;
width: 15px;
height: 15px;
background-color: #FF0000;
margin: 0 5px;
/*设置左右外边距*/
opacity: 0.5;
/*设置透明*/
fill-opacity: alpha(opacity=50);
/*兼容IE8透明*/
}
#navDiv a:hover {
background-color: black;
}
style>
<script type="text/javascript" src="./js/tools.js">script>
<script type="text/javascript">
window.onload = function () {
var imgList = document.getElementById("imgList");
var imgArr = document.getElementsByTagName("img");
//设置imgList宽度
imgList.style.width = 520 * imgArr.length + "px";
//设置导航按钮居中
var navDiv = document.getElementById("navDiv");
var outer = document.getElementById("outer");
navDiv.style.left = (outer.offsetWidth - navDiv.offsetWidth) / 2 + "px";
var allA = document.getElementsByTagName("a");
//默认显示图片的索引
var index = 0;
/**
* 设置默认选中效果
*/
allA[index].style.backgroundColor = "black";
/**
* 点击超链接切换到指定的图片,即点击第一个超链接显示第一个图片
*/
for (var i = 0; i < allA.length; i++) {
allA[i].num = i;
//单击响应函数
allA[i].onclick = function () {
//关闭自动切换的定时器
clearInterval(timer);
index = this.num;
//imgList.style.left=-index*520+"px";//切换图片
allA[index].style.backgroundColor = "black";
//设置选中的a
setA();
//使用move函数切换对象
move(imgList, "left", -520 * index, 20, function () {
//动画执行完毕后,开启自动切换
autoChange();
});
}
}
/**
* 自动切换
*/
autoChange();
//创建一个方法设置选中a(即导航方点)
function setA() {
//判断当前索引是否是最后一张
if (index >= imgArr.length - 1) {
index = 0;
//此时显示的是最后一张图片,而最后一张图片和第一张是一模一样的
//通过CSS将最后一张换成第一张
imgList.style.left = 0;
}
//遍历所有的a 并将他们的背景颜色设置为红色
for (var i = 0; i < allA.length; i++) {
allA[i].style.backgroundColor = "";
}
//将选中的a设置为黑色
allA[index].style.backgroundColor = "black";
}
/**
* 创建一个函数用来开启自动切换
*/
//定义一个自动切换的定时器的标识
var timer;
function autoChange() {
//开启一个定时器 用来定时切换图片
timer = setInterval(function () {
index++;
//判断index的值
index = index % imgArr.length;
//执行动画,切换图片
move(imgList, "left", -520 * index, 20, function () {
//修改导航点
setA();
});
}, 3000);
}
}
script>
head>
<body>
<div id="outer">
<ul id="imgList">
<li>
<img id="img1" src="./img/1.jpg" width="500px" height="333px" />
li>
<li>
<img id="img2" src="./img/2.jpg" width="500px" height="333px" />
li>
<li>
<img id="img3" src="./img/3.jpg" width="500px" height="333px" />
li>
<li>
<img id="img4" src="./img/4.jpg" width="500px" height="333px" />
li>
<li>
<img id="img1" src="./img/5.jpg" width="500px" height="333px" />
li>
<li>
<img id="img1" src="./img/1.jpg" width="500px" height="333px" />
li>
ul>
<div id="navDiv">
<a href="javascript:;">a>
<a href="javascript:;">a>
<a href="javascript:;">a>
<a href="javascript:;">a>
<a href="javascript:;">a>
div>
div>
body>
html>
分为html、css、js三个文件。
①index.html
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>二级菜单title>
<link rel="stylesheet" href="./css/second.css">
<style>
*{
padding: 0px;
margin: 0px;
list-style-type: none;
}
a,img{
border: 0px;
text-decoration: none;
}
body{
font: 12px/180%;
}
style>
<script src="./js/tools.js">script>
<script>
window.onload = function(){
/*
我们的每一个菜单都是一个div
当div具有collapsed这个类时,div就是折叠状态
当div没有这个类时,div就是展开状态
点击菜单,切换菜单的显示状态
*/
//获取所有的class为menuSpan的元素
var menuSpan = document.querySelectorAll(".menuSpan");
console.log(menuSpan.length);
//定义一个变量,保存当前打开的菜单
var openDiv = menuSpan[0].parentNode;
//绑定span单击响应函数
for(var i=0; i<menuSpan.length; i++){
menuSpan[i].onclick = function(){
//this代表当前点击的span
//获取当前span的父元素
var parentDiv = this.parentNode;
//调用函数,切换菜单的显示状态
toggleMenu(parentDiv);
//判断openDiv和parentDiv是否相同。不一样才加
if(openDiv != parentDiv && !hasClass(openDiv, "collapsed")){
//打开菜单以后,应该关闭之前打开的菜单
//为了可以统一处理动画过渡效果,我们希望将addClass改为toggleClass;
// addClass(openDiv, "collapsed");
// 此处toggleClass()不需要有移除功能(只需要加入的功能),即if中第二个条件判断
// toggleClass(openDiv, "collapsed");
//上五行可以写为如下一行代码
//调用函数,切换菜单的显示状态
toggleMenu(openDiv);
}
//修改openDiv 为当前打开的菜单
openDiv = parentDiv;
};
}
//切换菜单的折叠和显示状态
function toggleMenu(obj){
//在切换类之前,获取元素的高度
var begin = obj.offsetHeight;
//切换parentDiv的显示
toggleClass(obj, "collapsed");
//在切换类之后,获取一个高度
var end = obj.offsetHeight;
// console.log(begin+ " "+end);
// 动画效果就是将高度从begin向end过渡
// 将元素的高度重置为begin(设置一个内联样式)
obj.style.height = begin + "px"
// console.log(parentDiv.style.height);
// 执行动画,从begin向end过渡
move(obj, "height", end, 10, function(){
// 动画执行完毕,内联样式已经没有存在的意义,需删除
//当回调函数执行时,动画即执行完
obj.style.height = "";
});
}
};
script>
head>
<body>
<div id="my_menu" class="sdmenu">
<div>
<span class="menuSpan">在线工具span>
<a href="#">图像优化a>
<a href="#">收藏夹图标生成器a>
<a href="#">邮件a>
<a href="#">htaccess密码a>
<a href="#">梯度图像a>
<a href="#">按钮生成器a>
div>
<div class="collapsed">
<span class="menuSpan">支持我们span>
<a href="#">推荐我们a>
<a href="#">链接我们a>
<a href="#">网络资源a>
div>
<div class="collapsed">
<span class="menuSpan">合作伙伴span>
<a href="#">JavaScript工具包a>
<a href="#">CSS驱动a>
<a href="#">CodingForumsa>
<a href="#">CSS例子a>
div>
<div class="collapsed">
<span class="menuSpan">测试电流span>
<a href="#">Current or nota>
<a href="#">Current or nota>
<a href="#">Current or nota>
<a href="#">Current or nota>
div>
div>
body>
html>
②second.css
@charset "utf-8";
/* sdmenu */
div.sdmenu {
width: 150px;
margin: 100px auto;
font-family: Arial, sans-serif;
font-size: 12px;
padding-bottom: 10px;
background-color: darkblue;
/* background: url(bottom.gif) no-repeat right bottom; */
color: #fff;
}
div.sdmenu div {
background: url(title.gif) repeat-x;
overflow: hidden;
}
div.sdmenu div:first-child{
background: url(toptitle.gif) no-repeat;
}
div.sdmenu div.collapsed{
height: 25px;
}
div.sdmenu div span{
display: block;
height: 15px;
overflow: hidden;
padding: 5px 25px;
font-weight: bold;
color: white;
background: url(expanded.gif) no-repeat 10px center;
cursor: pointer;
border-bottom: 1px solid #ddd;
}
div.sdmenu div.collapsed span{
background-image: url(collapsed.gif);
}
div.sdmenu div a{
padding: 5px 10px;
background: #eee;
display: block;
border-bottom: 1px solid #ddd;
color: #066;
}
div.sdmenu div a.current{
background: #ccc;
}
div.sdmenu div a:hover{
background: rgb(167, 197, 235) url(linkarrow.gif) no-repeat right center;
color: #fff;
text-decoration: none;
}
③tools.js
//移动效果————move()方法
/**
* 创建一个可以执行简单动画的函数
* obj:执行对象
* attr:要执行动画的样式
* speed:移动速度(有正负)正数向右 负数向左
* target:执行动画的目标位置
* callback:回调函数 在动画执行完毕之后执行
*/
function move(obj, attr, target, speed, callback) {
//开启一个定时器 执行动画效果
clearInterval(obj.timer);
//判断速度的正负 如果从0到800 移动 speed大于0 反之小于0
var current = parseInt(getStyle(obj, attr));//元素目前的位置
if (current > target) {
speed = -speed;
}
obj.timer = setInterval(function () {
// box1.style.left=box1.offsetLeft-10+"px";
var oldValue = parseInt(getStyle(obj, attr));
var newValue = oldValue + speed;
//停止条件
if ((speed < 0 && newValue <= target) || (speed > 0 && newValue >= target)) {
newValue = target;
}
obj.style[attr] = newValue + "px";
if (newValue == target) {
clearInterval(obj.timer);
//动画执行完毕 调用回调函数
callback && callback();
}
}, 30);
}
/**
* 你停下来函数
*/
function stop(obj) {
clearInterval(obj.timer);
}
//版本适配后的获取元素属性的方法_getStyle()
/**
* 定义一个函数用来获取指定元素当前的样式
*/
function getStyle(obj, name) {
if (window.getComputedStyle) {
return getComputedStyle(obj, null)[name];// //正常浏览器的方式 // return getComputedStyle(obj,null)[name];
} else {
return obj.currentStyle[name]; // //IE8的方式 // return obj.currentStyle[name];
}
}
//删除、添加、替换、判断类是否存在 的方法(removeClass、addClass、toggleClass、hasClass)
//定义一个函数,用来向一个元素中添加指定的class属性值
/*
* 参数:
* obj 要添加class属性的元素
* cn 要添加的class值
*
*/
function addClass(obj, cn) {
//添加之前先检查obj中是否有cn
if (!hasClass(obj, cn)) {
obj.className += " " + cn;
}
}
/*
* 判断一个元素中是否含有指定的class属性值
* 如果有该class,则返回true,没有则返回false
* 用正则表达式判断 \b单词边界
*/
function hasClass(obj, cn) {
//通过构造函数设置正则表达式进行判断
var reg = new RegExp("\\b" + cn + "\\b");
return reg.test(obj.className);
}
/*
* 删除一个元素中的指定的class属性
*/
function removeClass(obj, cn) {
//创建一个正则表达式
var reg = new RegExp("\\b" + cn + "\\b");
//删除class,即替换为空串
obj.className = obj.className.replace(reg, "");
}
/*
* toggleClass可以用来切换一个类
* 如果元素中具有该类,则删除
* 如果元素中没有该类,则添加
*/
function toggleClass(obj, cn) {
//判断obj中是否含有cn
if (hasClass(obj, cn)) {
//有,则删除
removeClass(obj, cn);
} else {
//没有,则添加
addClass(obj, cn);
}
}