血的教训
当用li标签包裹住a标签,鼠标经过,让其它元素显示时。要写li:hover div{各种样式}而不能写ul li a:hover div{各种样式}
事件代理:为后来添加的元素添加上事件,优化引擎
— Gecko内核 css前缀为"-moz-" 火狐浏览器
— Presto内核 css前缀为"-o-" Opera(欧朋)
— Trident内核 css前缀为"-ms-" IE
— WebKit内核 css前缀为“-webkit- safari chrome
改变placeholder颜色input::-webkit-input-placeholder { color: red;}
DIV+CSS布局部分
小技巧
将span变为三角形
display: inline-block;
border-top:4px solid #676767;
border-right:4px solid transparent;
border-bottom:4px solid transparent;
border-left:4px solid transparent;
让一个元素上下左右居中
盒子居中:
垂直居中:top:50%;margin-top:盒子高度的一半的负值
水平居中:left:50%;margin-left:盒子宽度的一半的负值
文字居中:
Text-align:center 垂直:line-height:
通栏显示{页面背景 头部 导航 底部}
有通栏的全局变量body中不声明宽度,下面的每个部分单独声明,没有通栏的直接body声明,省得下面单独定义麻烦
通栏的时候里面再套一个div 然后外面的div定义背景颜色边框等。里面的div用width:980px;和margin:0 auto;限制居中显示
一般头部加上h1写上网站的名字是为了利于搜索引擎的搜索,然后用text-indent:-9999px;让这个文字不显示
导航栏制作时[文字不一样多] 当鼠标放上去只改变文字颜色时:给li修饰用margin-left:20px;margin-right:20px;就可以
当鼠标放上导航栏的背景还要变化,以及有小竖线时。给a修饰用padding-left和padding-right,且a元素写上display:block;转化成块状元素使a的宽度继承父级宽度,背景填充,但是当有背景图片小竖条时。给a加上背景小竖条。并且a:hover的background加上背景颜色时,也要再加上背景图片的小竖条才能不覆盖
进行浮动的元素设置宽度
有子元素且子元素加了高度,父元素没有设置高度,子元素浮动了,就会出现高度的塌陷,所有父元素最好加上高度
定位(position)改变元素的位置(脱离了文档流)
Position:static(静态的,不变,和没写一样)
Position:relative(相对定位)
原来的位置保留 相对自己的位置变化
Position:absolute(绝对定位)
不保留原来的位置,相对于父元素进行改变,但是父元素必须加上相对定位,父元素没加相对或者没加父元素时相对于body改变
Position:fixed(固定定位)
相对于浏览器进行改变, 用相对定位时放在页面的最开头或者最结尾,这个是对联广告,总是漂浮在两边那种
Z-index:0 30 8 98 谁的值越大越在上面显示
元素的分类(display)
Block 块级元素的默认显示方式
Inline行内元素的默认显示方式
Inline-block 行内块级元素 常见的有img input select textarea
Display:none隐藏后不占空间 visibility:hidden这个也是隐藏,但是隐藏后占空间
Opacity:0.8透明度
导航里面的li用display:inline-block (最好用这个,不用浮动) 来布局的时候,li之间会有4像素的空隙,减小这个空隙的办法是先设置ul的font-size:0;然后在下面的li里面设置font –size:?px;就可以了
使用服务器字体及阴影
在样式中首先引入@font-face{font-family:webfont; src:url(“http://www.baidu.com/ziti”)}然后需要的标签写上h1{ font-family:webfont; }
给字加阴影:Text-shadow:阴影的水平偏移(正直往左,负值往右); 垂直偏移 (正直往下,负值往下) ;阴影的模糊度; 阴影的颜色;可以添加多个阴影用逗号隔开
Text-shadow:2px 3px 3px red, -2px -3px 3px blue; 如果浏览器不识别,加上浏览器标志
text-shadow: 0 0 90px #fff, 0 0 40px #fff, 0 0 10px #fff;
-webkit-text-shadow:
给盒子加阴影:box-shadow:
第一个值:水平方向的偏移
第二个值;垂直方向的偏移
第三个值:模糊大小
第四个值:阴影的大小
第五个值:阴影的颜色
第六个值:不写的话是外阴影, 写的话就是写inset 内阴影;
无论是字体还是盒子,前两个值不能省略
Box- shadow :3px 4px 10px yellow inset;也可以加逗号再加 【一般写四个值就行,水平、垂直、模糊程度、颜色】
Text-overflow属性【文字溢出怎么处理】:ellipsis 省略号形式显示|clip(裁剪掉)
Overfllow:auto; 浏览器自动索引,就是宽高显示不开,浏览器就加上纵向滚动条
Overfllow:hidden;多余的部分进行隐藏
Overfllow:scroll; 浏览器加上横向和纵向的滚动条
如果只加上横向的【高度去掉,加上overfllow-x:scroll 不过很少用】;
white-space:nowrap让文字不换号
[给标题加省略号]
overflow:hidden; white-space:nowrap; text-overflow:ellipsis;width:400px;
CSS新增背景属性
背景线性渐变颜色
background-image:linear-gradient(方向,颜色,颜色,颜色……)
background–image:linear-gradient(to top,red,yellow) ; 从下往上由红变黄
背景裁切
background-clip:border-box默认值从边框开始裁剪,看不出效果
content-box从内容区域开始裁切,有padding的间距没有背景
padding-box从有内填充的地方开始裁剪,就是padding的间距也填充了背景
背景图像起始位置
Background-origin 与background-position配合使用
— border-box:以边框为原点开始计算background-position
— ,边框地下
— padding-box:默认值 background-position,紧临着边框为原点计算position。
— content-box:以内容盒子为原点开始计算background-position ,把padding的间距空开为原点;
控制背景图像的大小
Background-size:25px 25px 【横向和纵向,也可以写成百分比】
值Cover,将背景图像等比缩放到完全覆盖容器,但是有可能超出容器
值Contain,将背景图像等比缩放到宽度或者高度与容器的宽度或者高度相等,但是背景图像始终包含在容器之内
写多个背景图像
Background:url(),url(),url()……
Background:url(../images/pic1.jpg) no-repeat left top,url(../images/pic2.jpg) no-repeat right bottom;
CSSsprites雪碧图技术(css精灵)
用软件生成一张图片,会自动告诉你坐标,自己量的时候,是整张雪碧图的左上角是坐标00 到想用的图标的左上角 写XY 但是都是负值写到background:url(./img/icon.jpg) norepate -X px -Ypx; 然后让这个小图标在里面居中就是加上距离边的正值,比方说x是55 y是55 取到的图片是-55px -55px 然后居中比方说在想放的盒子里距离左边是8距离上面是10 才会居中,所以X轴坐标变为-55+8=-47px 而Y轴坐标变为-55+10=-45px;注意的一点就是在大图标定位到这个想要小图标时候都是负值,然后加上需要显示位置的正值得到最终位置坐标
PC端的布局形式:
固定宽度且居中
自适应宽度(浮动 、定位)
如果左中右三个浮动的div(也叫双飞翼布局) 然后把center写在div的最前面便于显示;
center:float:left , height:400px;width:100%; padding:0 200px; box-sizing:border-box;
left:float:left; width:200px; position:relative; margin-left:-100%;
right: left:float:left; width:200px; position:relative; margin-left:-200px;
移动端布局形式:
弹性盒布局(梳理)
1.谁是弹性盒,谁写(一般是父元素)Display:box 如果不兼容写:display:-moz-box
Display:-webkit-box;
Display:-o-box;
Display:-ms-box;
Display:box;
2.父元素决定子元素的排列方向 box-orient:horizontal(水平 默认的)
Vertical(垂直排列、纵向)
3.父元素决定子元素的显示顺序 box-direction :reverse(倒序)
4.依然给父元素设置,父元素决定子元素的对齐方式:
水平对其:box-pack:start center end (左中右)
垂直对齐:box-align: start center end (上中下)
以上四个都是写给父元素的。
5.子元素设置分配空间
Box-flex:1 2 3 4 写的数字越大,占空间越大
6.子元素位置的改变:box-ordinal-group:1 2 3 4写数值,很少用
<meta name=”viewport” content=”width=device-width,initial-scale=1.0”
第三个是初始化缩放,1.0 就是禁止缩放
第二个值是宽度等于设备宽度
第一个是虚拟窗口意思,就是模拟手机等设备
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
当http-equiv="X-UA-Compatible"这句话是遇上IE8的时候以后面最新版本的IE渲染
IE=edge 以最新版本IE显示 chrome=1 而当机器上安装的IE没法渲染就用谷歌浏览器的内核进行渲染
弹性盒子手机布局
分为上中下三个部分,山下给固定的高度45px或者44px ,然后让中间.main部分加上box-flex:1;也就是让剩余的空间全部给中间;【保证html body 最外层的父亲宽高都是100%】
弹性盒布局(懂懂)
给父元素加的属性:
首先,父元素加上一个display: flex;让其变成弹性盒 此时,其子元素会默认横向排列起来,类似浮动的效果
属性1:flex-direction:(决定子项在flex容器中的位置)
flex-direction: column; 从上到下排列,从父级上面开始[即纵向从上往下排列(顶对齐)]
flex-direction: column-reverse; 从下到上排列( 最后一个元素在最前面)并且从父级底下开始
flex-direction: row;(默认值) 即横向从左到右排列(左对齐)
flex-direction: row-reverse; 对齐方式与row相反
属性2:flex-wrap:(规定子项是否换行)
flex-wrap: nowrap;/*默认样式,超出不换号,自己平均缩小*/
flex-wrap: wrap;
flex容器为多行。该情况下flex子项溢出的部分会被放置到新行,子项内部会发生断行
wrap-reverse; 超出部分换行,并且反向 仅仅是行反转,单个子元素不变
属性3 flex-flow:/*这个属性是direction 和wrap的复合属性*/
属性4 justify-content 【默认值flex-start 】
justify-content:flex-start; /*子元素左对齐*/
justify-content:flex-end; /*子元素右对齐*/
justify-content: center; /*子元素居中对齐*/
justify-content: space-around;/*//平均分布 两边会有间距*/
justify-content: space-between; /*两边对齐中间平均分布【两边靠边了,中间的平分】*/
属性5 align-content: flex-start; 本属性可以用来调准「伸缩行」在伸缩容器里的对齐方式,这与调准伸缩项目在主轴上对齐方式的 <‘ justify-content ‘> 属性类似。请注意本属性在只有一行的伸缩容器上没有效果
align-content: flex-start; /*如果父容器高度大的话原本是行之间平分父容器,有空隙. 加上后 行---上对齐*/
align-content: flex-end;
align-content: center;
align-content:space-around;/*让行平均分布 最上和最底下还是会有中间行空隙的一半*/
align-content: space-between;/*让行平均分布 最上和最底下无空隙,其余平分空隙*/
align-content: stretch; 『默认值,子元素没有高度时默认会扩大高度,子元素加起来高度充满父元素』
属性6 align-items: 定义flex子项在flex容器的当前行的侧轴(纵轴)方向上的对齐方式。
align-items:flex-start; 垂直方向上对齐 左上方
align-items: flex-end; /*垂直方向下对其*/
align-items: center;/*居中对齐*/
align-items:stretch; /*这个属性是个默认值,如果这个元素的子元素没有给高度,子元素会垂直充满容器,给高度的话不起作用*/
align-items: baseline;/*子元素以当前行的首行文字为基准对其*/
加给子元素的
1.Order 默认是0 用整数值来定义排列顺序,数值小的排在前面。可以为负值。
2.flex-grow: 1; 分配剩余空间的 默认是0//*把父级元素剩下的分成grow的份数,此元素占的份数,比方说自己都规定了自己的宽度是30,五个子集,父级300,那么只有一个孩子写grow的话,这个孩子就是本身的50+(300-150 )| 如果有有两个孩子写了这个属性一个值是1一个是2 那么这两个孩子就是本身的50 加上把剩下的300-150=150分成三份,这俩再分别加上100 (2份的)和50(1份的) */
3.flex-shrink: 0;
用数值来定义收缩比率。不允许负值 默认1
/*当容器宽度不够,shrink为0的元素不会缩小 shrink为其他的数,是缩小的倍数,(不是它本身定义宽度的一半,而是其它那些经过挤压后的子元素的)比分说2就是其它的一半,3就是三分之一,所有默认值是1*/
4.flex-basis: 100px; <length>:用长度值来定义宽度。不允许负值
<percentage>:用百分比来定义宽度。不允许负值
auto:无特定宽度值,取决于其它属性值
content:基于内容自动计算宽度
5.flex是 grow shrink basis的缩写
6.align-self: flex-end;定义flex子项单独在侧轴(纵轴)方向上的对齐方式。
/*可以控制单个元素的上中下排列方式*/值:auto | flex-start | flex-end | center | baseline | stretch
手机端页面
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<script>
fontSize();
function fontSize() {
var w = window.innerWidth/10;
var html= document.querySelector("html");
html.style.fontSize=w + "px";
}
// 当窗口的大小发生改变的时候会触发
window.onresize = fontSize;
</script>
将这段话加上,时时监控窗口大小用的
手机端事件
Touchstart事件 手指落在屏幕的事件
Touchmove事件这里面可以阻止默认事件(和PC端的一样preventDefault() 这个默认事件不能加在touchstart上,加上会出a标签不跳转的bug )
Touchend事件,手指离开
在文本前插入东西
H2:before{content:”2016-5-24”;background:red;}在h2标签内容前添加时间并给他背景颜色 h2:nth-child(3):before{content:none;}如果none浏览器不认识用normal 后面插入用:after,当插入图片的时候用content:url(“./img/icon_01.jpg”);就可以
插入计数器
Counter 计数器 counter-increment计数器的增量,让其自增长
H2:before{content:”第”counter(abc)”章”;}再写一个
H2{counter-increment:abc;}
这是阿拉伯数字的
要修改成其他的H2:before{content: counter(abc, 其他文字比分说罗马,英文字母啥的);}
再加上H2{counter-increment:abc;}让它自增长
当想第一个大标题下面出现1-1 1-2 1-3 第二个大标题下面的是2-1 2-1时
li:before{
content: "第"counter(z)"章";
}
li{
counter-reset: c; 这里是让p标签的自增量重置,重置后li下面的小标题就成了li的大标题----c(每次都从1开始)
counter-increment: z;
}
p:before{
content: counter(z)"-"counter(c)".";
}
p{
counter-increment: c;
}
:first-line 第一行 :first-letter第一个字
本页面跳转用锚点链接
清除浮动最有力的方法:
在需要清除浮动的盒子A前面写一个空白的div,里面什么都不需要写,只给个类名B,样式中写
.B:after{
Content:”.”;
Clear:both;
Display:block;
Height:0;
Visibility:hidden; ……消失却占用空间
}
加上这个之后。在A的样式中写上margin-top:多少px;就可以了
既有表单元素又有图片的时候之间会有三个像素的间距,给图片写个margin-left:-3px,让他们挨起来
出现边框当全局样式用了box-sizing:border-box;时,导航栏写.nav{
height: 36px;
border-bottom: 2px solid #fd3f49;
line-height: 36px;
}
下面的盒子部分清除浮动后最上侧有可能会出现1像素的空白条,这是因为上面的导航栏部分line-height应该为34px,因为box-sizeing清除了边框,也就是说36px包括了下边框的2px,但是内容的行高是不应该加上这2px的,所有应该是34px
当一个盒子设置了透明度后,里面的内容也会跟着透明度,如何让内容不透明,背景透明呢?方法如下
<div class="lianxi">
<img src="img/top_bg.jpg"/>
<div class="bgtouming"></div>
<div class="copy">
<input type="text" value="这个内容不能透明" />
</div>
</div>
样式
.lianxi{
width: 900px;
margin: 0 auto;
position: relative;
}
.lianxi .bgtouming{
width: 370px;
height: 100px;
background: #ADFF2F;
border-radius: 15px;
position: absolute;
left: 50%; /*这句和下面的是为了让这个盒子左右居中,-盒子宽度的一半*/
margin-left: -185px;
top: 50%; /*这句和下面的是为了让这个盒子上下居中,-盒子高度的一半*/
margin-top: -50px;
opacity: 0.5;
}
.lianxi .copy {
width: 300px;
height: 70px;
background:transparent; /**让背景透明*/
position: absolute;
left: 50%; /*这句和下面的是为了让这个盒子左右居中,-盒子宽度的一半*/
margin-left: -150px;
top: 50%; /*这句和下面的是为了让这个盒子上下居中,-盒子高度的一半*/
margin-top: -35px;
}
简单来说就是定义一个div是透明的,定位到想要的位置,
再写一个同级的div是不想让透明的,也通过定位,放到透明的div上,想让背景透明就写上background:transparent; /**让背景透明*/就可以了
表单元素 <input type=”#” name=”” value=””>一般都放在form表单中
Text
Password
Radio name=”sex” checked
Checkbox name=”like” checked
File
Hidden
Submit 提交
Reset
Button
Image 提交
<select>
<option></option>
</select>
<textarea cols=”” rows=””></textarea>
H5中新增的表单元素<input type=”#” name=”” value=””>
Type=”Email” 电子邮件、邮箱 必须带@
url 必须网址
date 日期
number:数字,属性有 max min step
range 范围 进度条 0-100之间数字
color:颜色选择器
tel 电话 手机端选中直接切换数字键盘
search 搜索框 属性里面加上 results=”s” 左侧就会出放大镜
新增的input属性
Placeholder :空的input提示信息,鼠标点击的时候提示信息就会消失
Autofocus:自动聚集 值为:ture 或者false
Required:必填项
Autocomplete自动完成 ,就是记忆以前输入过的内容
Multiple:多选 用在file select
List属性,配合 Datalist 这两个属性使用Option
<input type=”text” list=”list1”>
<datalist id=”list1”>
<option value=”1”>深圳</option>
<option value=”2”>上海</option>
<option value=”3”>北京</option>
</datalist>
这个属性的优点在于还可以输入
Enabled:可用 disabled不可用背景灰色 readonly 只读 maxlength最大长度
Form新增属性:
更改提交方式:formmethod 更改提交地址:formaction
是否启用表单验证功能:novalidate=“novalidate”
UI伪类选择器:
:checked 选中的表单元素 checkbox radio
:disabled 不可用的表单元素
:enabled 可用的表单元素
视频音频标签:
Video标签,视频标签,加上controls=“controls”加上控制台,就是让播放按钮啥的
Html新增的标签 figure
响应式布局
布局适口: 电脑页面原本的大小
视觉适口: 手机的可见区域叫视觉适口
理想窗口:
开头加上;
<meta name="viewport" content="width = device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
媒体查询类型:screen(屏幕)、print(打印机)、handheld(手持设备)、all(通用)
常用媒体查询参数:width,height,device-width(设备屏幕的宽度),device-height,orientation(检查设备处于横向lanscape还是竖屏portrait)
Max-width:指的是浏览器窗口宽度
Max-device-width:指的是设备屏幕或者说分辨率支持的最大宽度
引入外部样式的方式
第一种:
<link rel=”stylesheet” media=”screen and (orientation:portrait) and(min-width:800px)” href=”800wide-portrait-screen.css” />
当浏览器发现设备是:视口宽度是大于800像素的纵向显示屏设备时加载样式表
第二种:(直接在一个CSS样式表中分别判断)
/*在992 和1199 像素之间的屏幕里,中等屏幕,分辨率低的PC*/
@media (min-width: 992px) and (max-width: 1199px){
这里面写属于这块的样式
}text
@import引入不常用:@import url(“phone.css”) screen and (min-width;200px) and (max-width:360px);
不同设备的分辨率:
页面大于1200px; 大屏幕,一般为PC端
在992和1199像素之间的屏幕里,中等屏幕 ,分辨率低的PC
在768和991之间的屏幕里 ,小屏幕,主要是pad
在480和767像素之间的屏幕,超小屏幕,主要是手机
小于480的,微小屏幕,更低分辨率的手机
为什么响应式布局要用百分比布局不用固定宽度设计:
固定宽度设计只会从一组CSS媒体查询规则突变到另一组,两者之间没有任何平滑渐变
而使用百分比布局创造的流动弹性界面同时使用媒体查询限制元素变动范围,这两者的结合构成了响应式设计的核心
1.修改宽度
需要牢记的公式:将固定像素宽度转换成对应的百分比宽度;
目标元素宽度 ÷ 上下文元素宽度 = 百分比宽度
PS:我的理解上下文元素宽度指的就是目标元素的父元素,需要修改成百分比的值,宽度width(当有边框宽度的时候要减去边框宽度再去÷父元素的,因为边框随着拖动变细不好看)
2.修改字体大小
em:根据父元素的font-size为相对单位;
rem:根据html的font-size为相对单ice-widt位。
浏览器默认文字大小都是16px;所以body{font-size:100%;font-size:16px;font-size;1em;}效果相同。同样可以用上面的公式来计算 12px表示 :12÷16=0.75rem【这里有用到可以把整体设置成62.5%,也就是10px,然后在这个基础上换算,但是这样会诞生许多问题,谷歌中文版不认识10px,会把他当成12px解读,用hml{-webkit-text-size-adjust:none;font-size:9px;}定义之后,虽然认识了,但欧鹏浏览器能解读此内核,所有需要修改成hml{-webkit-text-size-adjust:none;font-size:9px; -webkit-transform:scale(0.75);-o-transform:scale(1)}】
3.修改图片宽度
Img{max-width:100%;}
当然其它的多媒体标签,也可以设置最大宽度,让它缩放和容器100%匹配比如:
Img,object,video,embed{max-width:100%;}
然后特定图片设置特定的100%;比方说一个盒子里并排两个图片,那么每一个图片max-width:50%;有空隙再相应减小
HTML5
<!--[if lt IE 9]> <script> src="http://html5shim.googlecode.com/svn/trunk/html5.js"</script> <![endif]-->
IE9 以下版本浏览器兼容HTML5的方法,使用百度静态资源的html5shiv包:
<!--[if lt IE9]>
<script src="http://apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<![endif]-->
载入后,初始化新标签的CSS:
/*html5*/
article,aside,dialog,footer,header,section,footer,nav,figure,menu{display:block}
新增的结构性标签,用于布局
Header
nav
acticle
section
aside标签定义其所处内容之外的内容,aside 的内容应该与附近的内容相关
Footer标签
音频/视频
1. 多媒体标签
关于多媒体标签的由来,优点,特性
旧标记:
bgsound : 播放背景音乐,
缺点 : 兼容性差,不可操控
【IE的】object :引入外部内容,功能完善,可操控,可以引入多种格式。
缺点 : 需要控件的支持,性能比较差。
【网景的】embed :引入外部内容,功能完善,可操控,可以引入多种格式。
缺点 : 需要控件的支持,性能比较差
H5新标记:
audio: 音频标签
video:视频标签
优点:功能强大,不需要引入外部文件,性能优越,不需要控件支持
缺点:兼容不是很乐观 所以手机端用H5的,客户端想要兼容到IE8及以下,用上面老的
2. 兼容
兼容能够支持HTML5 的所有浏览器
<video autoplay="" controls poster="../music/Penguins.jpg">
<source src="../music/oceans-clip.mp4" type="video/mp4">
<source src="../music/oceans-clip.ogg" type="video/ogg">
<source src="../music/oceans-clip.avi" type="video/avi">
您的浏览器不支持视频功能
</video>
<audio autoplay="" controls>
<source src="../music/wudi.mp3" type="audio/mp3">
<source src="../music/wudi.ogg" type="video/ogg">
您的浏览器不支持视频功能
</audio>
兼容所有主流浏览器
<video autoplay="" controls poster="../music/Penguins.jpg">
<source src="../music/oceans-clip.mp4" type="video/mp4">
<source src="../music/oceans-clip.ogg" type="video/mp4">
<source src="../music/oceans-clip.avi" type="video/mp4">
<object data="../music/oceans-clip.mp4"></object>
您的浏览器不支持视频功能
</video>
3. 属性
音频
引入音频标签,如下:
<audio controls autoplay src="../music/wudi.mp3">
您的浏览器不支持音频
</audio>
controls : 显示播放控件
autoplay :自动播放,准备就绪(准备就绪!=下载完毕)后马上播放,默认不自动播放。
preload :页面加载完毕之后,准备标签加载,但不播放
loop :是否进行循环播放,默认是不循环
视频
poster :视频默认显示图片,只会在播放之前显示。
controls : 显示播放控件
autoplay :自动播放,准备就绪(准备就绪!=下载完毕)后马上播放,默认不自动播放。
preload :页面加载完毕之后,准备标签加载,但不播放
loop :是否进行循环播放,默认是不循环
4. 自定义
JavaScript (方法,事件)
方法:
play() : 播放视频(音频);
pause() :暂停视频(音频);
loop : 循环播放视频(音频);
属性:
paused :检测当前是否是暂停状态(是则返回true,不是则返回false);
volume : 获取当前音量值,或者是设置当前音量值
src : 获取当前视频/音频地址,或者是设置当前视频/音频地址
playbackRate : 获取当前视频/音频播放速度,或者设置当前视频/音频播放速度
currentTime : 获取当前播放的进度,或者是设置当前播放的进度
duration :获取视频的总长度,固定值
muted :获取当前是否为静音状态,或者设置当前静音状态
事件:
ended : 当视频/音频播放完毕之后触发;
ondurationchange : 当总时长发生改变
具体还要很多方法去我的百度文库找去
本地存储
webStorage提供两种类型的API:localStorage和sessionStorage,两者的区别看名字就有大概了 解,localStorage在本地永久性存储数据,除非显式将其删除或清空,sessionStorage存储的数据只在会话期间有效,关闭浏览器则自 动删除。两个对象都有共同的API
- length:唯一的属性,只读,用来获取storage内的键值对数量。
- key:根据index获取storage的键名
- getItem:根据key获取storage内的对应value
- setItem:为storage内添加键值对
- removeItem:根据键名,删除键值对
- clear:清空storage对象
离线缓存
在网页的html标签中加入<html manifest="test.manifest">这是告诉浏览器需要缓存.
在manifest中:
CACHE MANIFEST #这个必须在第一行,是来声明这是一个manifest文件
#2016年8月23日09:39:14,为了让本文改变,可以修改这里的时间,或者版本号
CACHE:
#这里写需要缓冲的文件,这里的文件内容修改了,页面也不会变,必须这个manifest文件有修改,重新缓存才行
css/test.css
css/test01.css
NETWORK:
#这里是不需要缓冲的文件,这里的文件内容有改变,页面会实时改变
FALLBACK:
#不存在时使用另一个文件替代,主页面引入的test1不存在,那就用test代替,一般用着没有网络的情况下或者是没有网络时跳转的页面,这个跳转的页面要缓存下来提前
css/test1.css css/test.css
/404.html [根目录下的404页面]
CSS3
选择器中需要注意的部分:
element+element |
div+p |
选择紧接在 <div> 元素之后的第一个 <p> 元素。 |
但是需要注意的是,首先它们要有共同的父元素,也就是说他们是同级别的,另外当有五个<P>,用P+P时,从第二个开始都变化。因为第三个也是第二个的下一个
属性值包含
[attribute~=value] [title~=flower] 选择 title属性包含单词 "flower" 的所有元素。
注意是单词,而不是子串,所以title=flowers 是无法被选中的。这样看来和title=flower就没区别了。其实不然,它可以用在class有多个值的时候使用
[attribute*=value] 这个指的是子串中只要有这个子串就行。所以包括flower1 flowers abcflowers都能被选中
属性值结尾
[attribute$=value] 选择属性值中以value结尾的
属性值以什么开头
[attribute|=value] [attribute^=value] 这两个没看出什么区别来?
:focus input:focus 选择所有获得焦点的input输入框
:first-letter P:first-letter选中每一个P的开头第一个字或单词
相对应的:first-line 选中的是第一行
P:first-child P:last-child P:nth-child(1)所指代的是 是先找到每一个父元素 如果规定了父元素就先找到指定的父元素 ,然后找孩子,从子元素中第一个开始找(无论是不是P),找到了再看是不是P元素,是就改变。不是就不改变
而P:first-of-type P:last-of-type P:nth-of-type(n) 和上面是区别是,找到每个父元素里面所有的P进行计数,不是P的它不认识,如果父元素中某几个子元素不是P,那么这几个元素根本不参与计数中找到的是P排名第一的,最后的,或某一个。上面的是找到子元素排名中第几的,再验证是不是要找的
:target找到当前活动的HTML锚,说的太高逼格。其实锚点链接时能用到修改样式用的
:target{border: 2px solid #D4D4D4;}
<p><a href="#news1">跳转至内容 1</a></p>
<p><a href="#news2">跳转至内容 2</a></p>
请点击上面的链接,:target 选择器会突出显示当前活动的 HTML 锚。
<span id="news1"><b>内容 1...</b></span>
<span id="news2"><b>内容 2...</b></span>
CSS3——变形
Transform
Translate(20px,30px) 第一个值的水平方向平移 第二个是垂直平移
Rotate(30deg):旋转 其中deg指的是角度,可以是负值(可分写成XYZ轴)
Scale(1,2)缩放 前者指的是水平方向多少倍,二是垂直方向缩放倍数,一个参数就是整体缩放,缩放的时候占位不变
Skew(20deg,30deg)倾斜
前者是水平方向倾斜的角度,后者是垂直方向的角度
默认以中心点进行变形
Transform-origin:20px 30px 改变变形的中心点
一般鼠标放上去配合过渡(transition)使用
Transition: css属性 ( 全部变的时候写all), 从没有变形到 变形结束需要的时间一般用毫秒或秒来表示 , 过渡的动画效果(linear/ease/ease-in/ease-out) ,动画开始需要延时的时间
Linear线性过渡
Ease 平滑过渡
ease-in 由慢到快
ease-out 由快到慢
比方说:transition:all 0.3s ease 0.5s;
这是复合属性,也可以单独写:
Transition-poterpy:all; 动画给哪个样式加加 all就是给所有的css属性加
Transition-duration:0.3s; 动画执行多长时间
Transition-timing-function:ease; 过渡效果
Transition-delay:0.5s; 延时
谁变化、有动画,给谁加过渡属性!!!
十四天
动画效果
Animation 动画 使用关键帧keyframes定义动画
Animation:name 5s{从开始到结束的时间} ease(过渡的效果) 6s{动画的延迟时间} 动画的循环次数 写infinite 就是无限循环 播放动画的播放方向(alternate摇摆播放、reverse 倒叙播放) 此复合属性6个值
@keyframes name{
From{}=0%
20%{这里面写CSS样式}
62%{}
To{}=100%
}
QQ对话框背景图片效果
Border:上右下左的最大值有单位
border-image:引入图片 上 右 下 左(四个裁切值,没有单位) fill(填充满,不是透明的写) repeat/round/默认的stretch(拉伸)
裁切时注意其他方向别切没了
:first-of-type 同类型的第一个
:last-of-type同类型的最后一个
:nth-of-type()同类型的第几个
:disabled 不可用的表单元素
:enabled 可用 的表单元素
::selection 选中之后改变的状态 两个冒号
浏览器标准规范
W3C组织
Html css js
结构 表现 行为(动作)
浏览器的兼容性
不同浏览器对CSS解析认识不同,导致生成的页面效果不一样,写针对不同浏览器的css代码代码就叫CSS hack其分类有(hack是修改的意思):
IE条件注释hack
<!-- [if ie 6]>
<h2>如果等于IE某个版本</h2>
<![end if]-->
<!-- [if ie]>
<h2>如果等于IE </h2>
<![end if]-->
<![if gt ie 7]>
<h2>如果大于IE7 也就是8910 11版本</h2>
<!--[end if]-->
<![if lt ie 8]>
<h2>小于IE8 也就是IE6 7</h2>
<!--[end if]-->
<!-- [if ! ie 8]>
<h2>IE中除了IE8都能看见我</h2>
<![end if]-->
gt:大于
gte:大于等于
lt:小于
lte:小于等于
!:非或者不等于 非IE中某个版本,但不能!IE
2.CSS选择符注释法(只针对IE6 7)在选择器前面加
*html .header{height:30px; background:red;} 前面写上*html只有IE6认识它
*+html . header{height:30px; background:red;} 前面写上*+的话只有IE7 认识它
要求:先写一般的,再写这个带选择符特殊的
3.CSS属性注释法(常用来改变高度)
Color:green;
_color:red; _或者-减号是专门给IE6用的
*+color:red; *+是专门对IE7浏览器的
*color:red;是IE6、7都认识的
Height:100px\0; ie8 ie9 ie10 都认识
Height:100px\9;ie6-11 都认识,其实就是限定IE下的样式
如果只让IE9认识写 height:100px\9\0; IE9-11认识;
! important IE7以上版本识别 也就是只有IE6不认识,谷歌啥的也都认识
Color:red!important; 加!important后优先级比行内还高
5新增的css3属性
-moz- FF 火狐
-webkit- Chrome 谷歌
-o- opera 欧鹏
-ms- IE9以上
常见问题及解决
图片问题
1.父元素浮动了并且加了边框,里面有图片,下方会产生空隙
解决方法:img(display:block)或者img(vertical-align:middle;)
2.IE6中如果给图片添加上超链接,图片会自带紫色的边框
Img{border:none/0;}
3.给图片添加超链接之后,并且鼠标放上去时候让显示边框,但边框显示不完整
本身写a:hover{border:1px solid blue}
解决方法:非IE6浏览器下写img:hover{border:1px solid blue}
动的问题的解决方法:在原图片上加一个大小相同的边框白色的
Img{border:1px solid #ffffff}
在IE6下解决办法:a:hover{border:1px solid red}
a{display:block;加上图片的宽高 如果动的话再加上个1像素的白色边框}
再在a:hover{border:1px sold red;}
4.如果连续插入图片在不同行写代码时会产生3像素距离
解决办法img{float:left;}
5.input标签或文字与插入图像垂直方向不对齐时,怎么让其垂直方向对齐
解决办法Img(vertical-align:middle)
间距问题
IE6
1个块级元素左浮,另一个块级元素没有浮动会产生3个像素的间距
解决办法 给另外一个不浮动的元素也让它浮动
2 IE6经典的双边距问题(有浮动的元素,给浮动元素加了magin-left:)
给其中设置margin-left的那个元素设置display:inline
第二种margin-left:10px _margin-left:5px 因为后者只对IE6起作用
第三种办法给前面的设置margin-right属性
3.IE6水平居中问题(margin:0 auto;不好用)
Body{ width :800px; margin:0 auto; text-align:center;}
再加上text-align:center;但是这样会让里面的文字居中对齐,如果不让居中,就再在里面的每一块设置上text-align:left;
4.*{margin:0; padding:0;}写上这些
5,margin-top引起的两个问题
A:margin-top叠加问题 上下设置了margin-top和margin-bottom,最后的值是取最大值,上下取最大值,左右累加
B:给子元素加margin-top时,加到父元素上去了
解决办法 不给子元素加了,给父元素加padding-top,或者依然在子元素随便写多少,但是父元素上要写上个padding-top:0.1px;
其它
1、 鼠标指针问题
加上cursor:pointer(指针)、hand(手) 最好用前面的,hand只有ie认识。Cursor后面也可以加cursor:url();用图片。但是图片是ico、ani、cur后缀的
Cursor:url(img/1447.ani),auto;
2透明度问题
一般使用Opacity:0.5,但是IE678不认识这个问题,就在它后面再加上个filter:alpha(opacity=50);
3.一行文本的垂直居中方式
Verrtical-align:middle 但是这个不实用。用line-height:height;
4:hover对IE6浏览器只能a标签使用,但是我还想给其它标签使用,可以借助JS实现
5.IE中不认识min-height和min-width
LESS学习
语法:less中文简体
@charset “utf-8”;
注释:
单行注释: // 编译后不在CSS中出现
多行注释: /*注释的内容*/ 编译后会跑到CSS中起
1普通变量的定义
声明@color:#546783;
下面使用h2{color:@color;background:@color;}
Mixins(混合)
2在一个类别选择器可以使用已经定义好的另外一个类别选择器
声明:
.width{width:960px; margin:0 auto;}
.p{.width;}
如果不想在CSS文件中输出这个mixin 声明时.width(){width:960px; margin:0 auto;}也就是说加个小括号
3带一个参数的mixins
声明 .pos(@p){
Position:@p;
}
使用:li{.pos(relative);}
4带一个参数并且有默认值
声明
.pos(@p:relative){position:@p;}
使用 li{.pos();}这里直接调用就是用的默认值,li{.pos(absolute);}
5 带多个参数的mixins
声明:
.pos(@p;@left;@top){
Position:@p;
Left:@left;
Top:@top;
}
使用:
Li{
.pos(fixed;100px; 20px);
}
考虑到定位有在左边有在右边,声明中不写@left; 使用中就只写.pos(fixed;20px); 然后下面单独写left:100px; 或者right:100px;
SEO(搜索引擎优化)
javaScript学习
ECMAscript(基础语法)
BOM:使用js控制浏览器(大小、开关等)
DOM:与网页的内容交互、控制页面中的标签
ECMAscript:基础语法
这三部分组成了javascript
变量名:数字、字母、下划线、$的组合但是首字母不能是数字或者关键字保留字
变量的类型
数值型: 1000 4 46 等就是数字
字符串:单引号或者双引号引起来的
布尔类型: 分为true 非0 或者 false 0两个值 叫bool或者boolean
空类型: null
Undefined类型:声明了变量但是没有赋值则为此类型
引用类型:object类型
函数typeof();用来得到变量或者常量的类型
将字符串转换成数值型
求整 用函数parseInt(); console.log(parseInt(3.14)); 出来的是3
第一步:找到第一个非空格字符2.如果第一个非空格字符是数字或者正负号,则开始转换3.如果第一个非空格字符不是数字或者正负号,则返回NaN(not a number);
4.直到碰到第一个非数字字符停止转换。
将字符串互转成浮点型 parseFloat();
比方说“-3.1426”用parseInt();转换后是-3 用parseFloat();得到的是-3.1426
当字符串可以成功转换成number类型数据时,我们可以直接把字符串与number类型数据进行比较,系统会自动转换成number
将数值型转换成字符串
用toString();函数 var a=3.14 转换成字符串a.toString();
运算符加上变量或者常量叫表达式
运算符
算数运算符:+ - * / %(取余数)
其中+除了作为数值运算符,还作为字符串连接符
赋值运算符:=
等号的左边不可是常量,必须是变量
关系运算符:> >= < <= == !=
逻辑运算符: &&(与、且) ||(或) !(非)
!表达式 就是颠倒黑白 ,真的变假的,假的变真的
3&&2; 计算机打印的是2 因为需要看&&之后的。。打印的是最后执行的
3|| 2;的话计算机打印的是3 因为不需要计算后面的
Var a=1,b=1,c=1,d=1,m=1,n=1;
(m=a>b) &&(n=c<d); 求m n的值 计算时,左边a>b不成立,为flase 也就是0;所有m=flase 也就是m=0;因为左边是假的,是&&表达式,所有计算机为了效率根本不去执行右侧的部分,所以n为原始值1;
对于表达式1||表达式2,只有表达式1的值为假的时候,才会计算表达式2的值
在 表达式1&&表达式2 中,只有当表达式1的值为真的时候,才计算表达式2的值
自增 a++ 让a 的值加1
自减 a - - 让a 的值减一
//a++ 与 ++a的区别在于自增表达式的值;a++是先赋值再+1,表达式的值也就是还没有+1之前的值,而++a是先++后赋值 ++A表达式的值是a+1之后的值
之后其实a都变成了+1之后的值,但是表达式存在是+1之前或者是+1之前
只可以对变量进行++ - -运算
复合算数运算符 += -= *= /= %=
a+=2; 就相当于a=a+2; 功能:将a的值加上2后再赋值给a
三目运算符
运算符的优先级 ()
! ++ -- 他们相同
*/ %
+ -
> >= < <= != ==
&&
||
= += -= *= /= %=
此运算符当牵扯到相同优先级时,按表达式从左到右计算它
Var 是定义变量的关键字
Function是定义函数的关键字,但是函数并不会自动执行,需要调用函数时才会执行,函数是对功能的封装,把多行代码封装到一起。
由事件触发的函数,无论定义在哪里都没有问题,但是不是由事件触发的函数必须定义在body最底下
流程控制
顺序结构
选择结构(分支结构)
If
if (表达式/变量) {
代码块
};
当程序自上而下执行时,碰到if结构,首先计算if后面小括号中的表达式的值,表达式的值为真,则执行大括号中的代码块,表达式的值为假,则直接跳过if结构。
if-else
二分支结构
【逻辑】当程序执行碰到if-else结构式,首先计算if后面小括号中的表达式的值,如果表达式的值为真则执行代码块1;如果表达式的值为假,则执行代码块2;
它也可以通过三目运算符(选择运算符)来表示:
条件表达式?表达式1:表达式2 【意思就是如果条件成立执行表1,否则表2】
例如var max=(a>=b?a:b);首先计算a>=b是否成立如果成立整个三木运算符表达式的值是a,否则的话整个三木运算符表达式的值的b
if---else if
if(表达式1){
代码块1
}else if(表达式2){
代码块2
}else{
代码块3
}
当程序碰到这个结构时;首先计算表达式1的值,表达式1的值为真,执行代码块1,然后跳出if---else if结构(自动跳出不需要加break);表达式1的值为假则进入else判断表达式2……
在if else if结构中,每一个else都是对前面所有if条件的否定
If----else if经常用在分段条件判断中 每一个else都是对前面所有if条件的否定,所有不需要重复前面的条件
confirm("什么东西"); 这是BOM自带的确认窗口
调用此方法会得到一个值ture或者false
prompt(“请输入一个整数”);
这是输入框,可以向浏览器中输入信息,有返回值,返回值为输入的内容,返回值类型是字符串
4. 编写一个成绩测评系统,输入语文、英语、数学、化学和物理五门课程成绩。输出对学生的评级,要求平均分超过85,无不及格成绩,为优秀,有不及格成绩为良好,70以上为良好,60以上为及格,其余为不及格。
Switch 当条件是等值判断时,多分支结构
循环结构
Switch(表达式或者变量){
Case 值1:代码块1;break;
Case 值2:代码块2;break;
……
Default:代码块n;break;
}
【注】小括号中表达式的值或者变量的值 可以是任意类型的数据。可以number类型,可以string类型 ,可以boolean类型等,这是JS语言所特有的;
【逻辑】当程序碰到switch结构的时候,首先计算小括号中表达式或者变量的值,然后根据所得到的值到大括号中起寻找匹配项(case后面的值==表达式的值或者变量的值),然后从对应的匹配项进入进入switch结构,执行代码块。直到碰到break语句跳出switch结构。如果没有找到匹配项则执行default后面的代码块,然后跳出switch结构。
在switch结构中 break语句可以省略。但是省略后会继续往下执行,无论case是否匹配,直到又遇见break,break的作用就是跳出switch结构!
我发现当省略break时,往下找到有break的case。这个时候这个case代码块里面得到的值,依然是最开始传进来的值,也就是说
如图。Case2有break。当case1的break不起作用时,而mon=1时,case的mon=1
另外default语句也可以省略,但是不推荐;
数学方法
[全部都是静态方法,所以要用引用类型名字调用Math.方法,在字符串方法中有个String.fromCharCode()也是静态方法—找asicii码对应的字符]
产生一个随机数:Math.random(); 这个方法产生的是0-1之间的浮点型数据。但是包括0 不包括1也就是[0,1)
如果得到的是0-10 就Math.random()*10就可以了
当想得到1-9;也就是得到a-b之间的数Math.random()*(b-a+1)+a
想得到:[2,8] 乘以(b-a+1) 也就是乘以7 得到 [0,7) 再加a也就是 +2 --->[2,9)但是它永远达不到9,所有取整之后就是【2,8】
Math.pow(x,y) 是计算x^y也就是x的y次幂
Math.pow()返回值是一个浮点型数值
注意:不要将浮点型的等值判断作为分支条件
比如:var f=2/5;
If(f==0.4){……}
数学方法3
Math.round(3.5);//四舍五入方法=4
Math.ceil(10.0001); //向上取整 =11
Math.floor(10.9999);//向下取整=10=parseInt();
Math.max( 1,14,123,204.5,30.3); //取最大值 204.5
Math.max( 1,14,123,204.5,-3,30.3);//取最小值 -3
Math.abs(-10) ; //取绝对值
Math.sqrt(25); // 开平方
________________________________________________________________
循环
While
Do- while
For 三种循环
两要素:1循环次数 (循环变量 初值 条件 步长) 2.循环操作
循环变量赋初始值
while(循环的条件){
循环操作
循环变量的步长
}
Do -- while循环
循环变量赋初值
Do{
循环操作
循环变量的步长
}while(循环条件)
【逻辑】当程序碰到do---while结构时,首先执行一遍循环体,然后循环变量发生步长,然后判断循环条件,如果成立接着再次执行循环体,直到循环条件不成立,跳出do---while结构。
Do---while 和while什么区别呢?
While先判断循环条件,再执行循环体,而对于do—while来说,不过条件符不符合,我先执行一遍循环体再来判断条件
所有如果循环条件一开始就不满足,while结构的循环体一次也不会执行,do---while结构的循环体会被执行一次。
For循环
For(循环变量赋初值;循环条件;循环变量的步长){
循环操作
}
【逻辑】
1循环变量赋初值;
2.判断循环条件是否成立,如果成立执行3如果不成立执行第五步
3执行循环操作
4循环变量的补进,然后执行第二部。
5跳出循环
计算最大公约数
Var a = parseInt(prompt(“请输入a的值”));
Var b = parseInt(prompt(“请输入b的值”));
分析得到,最大公约数比最小的值还要小或者一样大;
If(a<=b){
Min=a;
}else{
min=b}
for(var i=min; i>=1;i--){
if(a%i==0&&b%i==0){
alert(“最大公约数是”+i);
break;
}
}
Continue作用:只能用于循环结构,当程序碰到continue语句时候,结束本次循环,继续下次循环
Return;返回语句,只能用在函数体中。程序碰到return语句函数调用结束
。Break语句,只能用于switch结构与循环结构,在switch结构中碰到break语句直接跳出switch结构,在循环结构中碰到break语句直接跳出循环结构;往后就不执行了
Break一般与死循环结合使用 循环次数无法确定的时候用死循环+break while(1){死循环}
循环的 嵌套,循环体中还有循环,外层循环执行一次,内层循环执行一遍
对于while 和dowhile来说,如果后面条件永远为真比方说while(1)则死循环。对于for循环。第二个表达式不写则为死循环。For (var i=1; ; i++)
当循环次数不确定的时候使用死循环,使用死循环必须有能够使其跳出的break语句
函数
函数就是把完成特定功能的一段代码封装起来。给该功能起一个名字(函数名)。哪里需要实现该功能就在那里调用该函数。函数可以在任何时间任何地方调用
作用:使程序变得简短而清晰,有利于程序维护。可以提高程序开发的效率。提高了代码的重用性。
当代码封装到函数中时,这段代码什么时候执行,在什么地方执行都是可控的。
如何定义一个函数?
Function 函数名(参数列表){
函数体,也就是代码块;
}
- function关键字不能少,
- 函数名----顾名思义(功能名)
- (a,b,c)函数中有三个参数,分别是参数a,参数b,参数c.在函数体重可以对这三个参数进行操作
- {函数体} 所谓的函数体就是为了实现功能而书 写的代码,其中有个return语句,后面只可以跟一个值,就是函数的返回值。Return可以写也可以不写。碰到return语句时,函数调用结束。
而定义此函数时,。里面的参数叫形参 function isFlower( a ){} 里面的a是形参
当调用函数时,小括号里面的值叫做实参,实际的值,具体的数值isFlower(i ) 这个i就是实参,
因为定义函数时需要一个参数,在调用函数时需要给该函数传递一个具体的数值,也就是i,这个行为叫做传参。传参也就是赋值。
对于大部分语言,实参的个数需要与形参的个数类型一致。但是对于js语言来说,不会检查实参的个数,也不会检查形参的个数
Js语言可以传递任意个参数
在js中每一个函数的函数体中都有一个arguments对象。它类似一个数组
获取每一个实参的值arguments[0] 得到第一个实参。Arguments.length得到传递实参的个数
函数的重载:函数名一样,但是函数的形参不一样(个数不一样,类型不一样,顺序不一样)。但是因为JS语言不去检测参数,所以JS中没有函数的重载
所以在js语言中,当函数名与上面的函数名一样的时候,新的函数会覆盖掉旧的函数,函数会被重新定义。不会实现重载!js语言中是没有函数重载的
变量与作用域
函数的作用域
局部变量:在函数块中定义 的变量 作用域范围:函数体内
全局变量:函数外面定义的变量,作用域是整个HTML页面,另外在函数块中定义时没有var关键字的也叫全局变量
Js在加载script标签时,先把标签的全局变量的声明给执行一遍(开辟空间),然后才开始执行,所以在定义的全局变量b=“abc”之前alert(b),会提示undifind
当局部变量与全局变量名字一样的时候,在局部变量的作用域范围内,局部变量起作用。 但是如果我想在局部变量的作用域内使用全局变量。写window.全局变量名
函数的返回值:
- 直接输出
- 赋值给一个变量
- 作为另一个函数调用的参数 gcd(gcd(2,3),12)
- 可以作为表达式的一部分参与运算
函数的调用:1函数名() 2.事件触发(js语言中使用概率最高)
函数调用注意:1.可以在任何地方调用函数,2可以在一个函数体中调用另一个函数,3.可以在函数体中自己调用自己(这种函数叫递归函数)
没有函数名的叫匿名函数 function(){代码块}
调用时,把这个匿名函数赋值给一个变量 var f=function(){代码块} 通过变量名()调用匿名函数。 调用时f();
Onfocus()获得焦点 onblur()失去焦点 这是鼠标需要点击以下才能实现
递归函数对栈空间的消耗大。如果递归的次数太多的话会造成栈溢出。理解比较麻烦经常用于特定的情况,比如二叉树的遍历,计算阶乘
递归函数类似于循环,任何一个单层循环都可以写成递归函数
For(var i=1;i<=5;i++){
Document.write(“hero”);
}
改成递归:
Function printhero(n){
If(n>=1){ //循环的条件
Document.write(“hero”); // 循环操作
Printhero(n-1);//步进
}else{
Return;
}
}
数组(常用的官方的引用类型)
数组中的每个值叫做元素,每一个元素都有自己的位置。这个位置叫做索引,索引从0开始
对JS语言来说同一个数组中可以放入不同类型的数据
字面量法创建数组
// 1.字面量法创建数组
var arr=[];
//当使用字面量法创建数组的同时给数组赋值,最后一个如果加,会造成ie8及以下读取数组长度+1,造成浏览器兼容问题,所以不加,
var arr1=[1,2,,4,5.56,true,"gag"];
console.log(arr1.length);
console.log(typeof(arr1));//object 引用类型相当于其它语言中的类。
//数组是js语言中使用概率较高的引用类型之一
构造函数法
//2.构造函数法创建数组(new关键字可以省略,new的意思是程序员手动在堆空间开辟空间)
var arr2 = new Array();//空数组
var arr3 = new Array(20);//创建了一个容量为20 的数组
var arr4 = new Array(1,2,3,4)//创建了一个容量为4的数组
var arr6 = new Array(4);
arr6=[1,2,3,4,5,6,7];// 不能这样给new出来的数组这样赋值,要通过遍历
//使用构造函数法穿件数组的时候,如果只传一个值,这个值是number类型的,那么必须是大于等于0的整数,否则会报数组非法
// 获取数组的方法 下标法
// 对js而言没有数组越界的概念,当[index]超过数组的长度时,数组会自动扩充到index+1
数组的遍历
var arr=[1,2,3,4,5,6,7,8,9,10];
console.log(arr.length);//获取数组的长度
arr.length=8;//可以通过修改数组length的值来修改数组的长度,长度变化后,后面的值就被删除或者添加undefined。
console.log(arr.length);
// 遍历数组----就是获取数组的每一个数组元素
//先给数组赋值
var arr1=new Array(20);
for(var i=0;i<arr1.length;i++){
arr1[i]=i*2;
}
//1,遍历数组for循环方法
for(var i=0;i<arr1.length;i++){
document.write(arr1[i]+" ");
}
//2.for in 前面j是循环变量(也就是下标,从0开始到数组长度)。 in后面是数组名字
for(var j in arr1){
document.write(arr1[j]+" ");
}
//3.forEach ECMAScript5.0的新内容
//forEach是对数组中的每一个数组元素进行函数体中的操作,他不支持break语句 可以有return语句
// 里面是一个匿名函数,匿名函数的形参(num也可以其它名字,必须有。)就是数组的元素,把整个匿名函数当作forEach的实参
// 只有在遍历数组取值的时候才能使用for in 和forEach
arr1.forEach(function(num){document.write(num+" ")})
上面的它就相当于:function fun(num){
Document.write(num+” ”);
}
For(var i=0;i<arr1.length;i++){
Fun(arr1[i]);
}只是这两个在底层封装好了
数组中常用的方法
var arr=[1,1,2,3,4];
// 1 .push() 向数组末尾添加元素,返回值是改变之后数组的长度,原数组改变
arr.push("abc",34,23);
// 2 .pop()弹出数组的元素,删除数组末尾的元素 数组的长度减一,返回值是弹出来的数组元素
console.log(arr.length);
console.log(arr.pop()+"pop的返回值,也就是最后一个元素");
console.log(arr);
//3.shift() 弹出第一个元素,返回值是删除的第一个元素
arr.shift(v1,v2,v3,……);
//4 .unshift()在头部插入元素,返回值是改变后数组的长度
arr.unshift("asdf",200);
// 5.join(str)将数组元素按照写入参数链接成字符串,如果不写是默认逗号链接 返回值是连接好后的字符串 本身数组不变
arr.join("*");
//6.reverse()将数组元素倒置,返回的是倒置后的数组 ,原数组改变
arr.reverse();
// 7.concat(v1,v2,v3,……)将数组的数组元素与参数拼接起来,在最后面拼接,形成新的数组
// 返回值L:返回新拼接成的数组,但是原来的数组不会改变
arr.concat(1,2,"csd");
// 8.slice(startIndex,endIndex)截取数组的一部分。返回值是返回截取到的部分,原来的不变
arr.slice(2,5);//从下标为2到5,但是包括2 不包括5
// 9 splice(index,howmany,v1,v2,……) 向数组添加数组元素,或者删除数组元素,index必须写,意思是从下标几开始
// howmany为0,表示不删除元素。howmany为2,删除从index开始本身+后面长度共为2的元素
// v1,v2可选的,替换的数组元素,删除了上面的添加了这俩
// 注意上面index都包括了本身
// 10.toString() 将数组转换成字符串,返回值是生成新的字符串,但是原来的数组不会改变
arr.toString();
// 11. indexOf(v1)//从数组的头部开始查找v1,返回v1第一次出现的下标(没找到返回-1)
arr.indexOf(4);
// 12 .lastIndexOf(v1)从数组的尾部开始查找,返回v1第一次出现的下标
数组的排序
冒泡排序法
升序,1相邻的数组进行比较;大的沉底 2.开始的一对到最后一对比较共进行进行length-1轮 外层循环控制趟数 内层进行比较,比较次数为length-1-i;
3第一轮对所有的数组元素,都要进行冒泡比较,除最后一个元素(它没法和后面的比较了,后面没了)
for(var i=0;i<arry.length-1;i++){
for(var k=0;k<arry.length-1-i;k++){
if(arry[k]<arry[k+1]){
var little=arry[k];
arry[k]=arry[k+1];
arry[k+1]=little;
}
}
}
选择排序
从头开始和后面所有的元素进行比较,每次确定最头上的
var arr=[0.4,5,3,12,-3]
for(var i=0;i<arr.length-1;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
var thr =arr[i];
arr[i] = arr[j];
arr[j]= thr;
}
}
}
alert(arr);
3 sort官方也定义了一个数组的排序函数,但是是按照ascII码的大小从第一位开始比较,也就是3会大于29;
如果想要按照自己的规则进行排序,我们需要给sort传递一个实参,实参为函数名
var arr=new Array(3,2,8,1,50);
arr.sort(compare);
// 从小到大的排序 a和b代表的是数组的前一个元素和后一个元素
function compare(a,b){
if(a>b){
return 1;
}else if(a==b){
return 0;
}else{
return -1
}
// 或者直接
// if(a>b){
// return true;
// }else{
// return false;
// }
// 再或者直接
// return a-b;
}
数组交换元素位置
var arr=["a","b"];
[arr[0],arr[1]] = [arr[1],arr[0]];
字符串
字符串常用的方法
// 字符串的包装类型-----添加了方法属性
var str="abc"; //string类型
var str2 = new String("abcdefg"); //object类型,为引用类型,包含属性和方法
console.log(str);
console.log(str2); //{}----引用类型的实例
//在js中string类型的字符串也可以使用object类型中包含的属性 方法
//js会默认的将string类型转换成object类型,然后使用在object类型中定义好的属性和方法
// 字符串常用的属性和方法
// 1.长度 length 仅仅可读,没法修改
str2.length=10;//不可以
console.log(str2.length);
// 2.获取指定下标的字符 charAt() 下标从0开始的
// 返回值是字符
console.log(str2.charAt(1));
// 3.获取指定下标的字符的ASCII码, charCodeAt(index)
// 返回值 ASCII码(0~127的整数)
console.log(str2.charCodeAt(1));
// 4.将ASCII码转换成对应的字符, String.fromCharCode(); 这个必须用引用类的类名String来调用
console.log(String.fromCharCode(65)); //输出大写的A
// 5.查找子串,从字符串开头查找子串,返回子串第一次出现的位置,
// indexOf("子串"); 而lastIndexOf("子串")是从后面找,找不到都是返回-1
console.log(str2.indexOf("cde"));
// 6.替换子串 replace("被替换的子串","变化后的子串");
// 返回值是被替换后的字符串,但是原来的字符串并没有改变
// 参数1是被替换的字符串或者正则表达式 参数2是替换后的字符串
/*初窥正则表达式(在//之间写着)
/abc/标记
标记:g----就是全局
i--不区分大小写
比方说str="abcabcaacdaacaa"
str2.replace("aa","***");这样只替换第一个aa
str2.replace("/aa/gi","***");这样替换所有aa且不区分大小写Aa也被替换
*/
// 7.截取子串 substring(参数1,参数2),只有一个参数的时候是截取到末尾,【两个是截取中间的,无论一个或两个参数原来的字符串不会改变=数组slice】
// 返回值是截取到的子串,
// 8.substr(参数1,参数2); 一个参数截取到末尾,两个参数时,参数二代表截取的长度
// 9.字符串大小写转换toUpperCase(); 转大写toLowerCase();转小写 原来的字符串不会改变
// 10.字符串相等的判断 == 返回true或者false
// ==是值相等就可以10=="10" true ===是绝对相当 类型值都一样 10==="10" false
// 11.split字符串分隔符与数组的join()想对应,它是将字符串分割成数组
var str="welcome to beijing";
alert(str.split(" "));
字符串的大小比较,是从头也就是下标为0开始比较两个字符串的第一个位数的ascri码比较,如果下标为0的相同,再比较下标为1的。。直到找到不同的
字符串调用正则表达式的方法:
Str.math(parrent);
Str.search();
// 字符串关于正则表达式的函数
// match() 返回符合模式的子串组成数组或者是null
// search() 返回下标 或者 -1
// 只要找到返回下标,找不到返回-1 全局g修饰无用与RegExp 的test()一样
// replace(parrent,"新内容") 返回值就是替换之后的新字符串 但原来的字符串不变
// split(parrent) 返回值是数组
var str="this is a BOX or box?what a box……box";
var rex=str.match(/box/gi);
console.log(rex instanceof Array);
console.log(rex);
console.log(str.search(/box/i));
console.log(str.replace(/box/gi,"top"));
console.log(str);
BOM
------浏览器对象模型
// BOM(浏览器对象模型) Browser Object Model
// BOM就是js获取以及管理各个浏览器的内容
// js通过window这个全局对象来管理浏览器
// 所以在html页面定义全局变量 函数 都属于window这个全局对象的属性和方法
var a=100;
function fun(){
// alert("我是一个函数");
var b="abc";
window.a;
}
// alert(window.a);
window.fun();
window的对象属性
// window的对象属性有:
// document文档 history历史 location地址 frames框架 navigator导航器(获取浏览器是哪个厂商的) screen屏幕(获取分辨率啥的)
// 上面前三个重要
window.location.href="www.baidu.com";
window.location.reload();//刷新 带本地缓存
window.location.reload(true);//不带本地缓存
window.history.back(); //上一个历史记录
window.history.forward(); //下一个历史记录
window.history.length;//获取历史记录的长度
window.history.go(数值); 去第几条历史记录【在去的历史记录中,back和forward不会产生新的history,正数值往前,负值往后】
常用的方法
window.open("3.html","_blank","width=100px,height=300px,top=100px,left=30px,toolBar=yes,location=no");其中toolBar是工具条
window.open("3.html","","fullscreen=yes");
window.close();//这种方式关闭的窗口,在FF只能关闭window.open();打开的窗口
alert(弹出框),confirm(选择框) prompt(输入框)方法
模态弹出框(意思是不点击让当前窗消失,就无法操作其它的)
showModalDialog("url也就是要跳转的页面",参数2,"dialogWidth=200px;dialogHeight=200px");
第一个参数是将要打开的模态框的地址,参数2是将要传递到模态框的数据,参数3是模态框的一些数据。
参数2要在那个模态框里面接受一下用,
常用的事件
window.onload()=function(){
//页面加载完成后(执行完最后的html)执行里面,无所谓script的位置了
$("id").onclick=function(){
//这是给按钮的点击事件赋值/绑定了一个函数
}
}
window.onscroll()=function(){
//浏览器滚动触发此方法
console.log("go away!!");
// 浏览器支持那个属性就取哪个属性的值,获取浏览器滚动的高度值
var scrollTop = document.body.scrollTop||document.documentElement.scrollTop;
console.log(scrollTop);
可以通过修改document.body.scrollTop||document.documentElement.scrollTop这两个的值来控制滚动条滚动的距离;[回到顶部]
var top=document.getElementById(‘top‘);
top.onclick=function(){
document.documentElement.scrollTop=0;
document.body.scrollTop=0;
}
}
窗口大小变化事件onresize();
window.onresize=function(){
console.log("便便便便");
//获取可视区域的宽高
var width = document.documentElement.clientWidth||document.body.clientWidth||document.innerWidth;
var height=document.documentElement.clientHeight||document.body.clientHeight||document.innerHeight;
console.log(width+"width"+height+"height");
定时器
连续性定时器
setInterval(函数名,时间(毫秒单位));//每隔固定的时间调用一次函数
clearInterval(定时器的名字);//停止某个定时器
延时定时器
setTimeout(函数名,时间); //过了指定的时间后,函数才会执行,只执行一次
clearTimeout(定时器名字); //清除定时器
DOM
文档对象模型
W3c定义的访问html的标准
如何获取获取、修改、添加、和删除标签
节点
HTML文档中的所有内容都是节点
整个页面是文档节点
整个标签是元素节点
标签里面的属性就是属性节点
页面中直接写的文本或者标签之间的空白叫文本节点
注释叫注释节点
节点层级关系:根节点 、父节点、子节点、兄弟节点
获取元素节点方法:
document.getElementById();
var oinput =document.getElementsByTagName(“标签名”); 返回值是一个集合(下面俩也是,所以是elements)
用instanceof 来判断某个对象是不是某个引用类型的实例
alert(oinput instanceof Array);
document.getElementsByClassName(“clsaa属性的值”)通过class获取(IE8以下的浏览器无法获取)
document.getElementsByName(“name的值”); 有name属性的标签,一般是表单元素用
上面的四种方法都是从整个文档中查找元素节点。我要是想查找某元素(也就是标签、对象)的子节点元素(这个对象.getElementxxxxxx):
对象.getElementsXXX();
如:document.getElementById("box").getElementsByTagName("div");ID为box下面的子节点
获取官方定义的属性节点
document.getElementById().属性名------------也就是先获取到元素节点(标签)然后 .属性名字【返回的是这个属性的值】
设置官方定义的属性 节点的属性值
document.getElementById(“IDname”).属性名=”属性值”; 属性值必须要用引号括起来。
获取自定义的属性节点【用不大到啊】
Document.getElementById(“”).getAttribute(“自己写在标签中的属性名”);//得到的是自己写在标签中的属性名的属性值
Document.getElementById().setAttribute(“自己写的属性的属性名“,”这个名的值”);
修改自己写的属性的属性名的属性值
Document.getElementById().removeAttribute(“自己编写的属性名”);//把自己写的属性名删除掉
获取文本属性的方法
innerHTML获取文本标签之间的内容,但是不包括这个文本标签
outerHTML获取文本标签之间的内容,包括这个文本标签
innerText 只获取里面的文本信息 不包括里面的标签
常用的元素节点
对象.tagName标签名字 对象 .className获取class的值。。不能是.class
对象.id.title
对象.属性名.属性值 或者$(“id”).style[“width”];
Css脚本化(样式操作)
设置行间样式表的属性的属性值
$(“id”).style.width=“100px “ 如果是个border-radius 修改成borderRadius 不认识-
设置内部样式表或外部样式表
$(“id”).style.width=”100px”;
【这是获取行间样式表的方式】也就是$(“id”).style.width;
获取内部样式表或外部样式表的属性值
Window.getComputedStyle($(“id”),null)[“属性名”];这是非IE下的获取方法,null指的是伪类,没有就写null
$(“id”).currentStyle[“属性名”]; IE浏览器下获取方法
style与getComputedStyle区别:前者可读可写,后者只读,style获取的属性少,只能获取行间样式表中所设置的(如果复合属性能获取到所有的复合属性的值),后者是获取最终的属性,电脑上所有的样式属性
// 封装一个函数,通过这个函数获得相应的属性
function getStyle(element,attr){
if(window.getComputedStyle){
return getComputedStyle(element,null)[attr];
}else if(window.currentStyle){
return element.currentStyle[attr];
}else{
return element.style[attr];
}
}
console.log(getStyle(元素,"height"));
创建元素节点
Document.createElement(“div”);
只能由document来调用,参数是标签名字
//父节点.appendChild(子节点名字)
//将子节点添加到父节点孩子列表的最后一个
$("list").insertBefore(firstLi,lis) 在谁前面添加。 参数1是新加的,二是旧的
document.body.appendChild(odiv); 一定要记得添加到页面上用这句话
父节点.removeChild(“子节点名字”); //移除节点
this.parentNode.parentNode 这个parentNode是当前节点的父节点
document. createTextNode 创建一个文本节点,(当然只要是创建就要添加到父节点上咯)
对象偏移量
//offsetLeft-------偏移量 left的值(父元素及以上都没没定位就是相对于body,直到找到有定位的为止)
//offsetTop-------偏移量top的值(父元素及以上都没没定位就是相对于body,直到找到有定位的为止)
// offsetWidth-------节点本身的width的值
// offsetHeight------节点的height的值
//offsetParent -----获取该节点上面进行了相对定位的父节点,都没找到就找到了最终进行了相对定位的body
rightW=$("box").offsetParent.offsetWidth-$("box").offsetLeft-$("box").offsetWidth;
后面为一些常用属性方便查找:
clientHeight 获取对象的高度,不计算任何边距、边框、滚动条,但包括该对象的补白。
clientLeft 获取 offsetLeft 属性和客户区域的实际左边之间的距离。
clientTop 获取 offsetTop 属性和客户区域的实际顶端之间的距离。
clientWidth 获取对象的宽度,不计算任何边距、边框、滚动条,但包括该对象的补白。
offsetHeight 获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的高度。
offsetLeft 获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置。
offsetParent 获取定义对象 offsetTop 和 offsetLeft 属性的容器对象的引用。
offsetTop 获取对象相对于版面或由 offsetTop 属性指定的父坐标的计算顶端位置。
offsetWidth 获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的宽度。
offsetX 设置或获取鼠标指针位置相对于触发事件的对象的 x 坐标。
offsetY 设置或获取鼠标指针位置相对于触发事件的对象的 y 坐标。
clientX,clientY 鼠标当前相对于网页的位置,当鼠标位于页面左上角时clientX=0, clientY=0
screenX, screenY是相对于用户显示器的位置
网页可见区域宽: document.body.clientWidth
网页可见区域高: document.body.clientHeight
网页可见区域宽: document.body.offsetWidth (包括边线的宽)
网页可见区域高: document.body.offsetHeight (包括边线的宽)
网页正文全文宽: document.body.scrollWidth
网页正文全文高: document.body.scrollHeight
网页被卷去的高: document.body.scrollTop
网页被卷去的左: document.body.scrollLeft
网页正文部分上: window.screenTop
网页正文部分左: window.screenLeft
屏幕分辨率的高: window.screen.height
屏幕分辨率的宽: wind ow.screen.width
屏幕可用工作区高度: window.screen.availHeight
屏幕可用工作区宽度:window.screen.availWidth
事件
事件就是用户或者浏览器执行的某种动作 click load等都是事件的名字
事件处理程序,就是响应事件的函数,事件处理程序的名字都是on开头的。一般都是小写
比方onclick onblur等
HTML事件处理程序 将事件处理程序(onclick)添加在html的标签中 无法使用this指针
DOM0 事件处理程序
JS中得到HTML标签(元素节点),给这个元素节点的事件处理程序赋值一个匿名函数
这个函数就属于此元素节点的一个方法。在该函数中可以使用this指针,可以访问这个元素节点的其他属性
Var btn=document.getElementById(“box”);
Btn.onclick=function(){ Btn.onclick=null取消事件处理程序
Alert(this.id)//会出来box;
}
常用的事件
window.onload=function(){
alert("网页加载完毕");
}
window.onunload=function(){
// 页面要跳转走时触发,只有IE支持
alert("本页面要死翘翘了");
//一般进行内存空间的释放
}
window.onscroll=function(){
// 因为只要滚动就调用,所有最简单的操作
}
window.onresize=function(){
//最简单的操作,触发频率太高了,为了提高效率
}
document.getElementById(‘pic‘).onload=function(){
图片加载完成事件
alert("图片加载完毕触发我,需要写在图片html的下面,要不然图片都加载完了就没法触发了");
}
鼠标事件
如果一个元素同时具有单击和双击事件如何处理?不过双击用的比较少
Var timer;
元素(对象).onclick=function(){
clearTimeout(timer);
Timer=setTimeout(function(){
Alert(“单击”)},500);
}
元素(对象).ondblclick=function(){
clearTimeout(timer);
Alert(“双击”);
}
元素(对象).onmouseover=function(){
鼠标从元素外部进入元素内部的时候触发此事件
}
Document.onmousemove=function(e){
鼠标滑动执行里面的代码,我如果传过一个e来
e.clientX 和e.clientY 得到当前鼠标位置,然后随鼠标运动
}
元素(对象).onmouseout=function(){
鼠标从元素内部划出到元素外部的时候触发执行这里面代码
}
元素(对象).onmousedown=function(){
当鼠标点下去的时候执行此处代码
}
元素(对象).onmouseup=function(){
当鼠标抬起时触发的事件
}
键盘事件
document.onkeydown=function(){
键盘按下执行此区域
}
document.onkeyup=function(e ){
键盘抬起执行此区域
e.keyCode;得到键盘上的操作的键的ascii码
}
document.onkeypress=function(){
键盘按下可打印的键时执行此区域【你像shift,Capslk(大写锁定) fn ctrl等就不打印】
只有按下字符键盘才触发这里
}
事件流
页面接收事件的顺序
点击div:Div-----body-----html-----document---------window 由小及大 事件冒泡IE
点击div:Window-----document-----html----body----div 由大及小 事件捕获 网景
W3C事件流
分为三步:事件捕获--------->目标阶段---------> 事件冒泡
Window-----document-----html----body===div===body-----html-----document------window
常用的是事件冒泡,当点击div却不想让div得到这个事件而在半路拦截下来的时候才用事件捕获
DOM0级事件处理程序,只会在事件冒泡中执行,在事件捕获中不起作用
DOM2级事件处理程序,添加一个监听事件addEventListener()
$(“ID”).addEventListener("事件名",函数,布尔值) 布尔值true表示在事件捕获阶段触发事件,false为事件冒泡阶段触发事件;函数也可以写在外面,只写个函数名
清除事件处理程序用removeEventListener("事件名",函数,布尔值); 里面的参数必须和上面的参数一模一样,并且中间的函数必须是函数名,不能是匿名函数
oDiv.addEventListener("click",btnClick,false);
// 布尔值true表示在事件捕获阶段触发事件,false为事件冒泡阶段触发事件
document.addEventListener("click",function(){console.log("document")},false)
function btnClick(){console.log("btn");}
每一个事件处理程序都有一个事件对象event,包含了事件的基本信息,有共有的属性
Event.bubbles 返回true或false 判断此事件是否冒泡 为true可调用------->
event.stopPropagation(); 阻止此事件的进一步冒泡或者捕获
$(“id”).onclick=function(eventaa){
eventaa.stopPropagation();
}
Event.cancelable;是否能取消默认事件 如果能取消就调用event.preventDefault()取消
比方说给a标签加点击了取消默认事件,点击后就不跳转了
Event.type 返回的是事件名 看下面例子
function onevent(e){
switch(e.type){
case "mouseover":
console.log("鼠标悬浮");
break;
case "mouseout":
console.log("鼠标离开");
break;
case "click":
console.log("点击我");
break;
}
}
window.onload=function(){
$("box").onclick=onevent;
$("box").onmouseover=onevent;
$("box").onmouseout=onevent;
}
event.currentTarget 获取当前正在处理事件的当前元素,比方说我点击了当前div,当前div的currentTarget是div。但是它的父级body也有点击事件,父级里面的currentTarget指的是body。而下面的target都是出来的div 因为我本身点的就是div。Body的事件只是冒泡造成的
Event.target 事件的目标元素 ,点击的当前,而currentTarget 获取到的可能是冒泡造成的获取成父级
浏览器的鼠标事件属性
// 在浏览器可视窗口的位置
console.log("浏览器可视窗口X+"+e.clientX,"浏览器可视窗口Y+"+e.clientY);
//在页面中的位置
console.log("整个页面X:"+e.pageX,"整个页面Y:"+e.pageY);
//在屏幕上的坐标
console.log("在整个屏幕上的X"+e.screenX,"在整个屏幕上的Y"+e.screenY);
alert("你按得是谁?"+e.button); //检测按下的是什么键0是左键1是滚轮2是右键
阻止浏览器右键弹出框
Document.oncontextmenu=function(){
Return false;
}
时间Date
世界协调时间,也就是世界时间。从1970年1月1日0点开始
获取当前时间:
// 获取当前时间,传参是无效的
var d=Date();
console.log(d);
// new Date()构造函数获取时间
var d2=new Date();
console.log(d2);
1不传参数 得到的是当前的时间
// 当用构造行数的时候火狐出格林尼治时间,谷歌是转换成当地时间
//2 传入毫秒数,从1970 1月1日开始计算加上传的参数,可以是负值就是1970年之前的
var d3=new Date(24*3600*1000);
console.log("da3"+d3);
//3传入一个表示时间的字符串 月 日,年 时:分:秒
var d4=new Date("6 22,2016 12:00:00");
这个字符串也可以是 “2016-6-22”还可以是“2016/6/22”
console.log(d4);
如果不写时分秒,会默认是0
如果用2016-6-22 来表示传的字符串的话,日也可以不写,是从此月第一天开始
// ISO标准写法 2016-06-12 月份是两位的 假设开发者所在的时区是0度,所以用户看到的=========时间应该是当地日期,也就是+8小时=
// 非ISO写法 如果月份不加0 假设开发者所在时区和用户在一起【这是火狐的事情,FF就没事次奥】
var d5=new Date("2016-06-22");
console.log(d5);
// 传入年月日来创建日期对象
// (年,月[,日,时,分,秒])括号里面的可不写
// 月份的记录从0开始的 0----1月,1----2月。。。。。。。。
var d6=new Date(2016,6,12); 不加引号只能这样写,也就是说传的参数是数值的话只能用逗号隔开
常用的方法
获取四位年份:
Var day=new Date();
day.getFullYear(); 获取年份
day.getMonth();获取月份,因为月是从0开始的,所以要加1
day.getDate();获取日期
day.getDay(); 获取星期几
day.getHours(); 获取小时
day.getMinutes(); 获取分钟
day.getSeconds(); 获取秒数
// 设置年月日(在设置时间时,没有边界,如果超出会在前面位加或者减去,比放说,4日26点,会自动变成5日3点,如果是负的会减去,也就是说传入的月份、日期、时分秒超过范围的话会自动调整为正确的时间)
d.setFullYear(2015);
d.setMonth(13);
d.setDate(12);
// 星期不可以设置
d.setHours(20);
日期的计算
日期相减是返回两个日期对象相差的毫秒数,相加是先将两个对象转换成字符串,返回这两个字符串的拼接
日期的静态方法
Date.parse(参数是一个日期格式的字符串,返回的是这个日期距离1970年1月1日的毫秒数); 注:这里传入的参数都是东八区的时间,会先转换成格林尼治时间(-8小时)再算毫秒数。
日期格式:
月 日,年 时:分:秒 假设开发者在经度0的时区上
2016-04-22 16:06:59 或者2016-04-08
2016/06/22 16:06:59 2016/03/23
Var d =new Date();
d.getTime(); 获取某个日期从1970年距今的毫秒数
d.setTime(); 修改日期距离1970年的毫秒数,对应的日期也会修改
正则表达式
JS中的正则表达式就是RegExp Reg(合法的) Exp(表达式)
正则表达式的创建方法:
1构造函数法创建正则表达式:
Var parrent=new RegExp(“abc”);
一个参数里面的参数abc就叫做模式 也可以理解成后期需要匹配的东西
Var parrents=new RegExp(“abc”,”gi”);
两个参数,前面的是模式后面的是模式修饰符, 参数2可写可不写
比方说过滤敏感词汇,我把敏感词汇放到一个数组里面,然后循环这个数组,每次构造一个正则表达式,表达式每次的模式就是循环取出来的每次的敏感词,然后我让它全局,替换,把替换好的再赋值给原来的字符串,第二次循环就是替换已经替换过上次敏感词的字符串,达到敏感词过滤的效果
2.字面量法创建
var parent=/box/;
或者反斜杠后面添加模式修饰符:var parrent /box/gi;
正则表达式常用的方法:
1.test(); 检索正则表达式中所描述的模式是否存在于字符串中,存在返回true 不存在返回false; 可用i修饰,但是g写不写就无所谓了
Var parrent=new RegExp(“box”,”i”);
Var str=”this is a Box”; parrent.test(str); 返回true;
2.Exec();方法
也是用来检索字符串中是否存在表达式中所描述的模式,但是他返回的是存在的这个值,没有就返回null 另外,则个方法还有一个index属性,调用后返回的是这个值存在的位置
Var parrent= /box/gi;
var str="this is aBOX or box?what a box……box";
Var tex=Parrent.exec(str);
返回的是Box ,tex.index;返回的Box在这个字符串中的下标
如果调用第二遍这个方法,就从已经找到的位置继续往下寻找,返回的就是第二个box和这个box的下标,直到最后找不到返回null ,而这个时候调用的index是报错的。没有怎么告诉下标呢,是吧
这个方法可以透过循环找出所有的下标
While(1){
Var ss=parrent.exec(str);
If(ss==null){
Break;
}
Alert(Ss.index);
}
3compile();方法,用来修改模式,还可用来增加、修改、删除模式修饰符
Parrent.compile(“bzx”,”g”); 就修改完了,我不管以前的正则表达式是什么,反正从现在开始按照我执行就好了。
有几个字符串的方法结合正则表达式使用
// 字符串关于正则表达式的函数
// match() 返回符合模式的子串组成数组或者是null
var str="this is a BOX or box?what a box……box";
var rex=str.match(/box/gi);
// search() 返回下标 或者 -1 str.search(/box/i)
// 只要找到返回下标,找不到返回-1 和字符串的indexOf差不多 与RegExp 的test()一样全局g修饰无用
// replace(parrent,"新内容") 返回值就是替换之后的新字符串 但原来的字符串不变
str.replace(/box/gi,"top")
// split(parrent) 返回值是数组 当正则表达式用/[,?]/表示的时候,就能依据不同的标志分割成数组
一些常用的元字符
[ ] 代表单个字符,无论里面多少表达式,要满足一种就能匹配上,一个【】匹配一个字符
Javascript面向对象
【内置对象】
Object、String、Array、Math-------宿主对象 DOM 、BOM等。
【字面量对象】
通过点 对象 . 属性名或者 对象[“属性名”] 来访问(包括获得值和赋值操作)字面量对象内部的属性值
简单的说可以理解为“名称-值”(键值对);
这种数据类型相当于java语言中的HashMap,C语言中的散列表,Python中字典以及objective-c中的字典等。
这种数据结构可以实现各种复杂的需求,所以适用于各大编程语言中。
语法:字面量对象用大括号表示”{ }”,内部是由各种“名称-值”对组成。
名称和值之间用冒号“:”连接,各组”名称-值”之间用逗号“,”隔开。
注意最后一组不需要加逗号“,” 。
名称部分(属性):是由javascript字符串表示。
值部分:可以是javascript任何数据类型(包括字面量对象,甚至函数)。
例://创建一个含有多组属性-值的字面量对象
var obj3 = {
"name" : "迈克尔·斯科菲尔德",
"age" : 18,
"isMarry" : true,
"friends" : ["小明","小红","小白"],
"wife" : {
"name" : "晓雪",
"age" : 18
},
"sayHello" : function(){
//this代表obj3对象本身
console.log("大家好,我是"+this.name);
}
};
//调用字面量对象内部的字面量对象
console.log("获得晓雪:"+obj3.wife.name); //优先用这种
console.log("获得晓雪:"+obj3["wife"]["name"]);
console.log("获得晓雪:"+obj3.wife["name"]);
console.log("获得晓雪:"+obj3["wife"].name);
// 修改属性的值
obj3.name="小飞侠";
obj3.sex = "男";
如果之前obj3里有这个sex属性,那么这个操作是修改操作,否则就是添加一个属性和值得操作。
Javascript是一种面向对象的动态脚本语言。它的语法和特性是基于C和java等语言的。
【面向过程思想】
注:C语言是面向过程的
解决某个问题,看的是“如何”解决这个问题,是一种数学逻辑的映射,按照步骤执行。
【面向对象思想】
注:Java是面向对象的
解决某个问题,看的是“谁”能解决这个问题。把问题拆解成各个“对象”,对象处理相应的功能逻辑,“对象”之间协同完成工作。对象作为接收消息的基本单位。同时是一种生活逻辑的映射。
【面向对象的几个专业术语】
1.类(class):某一种事物的抽象,是创建对象的模板。
2.对象(object):是某一种事物的实例(真实的东西)。就是能找到具体的东西
3.方法(method):是对象的行为。
4.属性(property):是对象的特征。
【重点从几个角度说下类和对象】
1.从生活逻辑的角度来看
类:人 对象:我 、奥巴马
电脑 这台戴尔电脑 ,你的这台戴尔电脑
超级英雄 超人、蜘蛛侠、 绿巨人 都对,但是葫芦娃不对,二娃对
2.从封装的角度来看
函数:对一些功能逻辑的封装 ,为了封装完之后能重复使用
类:对属性(变量)和行为(函数)的封装。
总结:面向对象编程,是以对象为基本单位进行编程的。但有对象之前,一定要先有类。对象是通过类创建出来的。咱们JS没有“类”的概念,不过我们可以通过其他方式来模拟“类”。(ECMA6已经支持类的概念,不过和传统面向对象语言的类还是不太一样)
//构造函数方式创建对象
function Person(name,age,sex){
this.name=name;
this.age=age;
var sex = sex; //私有属性:构造函数外部,无法直接访问的属性叫做私有属性
// 建立一个所谓的桥梁,来间接的访问私有属性
// 获取私有属性的间接方法
this.getSex = function () {
return sex;
}
this.setSex = function (_sex) {
sex=_sex; //这里是设置其属性值,所以没必要return 分工明确
}
this.sayHello=function(){
console.log("大家好,我叫:" + this.name +"年龄:"+this.age + "性别:" +sex);
}
}
// return this; 这句不用写
//如果外面通过new关键字来调用这个构造函数的话,会自动返回this,也就是当前创建的对象
//通过new关键字配合构造函数,创建一个对象(实例)
//其原理:首先在堆内存申请了一块存储空间,同时在这里创建了一个Person类型的对象,会分配给这块空间一个地址,那么我们想通过栈里的变量来访问堆里的这个对象,只能通过指针来访问。其语法如下
var person = new Person();
模拟类创建对象
function makePerson (name, age) {
return {
"name" : name,
"age" : age,
"sayHello" : function () {
//this指针指向当前对象。
console.log("大家好,我叫:" + this.name + " 年龄:" + this.age);
}
};
}
//通过函数创建一个对象
var person1 = makePerson("小雪人", 18);
//在创建一个对象
var person2 = makePerson("小火人", 19);
//调用各自的sayHello方法
person1.sayHello();
person2.sayHello();
类方法创建对象
//类方法,通过类名(构造函数的名字)直接调用的方法,不需要创建对象,就可以调用的方法
function Person(name){
this.name=name;
// 我就是个空壳子,一个对象空间
}
//其实类方法本身自己不具备创建对象的功能,实质上依然是通过new关键字配合构造函数来创建对象
Person.createPerson=function(name){
return new Person(name);
}
var person1= Person.createPerson("晓雪");
构造函数方式创建对象(就是个模板 最常用的)
构造函数为了和普通函数区分开,往往构造函数的首字母大写
function Person () {
// this永远代表当前对象,也就代表着每次调用Person构造函数创建出来的那个对象。
this.name = "晓雪";
this.age = 18;
this.sayHello = function () {
console.log("大家好, 我的名字:" + this.name + "年龄:" + this.age);
}
// return this; 这句不用写
//因为如果外面通过new关键字来调用这个构造函数的话,会自动返回this,也就是当前创建的对象
}
//通过new关键字配合构造函数,创建一个对象(实例)
//其原理:首先在堆内存申请了一块存储空间,同时在这里创建了一个Person类型的对象,会分配给这块空间一个地址,那么我们想通过栈里的变量来访问堆里的这个对象,只能通过指针来访问。其语法如下
var person = new Person();
我如果不new构造函数直接使用的话内部的this指针会指向全局
===============================================================================
===============================================================================
私有属性
function Person(name,age,sex){
this.name=name;
this.age=age;
var sex = sex; //私有属性:构造函数外部,无法直接访问的属性叫做私有属性
// 建立一个所谓的桥梁,来间接的访问私有属性
// 获取私有属性的间接方法
this.getSex = function () {
return sex;
}
this.setSex = function (_sex) {
sex=_sex; //这里是设置其属性值,所以没必要return 分工明确
}
}
person1.sex="男"; //注意这里不是修改内部的私有属性,而是新增一个sex属性
//调用"桥梁"间接访问私有属性
person1.setSex("未知"); 这样才能访问到
console.log(person1.getSex());
属性访问器(感觉用不到呀)
function Duck(name,age){
this.name=name;
this.age=age;
Object.defineProperty(this,"name",{
"get" : function (){
console.log("这是get访问器!!");
return name;
},
"set" : function(userName){
console.log("这是set访问器");
if(userName!="晓雪"){
console.log("只要晓雪");
return;
}
name=userName;
}
});
}
var dack1=new Duck("小灰",6);
dack1.name="小苏";
dack1.name="小刘";
console.log(dack1.name);
这种方式可以防止随便修改、访问、属性值
原型模式
每个构造函数都有一个原型属性(prototype)这个原型属性指向一个原型对象,我们可以给这个原型对象设置属性和方法,这些属性和方法可以给通过该构造函数创建的对象使用。 换句话说,也可以理解为通过该构造函数创建出来的对象,继承于这个原型对象,可以直接使用原型对象的属性和方法。
【以下这种创建对象的有一个好处就是相比较上面而言,更节省空间,上面的方法在不同的对象里,下面的是无论创造出多少对象,共用一个方法,也就是说方法在同一块内存堆里】
function Person(name){
this.name=name;
}
Person.prototype.sayHello=function(){
//这个this依然表示当前通过Person构造函数创建出来的对象
console.log("大家好,我叫:"+this.name);
}
与原型相关的知识点:
1.支持运行时添加方法,在添加方法之前创建的对象,依然可以使用这个方法
也就是说,我先new出了实例对象来,我又在下面给构造函数添加了方法,这个上面new出来的实例依然可以使用这个方法
2.也可以给内置构造函数的原型添加方法
String.prototype.reverse = function () {
var resultStr = "";
for (var i = this.length - 1; i >=0; i--) {
resultStr += this[i];
}
return resultStr;} str.reverse() "小雪转大雪".reverse()
3.也支持重新覆盖掉,原来的方法,
注意:!!!!不到万不得已的时候,千万别去覆盖系统自带的方法。否则后果自负!!!!
Array.prototype.indexOf = function (ele) {
console.log("乱改!");
}
原型链及其原型方法和属性相关
何为原型链:
每个对象都有一个对应的原型对象,这个原型对象本身也是一个对象,那么既然它也是一个对象,所以它也应该会有一个属于它的原型对象,以此类推,一直到Object.prototype为止。Object.prototype的原型是null。通过以上分析,会形成一条链子,这条链子被称作为原型链。
例:
//通过不同的方式来生成原型链
var obj = {
"name" : "小雪"
}
obj对象继承了Object.prototype的属性和方法
所生成的原型链为:
obj --> Object.prototype --> null
数组
var arr = ["小雪", "小王"];
arr对象继承了Array.prototype的属性和方法
所生成的原型链为:
arr --> Array.prototype --> Object.prototype --> null
函数
function fn () {
console.log("小雪");
}
fn对象继承了Function.prototype的属性和方法
所生成的原型链为:
fn --> Function.prototype --> Object.prototype --> null
自定义对象
function Person (name) {
this.name = name;
}
var person1 = new Person("小雪");
person1对象继承了Person.prototype的属性和方法
生成的原型链为:
person1 --> Person.prototype --> Object.prototype --> null
//Object.create():这个方法可以用来创建对象,创建出来的对象继承于这个方法的参数。换一句话说,也就是,这个方法的参数是一个对象,而且它是创建出来的那个对象的原型对象。
var a = {
"name" : "包女士"
}
//通过Obejct.create方法生成一个新的对象
var b = Object.create(a);
//生成的原型链:b --> a --> Object.prototype --> null
console.log(b.name);
var c = Object.create(b);
//生成的原型链:c --> b --> a --> Object.prototype --> null
console.log(c.name);
var d = Object.create(null);
//生成的原型链:d --> null
//constructor:每个原型对象都有constructor属性,这个属性指向的是该原型对象所在的构造函数
console.log(Person.prototype.constructor);
console.log(person1.constructor);
//hasOwnProperty(): 判断一个对象是否有某个属性,返回值是一个布尔值
console.log(Person.prototype.hasOwnProperty("constructor"));
console.log(person1.hasOwnProperty("constructor")); //是false ,证明这个constructor不是person1的,是继承来的
总结:当调用某个对象的属性或方法的时候,首先去查找该对象自身是否有这个属性和方法,如果没有的话,就沿着原型链去往上找,如果找到了就可以直接使用,如果没找到,就继续找,以此类推,直到找到null为止。
Object.getPrototypeOf(): 返回一个对象的原型对象
console.log(Object.getPrototypeOf(person1));
isPrototypeOf(): 判断一个对象是否是另外一个对象的原型对象
console.log(b.isPrototypeOf(c)); //b是c的原型对象所以是true
Map认识
//Map的认识和使用
//是一种映射结构,JS里的Map相当于JS里的字面量对象,其结构基本一样。map里就是一种"键值对"的关系集合。
//Map相当于java中的HashMap、OC中的字典、python中的字典等
var map=new Map();
//map的添加方法
// 要添加的是一对键值对(也可以理解为是属性和值,值可以是任何JS类型)
console.log(map);
map.set("name","晓雪");
map.set("age",18);
console.log(map);
// 删除的方法
// map.delete("age");
console.log(map);
//通过某个键(key或者叫做属性)获得该键对应的值
console.log(map.get("name") );
//判断map中是否有某个键
console.log(map.has("age"));
//修改方法和增加方法是同一个方法【map有个特性那就是键,或者叫key、属性是不能重复的,所以调用set方法的时候,如果这个属性不存在则是添加操作,存在则是修改操作】
console.log(map.set("name","晓雪她妈") );
//map的长度
console.log(map.size);
各种遍历的整理
//声明一系列数据结构
//构造函数
function Person(name){
this.name=name;
}
//数组
var arr = [new Person("有鬼"),new Person("白牛"),new Person("撼地神牛")];
//字面量对象
var dog = {
"name" : "幻影长矛手",
"type" : "盖伦"
}
//Map :Map是无序不重复的
var map= new Map();
map.set("name","虚空假面");
map.set("sex","男");
/***************************普通的for循环遍历*********************************/
// 遍历数组 最普通的:用for循环
for(var i=0;i<arr.length;i++){
console.log(arr[i].name);
}
/***********************for****in 循环遍历*************************/
// 遍历数组用for in遍历数组性能不好,容易造成下标错乱
// 左边变量表示数组的下标,
// 右边变量表示要遍历的数组
for( var tempIdx in arr){
console.log(arr[tempIdx].name);
}
遍历对象:for……in非常适合去遍历字面量对象
//左边变量:是这个对象的属性
//右边的变量:要遍历的对象
for(var tempProp in dog){
// 注意:当属性为变量的时候,要用方括号语法去访问!!
// console.log(dog.tempProp);
console.log(dog[tempProp]+"我是什么?");
}
/*************************forEach()******************************/
// 如果遍历数组,这个方法其实是Array.prototype.forEach 也就是数组原型的方法
// forEach的参数是一个匿名回调函数;这个匿名函数的参数1.数组的每个元素,2.数组的下标,3.当前数组对象
console.log("=========================三个参数写几个都行================================");
//注意foreach遍历 不能break 、continue 和return;
arr.forEach(function (ele,idx) {
console.log(ele.name);
});
// 遍历map
// 如果遍历map、这个方法其实是Map.prototype.forEach
// forEach的参数是一个匿名回调函数;这个匿名函数的参数1.value值 2.key 键 3.当前map对象
console.log("======================三个参数写几个都行=======================");
map.forEach(function(value,key,map){
console.log(key+":"+value);
})
/*****************for....of遍历*********************/
//遍历数组
//第一个变量:数组中的每一个元素
//第二个参数:要遍历的数组对象
for(var tempEle of arr){
console.log(tempEle.name);
}
//遍历map
//第一个参数: 是一个数组,数组中有两个元素[key ,value]
//第二个参数:要遍历的map对象
console.log("==============遍历map=============");
for ( var [key,value] of map ){
console.log(key+"*******"+value);
}
// 或者:
for ( var temp of map ){
console.log(temp[0]+"*******"+temp[1]);
}
另外还有jQuery的两种遍历方法
//$.each():遍历 和$("").each()差不多 后者是jQuery对象调用
$("").each() :只能遍历jQuery对象,参数是一个匿名函数,匿名函数的参数分别是下标和元素
$.each() : 无论什么对象(DOM/jQuery)都能遍历,如果遍历的是一个数组,那么匿名函数中的参数分别是下标和元素,如果遍历的是一个字面量对象,那么匿名函数中的参数分别是属性和值 【数组和对象,map遍历不了】a
举例说明:
var arr = ["fai","ye","得","吼"];
$.each(arr,function(idx,ele){
console.log(idx+"======"+ele);
})
//遍历对象
var obj = {
name : "负心串",
age : 18
}
$.each(obj,function(propaa,valueaa){
console.log(propaa+"======="+valueaa);
});
var person = {
name : "陈老师",
friends : [
{
name : "张女士"
},
{
name : "敏儿"
},
{
name : "小谢"
}
],
grilFriend : {
name : "网红之一"
}
}
$.each(person,function(prop,value){
if(prop=="friends"){
//此时的value就是数组
$.each(value,function(idx,ele){
console.log(ele.name);
});
}
})
This的使用总结
/*
在javascript中,函数都运行在某个运行环境中,运行环境也可以理解为是一个对象,函数内部的this指针会跟据当前的运行环境改变而改变
*/
/*****全局环境******/
console.log(this); //window
/*******构造函数中*******/
function Person(name){
// this代表当前构造函数创建出来的对象
this.name=name;
}
console.log(new Person("迈克尔").name); //迈克尔
/*******在某个函数中*******/
function fn(){
console.log(this.name);
}
var obj1 = {
name:"可儿",
objFn1:fn
}
var obj2 = {
name:"菲儿",
objFn2:fn
}
obj1.objFn1(); //可儿
obj2.objFn2(); //菲儿
/*******在dom元素中**********/
<input type="button" value="这是一个牛逼按钮" onclick="btnClick(this);" />
<input type="button" value="这是另外一个牛逼按钮" onclick="btnClick(this);" /
function btnClick(ele){
// ele就是点击按钮后传过来的指针,这个this就表示当前点击的按钮元素
alert(ele.value);
}
/**********在字面量对象中************/
var a ={
age:19,
aFn:function(){
console.log( this.age );
}
}
var b = {
age:18,
// bFn:a.aFn; 这样写this就会指向b,所以age是18
bFn: function(){
a.aFn(); //这样写this还是运行在a对象里,所以age是19
}
}
b.bFn(); //19
/**************有的时候,一个对象的层次结构很深,我们想取出内部的某个函数,我们不要直接提取,而是要提取这个函数所在的对象***************/
var c = {
d : {
sex : "男",
sayFn : function(){
console.log(this.sex);
}
}
}
//我把c.d.sayFn拿出来但是没调用(运行),付给了testFn,this指针就变成了全局的环境,全局没有sex 所以是undefined
var testFn=c.d.sayFn;
testFn(); //undefined
var testObj = c.d; //这样就提取到男了,也就是说要提取函数所在的对象
testObj.sayFn();
</script>
固定this指针
//因为this指针的指向是根据运行环境而决定的,有的时候我们需要在特定的环境下去运行,这里用到了call方法和apply方法就可以使用
var name="碧波";
var obj = {
name: "乔丹"
}
function fn(){
console.log(this.name);
}
fn(); //this指向window name是碧波
fn.call(obj);// 让fn函数的运行环境变成在obj内运行 name是乔丹
function fn2(a,b){
console.log(a+b);
}
fn2.call(this,3,8)//fn2.call(this)与fn2();一个样
fn2(3,8);
apply方法和call实现的功能一模一样,只不过如果带参数的话,apply接受的是一个数组而已。
fn2.apply(this,[5,8]);
作用域
/*******************局部作用域******************************/
function fn2(){
var parentName="局部作用域";
console.log("局部作用域:"+parentName);
}
fn2();
// try.....catch语句:运行在try...catch中的代码,如果出错了的话,不会像之前那样程序崩掉,后面的代码无法执行,而是会捕获到这个错误或者异常。
// console.log(parentName);这是个局部变量,会报错
try{
console.log(parentName);
}catch(execption){
//如果出现异常,catch会捕捉到,并且打印异常信息
console.log(execption.toString());
}
//注意,javascript当中没有块级作用域的概念,只有函数作用域的概念
function fn3(){
for(var i=0;i<4;i++){
}
console.log(i); //没有块级作用域可以访问到,那个for循环就是块级
}
fn3();
//注意:javascript当中,如果没有用var声明的变量,则是全局变量
function fn4(){
testname="猜猜我是全局的还是局部的";
}
fn4(); //必须运行一次函数才会生成,才能在外面调用到
作用域链
/*作用域链和原型链非常相似,就是说当你访问某个变量的时候,首先去作用域链的最低端去找,如果找不到,则去找它的父级作用域,以此类推,直到找到全局作用域位置*/
var name="陈奕迅";
function fn(){
var name="耿耿";
function subfn(){
var name="卢星宇";
console.log(name);
}
function subFn2 (){
console.log(name);
}
subfn(); //卢星宇
//其原理:当调用subfn函数的时候,会把subfn所在的执行环境放到作用域链的最低端,然后再把fn函数放到它的上面,最后再放入全局作用域 subfn()----------->fn()----------->window
subFn2();
}
fn();
JSON
JSON(javascript Object Notation);是一种轻量级数据交换格式。
JSON是javascript的一个子集。JSON不是JS独有的,其他语言也用它,但是它是JS演变出来的。
JSON的语法基本就和javascript字面量语法一模一样,无非就是一个字符串,但其内部的格式完全和javascript字面量一样
序列化:把javascript对象转换成JSON格式字符串的操作叫做序列化(为了给服务器传输数据用)
JSON.stringify();
反序列化:把JSON格式字符串转换成javascript对象的操作叫做反序列化(一般从服务器获取JSON格式数据后,需要进行反序列化操作)
JSON.parse();
AJAX
【客户端和服务器交互模型】
客户端和服务器(C/S)架构,是最基本的互联网通信架构。
客户端包括:桌面应用(C/S)、浏览器应用(B/S)、移动应用等。
服务器包括:web服务器、数据库服务器等。
推送:服务器主动给客户端发送数据
拉取:向服务器发送请求获取数据
客户端和服务器各自擅长做的:
在用户输入表单的时候:客户端一般做数据格式的校验,而服务器一般做数据的业务逻辑处理。
【HTTP协议】
HTTP协议是超文本传输协议。该协议规定了客户端和服务器传输交互的约定(协议),(推荐一本书:TCP/IP详解),
通过这个协议才可以让客户端和服务器正确的传输(交互)。
HTTP协议通信的两大步骤:
1:请求:客户端向服务器索取数据。
2:响应:请求后,服务器端反馈给客户端的数据或状态。
【GET请求和POST请求】
GET请求:明文请求,如果请求有参数,会在链接(URL)的后面以问好“?”拼接,例如:http://10.192.0.1:8080?username=suming&password=123456
如果是多个参数,参数中间用“&”符号拼接,这种请求方式会把信息暴露在用户面前。
POST请求:密文请求,请求参数会放在请求体中。这种请求不会把信息暴露在用户面前。
GET请求和POST请求的选择情况:
1.如果请求的数据量特别大或者需要有上传功能的话必须使用POST请求。
2.get请求相对于post请求来说,安全性略差,如果要请求的数据具有严重的隐私性的话,建议使用POST请求。
3.如果仅仅是数据查询的操作建议使用get请求
4.如果是其它操作,建议使用POST请求。
【同步和异步】
同步:相当于请求一次过后,要等到这次请求的响应后,才能继续下一次请求。(很少用,用户体验差)
异步:请求一次后,不需要等到这次请求的响应后,就可以进行其它请求。
【Ajax】
Ajax异步的javascript和XML,也就是说,Ajax就是通过javascript语言,去异步请求之后,得到响应,局部刷新代码
两个特点:异步请求、局部刷新。
【ajax的原生开发流程】
1.创建请求对象(异步)
创建核心的XMLHttpRequest请求对象,Ajax编程都是通过这个对象来进行的
注意:浏览器对XMLHttpRequest对象的支持有所不同。
1)大部分主流浏览器都支持XMLHttpRequest对象
var xhr=new XMLHttpRequest(); //造了一个请求对象
2)IE6 var xhr = new ActiveXObject("Msxml2.XMLHTTP");
3)IE6以下的 var xhr = new ActiveXObject("Microsoft.XMLHTTP");
2.打开与服务器的链接
创建完请求对象后,通过请求对象的open()方法,这个方法可以与服务器建立链接。
open(method,url,flag);
三个参数: 1:表示用什么请求方式。GET、POST等。
2:要请求服务器的路径,如果用的是get请求,如果有参数的话,要拼接在URL的后面
3:表示是否是异步请求,默认是异步的,不用写就可以
var xhr = new XMLHttpRequest();
xhr.open("GET","http://10.xxx.xx.xxx:8080/?name=su&pwd=123456",true);
3.发送请求:
与服务器建立链接后,在利用请求对象的send()方法去发送请求
如果用的是GET请求,send方法内的参数写null就行,如果是post请求,请求有参数的话,请求参数要写在send方法内
var xhr = new XMLHttpRequest();
xhr.open("GET","http://10.0.0.1:8080/",true);
xhr.send(null);
//注意:如果是POST请求,那么在调用send方法之前,要设置请求头。
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
4.接收服务器响应:
当请求对象调用完send方法后,就可以等待服务器的响应,请求对象会根据响应的不同状态触发一个onreadystatechange事件。
请求对象的几种状态码:
0:未初始化完成,只是创建了XMLHttpRequest对象,还未调用open方法
1:初始化完成,请求开始,开始调用open方法,但没调用send方法
2:请求发送,就是说已经调用了send方法。
3:开始接收服务器的响应。
4:读取接收服务器响应后返回的数据。(响应彻底结束)
当状态码发生改变的时候,会触发onreadystatechange事件,共触发5次
可以利用请求对象的readyState属性来查看当前的状态码。
真正开发的时候我们只关心状态码为4的时候。
【服务器响应的状态码】
200:响应正常(这就是我们最后想要的状态码)
404:找不到要访问的URL
500:服务器方面的错误。
我们可以利用请求对象的status属性来查看服务器状态码
最后我们要写类似于
var xhr=new XMLHttpRequest();
xhr.open("GET","",true);
xhr.send(null);
xhr.onreadystatechange = function (){
if(xhr.readyState == 4 && xhr.status == 200){
//这里是我们想要的返回的JSON串
xhr.responseText;(再把这个反序列化)
}
}
转换为正规的JS代码:
//1.创建请求对象
var xhr;
if(window.XMLHttpRequest){
xhr=new XMLHttpRequest();
}else if(window.ActiveXObject){
//IE6
var versions = ["Msxml2.XMLHTTP","Microsoft.XMLHTTP"];
for(var tempVersion of versions){
xhr = new ActiveXObject(tempVersion);
if(xhr!=undefined){
//如果满足第一个就不是undefined了。直接退出循环就OK
break;
}
}
}else{
throw new Error("该浏览器不支持ajax!");
}
//2.建立链接
xhr.open("GET","car.json",true);
//3.发送请求
xhr.send(null);//给个null是为了兼容火狐
//4.接收响应
xhr.onreadystatechange = function(){
//当状态码为2、3、4的时候触发
if(xhr.readyState==4 && xhr.status==200){
//反序列化,转换成JS字面量对象
var rootObj=JSON.parse(xhr.responseText)
}
混合继承
//混合继承:利用类世继承和原型链继承一起来实现继承
function Person(name){
this.name = name;
}
Person.prototype.say = function(){
console.log("名字:"+this.name);
}
function Student(name,age){
Person.call(this,name); //这里学生类继承了父类本身的属性,这里也就是name但是它继承不了方法;
this.age = age;
}
Student.prototype = new Person(); //这里继承了父类的say方法
Student.prototype.say = function(){
console.log("孩子自己的:"+this.name+"--"+this.age); //又把say方法重写了
}
var student1=new Student("小红",18);
var student2=new Student("小李",19);
student1.say();
student2.say();
jQuery
【库】
1.所谓库就是利用javaScript原生语言编写的一套使用方便以及功能强大的一些JS文件
2.使用库的好处:使用库可以简化代码,不用再去写重复的代码,而且不用去考虑那些所谓的兼容问题。
【jQuery库】
jQuery是目前为止前端程序猿使用最多的一个库,而且是前端程序猿必须学的一个库,它能解决浏览器的不兼容问题,提供了相同的访问接口,程序猿不用再关心这些非计算、非业务无关的问题了。
jQuery的特点:压缩后仅有几十Kb,非常小巧。可以通过链式语法进行调用。可以通过CSS选择器进行DOM操作。支持插件开发,可拓展性强。
jQuery可以获取文档元素,并且对其进行操作(包括增删改查,修改样式等),可以响应用户的交互。可以简化常用的javascript逻辑
jQuery的版本:
大概分为三个版本,1.X版本 2.x版本 3.x版本 ;1.x版本相对于2.x版本来说支持IE6、7、8 2.x版本支持IE9及以上,根据需求决定使用哪个版本。可以去jQuery的官网请下载
3.x版本正式版刚发布不久(最好使用2.x);
导入JQuery
【基础选择器】
>表示选中指定的元素唯一的一级子代元素;
+表示选中指定元素其后紧邻的唯一一个元素;
~表示选中指定元素其余所有的元素;
【过滤选择器】
在jQuery中所有的过滤选择器都以冒号开头
:not()在指定的元素当中排除某一个元素或某一类元素
:eq()按照指定的索引值进行过滤,(索引值从零开始)
:gt()过滤大于指定索引值的所有元素
: lt ()过滤小于指定索引值的所有元素;【无论大于还是小于都不包含自己本身】
【筛选选择器】
这其中有3个巨头选择器,父子兄;
特点:所有的筛选选择器都是一个函数的形式,所以他不会写在选择符号的内部
$(this).children(‘.class’).css(‘background’,’red’)
修改css
单属性修改.css(‘background’,’red’)
多属性修改.css({background:’red’ ,width:’30px’})
当是复合属性修改时比方说background-color:’red’是不可以的应该是:backgroundColor:’red’【驼峰式命名法】
- ID选择器 $(“#idName”)
- //注意:作为jQuery对象一定要使用jQuery相关的属性和方法,不能去操作JS原生的属性和方法 $(“#idName”).innerHTML是错误的,用.html();
JQuery对象和 js DOM对象相互转换
console.log($p1);
通过打印可发现 通过构造函数创建获得的jQuery对象都是一个数组,我们获得数组的第一个元素(就获得了dom对象-js原生);
var dom_p1 = $p1.get(0); //转换为普通的DOM对象
console.log(dom_p1.innerHTML);
js DOM对象转换成jQuery对象
var $p2 = $(dom_p1); dom_p1原本是个DOM对象,我用$符号括起来就成了JQ对象
- 类选择器var $p4 = $(".my_class");
- 属性选择器var $p5 = $("[name = span_name]");
- 属性过滤,获得属性前缀相关:获得class属性值的前缀为my_的所有元素
var $p6 = $("[class ^=开头]");
- 获得class属性值后缀为_class的所有元素var $p7 = $("[class $=class结尾]");
- 组合选择器 获得所有input标签中name属性为span_name的标签
$p8 = $("input[name = span_name]");
多项选择器: 可以获得多个不同的元素 例如$("div,p") 获得所有的div和p元素
层级选择器:因为JS DOM的结构是有层级关系的,单纯的通过基本的选择器是无法满足我们的查找需求,这时候我们就需要用到层级选择器,层级选择器其实就是说祖先与后代的关系
子选择器: 层级选择器包含子选择器,只不过子选择器是描述父与子的关系
过滤选择器: 过滤选择器一般不单独使用,通过和其它选择器配合使用,能更精确的查找某些元素
层级选择器
// 获得所有的div和li
var $many_1 = $("div,li");
//获得所有div下的javascript语言所在的层级元素
var $js_1 = $("div li.lang_javascript");
// 子选择器:
//获得所有ul下的javascript语言所在的层级元素
$js_5 = $("ul>li.lang_javascript");
console.log($js_5.length);
//获得所有类名叫做lang的ul下 的javascript语言所在的li
$js_6 = $("ul.lang>li.lang_javascript");
console.log($js_6.length);
// 过滤选择器:
//获得类名为lang的ul元素下的第一个li元素
var filter_1 = $("ul.lang li:first");
console.log(filter_1.html());
//获得类名为lang的ul元素下的最后一个li元素
var filter_2 = $("ul.lang li:last");
console.log(filter_2.html());
//获得类名为lang的ul元素下的某一个li元素 从0开始
var filter_3 = $("ul.lang li:eq(1)");
console.log(filter_3.html());
// 获得类名为lang的ul元素下的所有偶数li元素
var filter_4 = $("ul.lang li:even");
console.log(filter_4[0].innerHTML+"====="+filter_4[1].innerHTML);
// 获得类名为lang的ul元素下的所有奇数li元素
var filter_5 = $("ul.lang li:odd");
console.log(filter_5[0].innerHTML+"====="+filter_5[1].innerHTML);
// 获得类名为lang的ul元素下的所有下标小于2的li元素
var filter_6 = $("ul.lang li:lt(2)");
console.log(filter_6[0].innerHTML+"====="+filter_6[1].innerHTML);
// 获得类名为lang的ul元素下的所有下标大于2的li元素
var filter_7 = $("ul.lang li:gt(2)");
console.log(filter_7.html());
// 获得所有隐藏的div
var filter_8 = $("div:hidden");
console.log(filter_8.html());
// 获得所有可见的div
var filter_9 = $("div:visible");
console.log(filter_9.html());
// 获得类名为lang的元素下的除了类名为lang_javascript的所有li元素
var filter_10 = $("ul.lang li:not(.lang_javascript)");
var filter_11 = $("ul.lang li:not([class = lang_javascript])");
console.log(filter_11.length);
//获得类名为lang 的ul下的包含文本为java的li元素
// 注意 此内容查找 是模糊查找,只要包含某段内容的就会找出来
var filter_12 = $("ul.lang li:contains(‘java‘)"); //javascript和java都符合
console.log(filter_12.html());
console.log(filter_12.length);
//获得所有子元素为空或文本为空的元素
var filter_13 = $(":empty");
console.log(filter_13);
// 获得所有div为空的或者所有p为空的元素(多项选择)
var filter_14 = $("div:empty,p:empty");
console.log(filter_14.length);
// 获得所有包含li元素的div元素
var filter_15 = $("div:has(‘li‘)");
console.log(filter_15.length);
// 获得所有ul下的第一个li元素
// 注意::first :last :eq等是获取唯一的一个元素,而不是多个
var filter_16 = $("ul li:first"); //一个
console.log(filter_16.length);
// first-child是为每个父元素匹配下面的第一个子元素 同理last-child
var filter_17 = $("ul li:first-child"); //两个
console.log(filter_17.length);
//获得所有ul下的某一个li元素 nth-child(2)是从1开始算的,eq是从0开始算的
var filter_18 = $("ul li:nth-child(2)");0
console.log(filter_18[0].innerHTML+"===="+filter_18[1].innerHTML);
// 获取仅有一个li子元素的ul
var filter_19 = $("ul li:only-child");
console.log(filter_19.html());
表单选择器
表单选择器:专门用来获取表单相关的选择器
// 获取所有input元素
var f1 = $(":input");
/获取表单里所有text
var f2 = $(":text");
var f3 = $(":password");
//获取表单里所有的radio事件
var f4 = $(":radio");
$("[type=button]").get(0).onclick = function(){
// console.log(this.value);
// 获取所有被checked选中的元素
//注意:包括radio、checkbox以及select都适用
var f5= $(":checked");
console.log(f5.length);
// 获取所有checkbox被checked的元素
var f6= $(":checkbox:checked") ;或者
var f7 = $("[type = checkbox]:checked");
console.log(f6.length);
console.log(f7.length);
//专门给select标签使用
var f8 = $(":selected");
console.log(f8.length);
// 获得所有表单禁用的元素
var f9 = $(":disabled");
console.log(f9.val());
}
查找和过滤选择器
查找和过滤:对结果集再进一步的查找或过滤
注意:和之前的:first/:last/:eq/一样,获取的是一个元素
first():查找结果集里的第一个
last():查找结果集里的最后一个
eq():查找结果集里的某一个 从0开始算
var f1 = $("ul.lang li").first();
next();获取下一个元素(描述的是兄弟关系)
prev();获取上一个元素(…………………………)
// 获取ul下的第三个li的下一个元素
var f4 = $("ul li").eq(2).next();
获取ul下的最后一个元素的上一个元素的上一个元素
var f6 = $("ul li").last().prev().prev();
描述的是 祖先和晚辈,父与子的关系
parent(): 获取父元素
parents():获取祖先们 所得到的第一个是相邻的
children():获取孩子们
// 获取第一个li的父亲
var f7 = $("ul li").first().parent();
// 获取第一个li的祖先们
var f8 = $("ul li").first().parents();
获取第一个li的祖先们中的div元素
var f9 = $("ul li").first().parents("div");
// 获取ul下的所有孩子
var f10 = $("ul").children();
// 获取class为ruby的孩子
var f11 = $("ul").children("[class=lang_ruby]");
console.log(f11.length);
console.log(f11.html());
以下描述的都是同级关系
siblings();获得当前元素的所有邻居元素 先获取出所有的来再从头开始计算
nextAll();获取当前元素的后面所有元素 第一个元素是最靠近调用的那个元素
prevAll();获取当前元素的前面所有元素 第一个元素是最靠近调用的那个元素
find():按照条件查找某些子元素 找它下面的子元素
filter(): 通过结果集,按照条件过滤 找结果集里面的
not(): 通过结果集,利用not去排除
var f18 = $("ul").find("[class=lang_java]");
var f19 = $("ul li").filter("[class = lang_java]");
var f20 = $("ul li").not("[class = lang_php]");
is();判断某个结果集里面是否有某个元素,返回值是true或false
var f21 = $("ul li").is("li");
hasClass();判断某个结果集里面是否有某个类,返回值是true或false
var f22 = $("ul li").first().hasClass("lang_js");
操作属性相关
//html和text的用法区别
console.log(li2.html()); //保持原始数据不变
console.log(li2.text()); //对立面特殊html标签转译 比方说&会变成&
// 设置值 正好和获得值反过来,html能转译了,而text写什么是什么
$(".div_1").html("<span style =‘color:red;‘>这是通过htm()设置的span元素</span>");
//结果是变红后的:这是通过htm()设置的span元素
$(".div_1 span").text("我盟出来么"); 有span标签的话,会把它当字符串
addClass();给元素添加类样式
$("#p_1").addClass("class_p");
removeClass(): 给元素移除样式
$("#p_1").removeClass("class_p");
toggleClass():从添加和移除样式之间进行切换
$("#p_1").toggleClass("class_p");
css():给元素设置样式或获取样式
$(".lang_js").css("color","red");
//获取
console.log($(".lang_js").css("color"));
//多个样式的设置
$(".lang_js").css({
"font-size" : "50px",
color : "green"
});
// 或者链式语法
$(".lang_js").css("font-size","12px").css("color","blue");
<input type="button" value="val" onclick="fn6(this);">
function fn6(ele){
//val()方法获得value值和设置value值,需要先转换成jQuery对象
$(ele).val("改变自己");
console.log($(ele).val());
}
FIS3使用
1。cmd模式下在当前程序在的那个目录下: fis3 server start
2. fis3 server open
3.fis3 release -cwL (后面是表示发布同时监听)
[-c, clean 清除编译缓存]
[-w、watch 启动文件监听]
【会启动文件监听功能,当文件变化时会编译发布变化了的文件以及依赖它的文件。加了此参数,命令不会马上退出,而是常驻且监听文件变化,并按需再次执行。想停止命令需要使用快捷键 CTRL+c 来强制停止。】
[-L、live 启动 livereload 功能]
fis3 release -d ./output 发布到当前目录下的output目录下[发布到指定的路径下]
这样修改html文件及其依赖文件,启动open时得到的网页地址效果会自动改变
达到压缩源代码的效果(类似百度)
在根目录,也就是index.html目录下,新建 一个js文件 fis-conf.js 此js文件其内部
内容为:
//用来压缩html文件的
fis.match(‘*.html‘, {
//invoke fis-optimizer-html-minifier
optimizer: fis.plugin(‘html-minifier‘)
});
// 用来压缩js文件的
fis.match(‘*.js‘, {
useHash: false, // default is true
// 指定压缩插件 fis-optimizer-uglify-js
optimizer: fis.plugin(‘uglify-js‘, {
// option of uglify-js
})
});
//用来压缩css文件的
fis.match(‘*.css‘, {
useHash: false, //default is `true`
// compress css invoke fis-optimizer-clean-css
optimizer: fis.plugin(‘clean-css‘, {
// option of clean-css
})
});
此时重新启动监听,,ctrl+c退出
启动时可能报这个错误。。需要继续安装插件
npm install -g 错误中,中括号里面其中一个
Node.js使用
在这个服务器里面有个js文件随便叫什么名字里面的内容:
var express = require(‘express‘);
var app = express();
// 可以配置路径(苏明)
var url = "/shop_list";
app.get(url, function (req, res) {
var obj = {
name : "滚蛋"
}
console.log(req.query.page); //得到请求数据的参数
var obj2 = {
"page_count": 2411,
"errno": 0,
"errmsg": ""
}
// 判断请求参数中是否有page这个参数
// res.json(obj2);
// 返回jsonp格式
res.jsonp(obj2);
});
app.listen(4200); //监听的端口号
//这个时候我想得到数据访问的链接就是 http://10.0.0.1:4200/shop_list就能得到数据
// 我想访问这些json数据的项目里面的js请求时写
// $(function(){
// // 展示商铺列表数据
// $.getJSON("http://127.0.0.1:4100/shop_list?callback=?page1",null,function(data){
// console.log(data);
// })
// });
关于jsonp比较好的文章:http://kb.cnblogs.com/page/139725/
git新浪云使用
进入想要创建git的目录,执行:
git init 【这个命令是设置当前目录为git的仓库这个目录此时就是本地一个暂存区 】
git remote add sunshine 仓库地址 【创建一个git远程仓库,可以通过git remote查看仓库有哪些】
git add 文件或者文件夹 【将文件选中放入暂存区】
git commit -m “有意义的说明” 【 这里已经提交到本地仓库了,在.git中有一个暂存区一个本地仓库】
git push sunshine master:1 【部署到云服务器的版本1中】
想删除就是 git push sunshine :1
Git diff 查看工作区和暂存区区别
git diff HEAD~n 工作区和本地仓库区别
http://www.cnblogs.com/zhongxinWang/p/4205339.html
红色,有改动,未添加进仓库, 红变绿,添加了未提交远程仓库
git 版本控制工具
master 线上分支------发布代码
dev 开发分支
qa 测试分支
git代码存在的环境: 线上 本地版本库 内存
git pull origin dev //拉取代码到本地仓库(先把别人做的弄下来)
把自己做的东西加到弄下来的代码里面去
git status 查看
git add www/index.html
git commit -am "开发默认页面"
git push origin dev//推送代码到线上
git checkout qa //切换分支
git merge dev //到qa之后把dev代码合并到qa分支上
WEB安全
学名:XSS 跨站脚本攻击 代码注入
解决方案:
1.转译。比方说检测到< 括号替换成<,>替换成>,或者直接用模板引擎,比分baidu.template,就会自动过滤掉。
2.进行过滤
CSRF 跨站伪造请求
这方面需要后台提供一个token(随机码), 一个唯一标识,会随时变的,前端会得到这个token提交的时候会拿这个实时的码与后台的token做对比,相同才能发送请求,否则屏蔽掉
性能优化之图片懒加载
1给图片设置宽高,让图片占位
2不直接显示图片,先把图片链接存起来,比方说放到img标签的data-src=””里面
3,判断当前屏幕的位置,将当前屏幕内的图片展示出来,也就是将存起来的图片(data-src),放到src内
代码开始
Var imgs = document.querySelectorAll(‘img’); 所有的图片
当前屏幕的高度 var h = window.innerHeight;
Document.onscroll = thatop; 滚动条事件,触发函数加载当前屏幕的图片
Function thatop(){
获取滚动条的位置(当前屏幕的位置)后面方法是获取IE浏览器当前屏幕的位置
Var t=document.documentElement.scrollTop ||document.body.scrollTop;
当前屏幕的高度+滚动条的位置(最顶部)= 当前屏幕的位置(可视区域)t+h;
Var num = t+h;
For(var i=0; i<imgs.length;i++){
If(imgs[i].offsetTop <=num){
Imgs[i].src = imgs[i].getAttribute(‘data-src’);
}
}
}
当检测到图片距离最顶端的距离,小于当前屏幕的高度与滚动条卷上去的高度加和,就说明它被滑动上来了.那么把提前请求下来的路径地址给src属性(属性的获取),便可以展示
通过以上分析需要满足以下几点:
1.给图片设置宽高,让图片占位
2.不直接显示图片,先把后台请求到的图片链接存起来,比方说放到 img标签的data-src=””里面
3,判断当前屏幕的位置,将当前屏幕内的图片展示出来,也就是将 存起来的图片(data-src),放到src内
Ⅱ.伪代码:
下图为临时qq截图画的一张表,有点儿丑哈
简单说明下:
包裹绿色图片的外层红框为手机屏幕,红框里面的就是当前看到 的,红框上面的就是滚动条往下滑动遮挡的,红框下面的就是 用户还没来得及看的.
绿色框为图片列表(比方说天猫商城上的商品)
右侧紫色的为滚动条
那么以基础知识来转化成伪代码,语言叙述中加粗的是知识点:
1.当前屏幕(高度): window.innerHeight;
2.滚动条卷上去的部分:document.documentElement.scrollTop(要考虑兼容性)
3.图片距离最顶端的距离:offsetTop
4.实时监听:scroll事件
5.属性获取:getAttribute
Ⅲ.代码产出物:
//所有的图片
Var imgs = document.querySelectorAll(‘img’);
//当前屏幕的高度
var currentViewHeight = window.innerHeight;
//滚动条事件,触发函数加载当前屏幕的图片
Document.onscroll = thatop;
Function thatop(){
//获取滚动条卷上去高度,后面方法是获取IE浏览器当前屏幕的位置
Var hiddenHeight=document.documentElement.scrollTop ||document.body.scrollTop;
当前屏幕最低端到隐藏区域最顶部的距离= 当前屏幕的高度(可视区域)+隐藏的
Var totalHeight = currentViewHeight +hiddenHeight;
For(var i=0; i<imgs.length;i++){
If(imgs[i].offsetTop <=totalHeight ){
Imgs[i].src = imgs[i].getAttribute(‘data-src’);
}
}
}
原文地址:https://www.cnblogs.com/chenhongshuang/p/8610570.html