H5新标签/网页元素/属性/选择器
1.结构标签
header 一个区域的头部
nav 导航的链接组
section 页面的内容区块 通常有 内容 和 标题 组成
article 一个独立的内容区块
aside 非正文的内容(侧边栏什么的),与页面的主要内容是分开的
footer 一个页面的尾部
2.以上都是块元素哦
3.能让搜索引擎爬虫快速抓住这些语义化的标签
2.HTML5新增网页元素
标签:
datalist 定义可以选数据的列表
time 定义时间和日期
mark 标记
progress 进度条
video 定义视频
audio 定义音频
canvas 定义图像
1.datalist
<input type="text" list="iWant"> <!-- list属性和 datalist的标签的id 一样即可 -->
<datalist id="iWant">
<option value="火锅"></option>
<option value="奶茶"></option>
<option value="奶油蛋糕"></option>
</datalist>
2.time/mark/progress
<time>现在是12:00</time> <!--没什么区别 语义化标签 给爬虫看的 有利于SEO优化-->
<mark>这里是mark标签</mark>
<progress></progress>
<progress value="50" max="100"></progress>
3.新增全局属性
(所有的标签都可以具有的属性)
contentEditable 规定是否允许用户编辑内容
designMode 全局都可编辑 document.designMode='on'
hidden 隐藏
spellcheck 拼写检查
tabindex 按tab键让光标定位在哪里
1.contenteditable
<p contenteditable="true">这里是contentEditable</p>
2. designMode
<p>全局都可被编辑designMode</p>
<!-- <script>
document.designMode='on'
</script> -->
3.hidden
<p hidden="hidden">看不见我嘻嘻嘻</p>
4.tabindex=? (?就是获取光标的顺序)
<p>tabindex</p> 按tab 光标定位到哪里
<a href="" tabindex="2">2222</a>
<a href="" tabindex="3">3333</a>
<a href="" tabindex="1">2222</a>
4.css3的高级选择器
first-of-type 第一个这种类型的孩子 div P:first-of-type div下面的只要是p的 的第一个P
last-of-type 最后一个这种类型的孩子
first-child 第一个子元素
last-child 最后一个子元素
nth-child(n) 第几个 里面可带odd even
:before P:before 在p的前面 插入内容
:after
4.1 伪类其他的用法-3
1.
h1::before{
content:attr(name);/*content 必须要有 为空都行*/
background: blue;
font-size: 55px;
}
<h1 name="(伪类的对应用法)我是">付艺佳</h1>
2.在元素的后面加一个线 点什么的 ,就不用span标签了,减少的dom元素
h1::after{
content: "";/*content 必须要有 为空都行*/
display: inline-block;
width: 20px;
height: 20px;
border-radius: 50%;
background: blue;
margin-left: 10px;
}
3.清浮动
.clearfix::after{/*然后把这个clearfix这个类给 塌陷的父级*/
content: "";
display: block;
clear: both;
}
4.2 css3新增其他伪类
1 伪对象选择符
::after 与 :: before
::first-letter 匹配选择器元素段落内容的 第一个 字符
::first-line 匹配选择器元素段落内容的 第一行 字符
::placeholder 匹配文本框中占位符内容input 里面 的placeholder
::selection 匹配网页中选中的文本内容
2 CSS2(3)新增的伪类对象选择器:
a:hover , a:link , a:active , a:visited
:not(选择器1) 对匹配元素过滤取非选择器1所匹配元素
.box :not(p){ color: red; }
:root 永远匹配html根元素
:first-child / :last-child / nth-child(n) / only-child
:first-of-type / :last-of-type
:empty 匹配内容为空的元素(空格也算内容)
.box:empty{
width: 200px;
height: 200px;
background: red;}
:checked 匹配单选框和复选框被选中状态
/* 给单选框和多选框设置选中状态样式 */
input:checked{
width: 200px;
height: 200px;}
:enabled / :disabled 匹配可用和不可用表单元素
button:enabled{
background-color: green;
}
button:disabled{
background-color: indigo;
}
:target 匹配当前锚链接指向元素
例子:不带js的选项卡
2. H5表单
1.新增的表单元素 type=" "
email 自动验证输入邮箱的是否符合规则
url 自动验证网址的是否符合规则
number 只能输入数字 可有max min step(每次递增递减几个) 属性值
range 滑动条 ~
search 搜索
Date pickers 拥有可供选取日期的新输入类型
name=" "
date 选择年月日
month 选择年月
week 选择年周
time 选择时间
datetime UTC时间(废弃了
datetime-local 选择本地时间
<form action="#" method="GET">
<div>邮箱: <input type="email" name="email"><input type="submit" value="提交"></div>
<div>网址: <input type="url" name="url"><input type="submit" value="提交"></div>
<div>数字: <input type="number" name="num" value="3" max="10" step="2"><input type="submit" value="提交"></div>
<div>滑动条: <input type="range" name="range" value="10" max="100" step="2"><input type="submit" value="提交"></div>
<div>搜索: <input type="search" name="search"><input type="submit" value="提交"></div>
</form>
<fieldset>
<legend>Date pickers</legend>
<form action="#" method="GET">
<!-- date 年月日-->
<div> date<input type="date" name="date"></div>
<!-- month 年月-->
<div>month <input type="month" name="month"></div>
<!-- week 年周-->
<div>week <input type="week" name="week"></div>
<!-- time 时间-->
<div>time<input type="time" name="time"></div>
<!-- datetime 时间-->
<div>datetime<input type="datetime" name="datetime"></div>
<!-- Datetime-local" 时间 -->
<div>datetime-local"<input type="datetime-local" name="datetime"><input type="submit" value="提交"></div>
</form>
</fieldset>
2.新增的input/form的表单验证属性
required 规定输入的域不能为空
autofocus 自动获取焦点
placeholder 提示语 输入内容的时候 就消失 删掉输入的内容 就有回来了
pattern 规定验证input域的模式(正则表达式) pattern="[0-9]{11}
height/width 仅适用于image类型的input标签的图像高度和宽度
autocomplete="off" 检验带之前输入的东西
novalidate 不需要验证
3.validity 属性
1.在h5中为了配合表单的验证, 所有的表单元素都新增了一个validity属性(validityState对象),主要返回验证的状态
var vali=ele.validity// ValidityState对象
vali.valueMissing
2.validityState 对象 - 主要返回当前表单元素的验证状态(用于提供根据错误做出不同的用户提示)
patternMismatch : 输入的内容与pattern属性定义的正则要求不相匹配,则返回true ,反之false
rangeOverflow : 输入的内容大于要求的最大值 ,返回true
rangeUnderflow : 输入的内容小于要求的最小值 ,返回true
stepMismatch :针对于输入数字类型的输入框 ,数字间隔不匹配返回 true
tooLong : 输入的内容超过规定的最大长度 ,则返回 true
tooShort :输入的内容规定不足最短的要求 ,则返回 true
typeMismatch : 输入的内容与规定的类型(url,email...)内容要求不匹配,则返回true , 反之false
valueMissing :如果表单的值为空,则返回true ,反之false
var one =document.getElementsByClassName('one')[0]
var forms=document.querySelector('form')
// invalid事件 只要发生表单的验证 所有未通过验证的表单元素都会触发一个invalid事件
forms.addEventListener('invalid',function(event){
var ele=event.target//没有通过的元素
console.log(ele)
var vali=ele.validity//没有通过的元素的validity属性 下面的ValidityState对象
var notPassName=ele.name//没有通过的元素的name
switch(notPassName){
case 'one':
if(vali.valueMissing){
ele.setCustomValidity(' 昵称不能为空')
}
}
})
4.invalid 事件
h5新增一个 invalid 事件 (单词:valid验证通过 ,invalid验证不通过)
//通过对表单对象添加一个捕获事件(捕获来自于表单内各个输入框的invalid事件,统一做事件错误处理)
loginForm.addEventListener("invalid",function(e){
// console.log("表单验证失败...",e.target);
var ele = e.target;//返回触发当前验证失败事件的元素
console.dir(ele);
ele.setCustomValidity("测试一下提示!!!!!");
},true)
//如果要修改表单验证后的提提示内容 ,可以通过表单元素中提供的一个方法来设置。
// 在表单元素上有一个方法: setCustomValidity() 用于设置消息提示
案例
1.实现表单验证和自定义提示
//1.先获取表单元素
var loginForm = document.getElementById("loginForm");
//2.在父元素上捕获来自于表单元素的invalid 事件
loginForm.addEventListener("invalid", function (e) {
//实现:根据不同的输入框,和不同的错误,做出不同的提示
var element = e.target;//没通过的目标元素
var name = element.name;//没通过的目标元素的name属性
var validityState = element.validity;//没通过的目标元素 validityState对象
// console.log(element,name);
switch (name) {//根据不同的输入框,做出不同的提示处理
case "username":
// console.log('当前是用户名输入有问题', validityState);
if (validityState.valueMissing) {
element.setCustomValidity('用户名不能为空!');
} else if (validityState.patternMismatch) {
element.setCustomValidity('用户名长度必须为:6 - 10位字符!');
} else {
element.setCustomValidity(''); //如果没有错误了,记得设置为空,为空时就没有提示
}
break;
case "password":
if (validityState.valueMissing) {
element.setCustomValidity('密码不能为空!');
} else if (validityState.patternMismatch) {
element.setCustomValidity('密码长度必须为:8 - 16位字符!');
} else {
element.setCustomValidity('');
}
break;
}
}, true);
2.不带js的选项卡
html
<div class="container">
<div class="tab">
<div class="tab-nav clearfix">
<a href="#jd">京东</a>
<a href="#tm">天猫</a>
<a href="#tb">淘宝</a>
<a href="#dd">当当</a>
<a href="#pdd">拼多多</a>
</div>
<div class="tab-content">
<div id="jd">京东</div>
<div id="tm">天猫</div>
<div id="tb">淘宝</div>
<div id="dd">当当</div>
<div id=pdd>拼多多</div>
</div>
</div>
</div>
css
*{
padding: 0;
margin: 0;
}
a{
text-decoration: none;
}
.container{
width: 500px;
margin: 50px auto;
}
.tab{
width: 100%;
}
.tab a{
float: left;
width: 20%;
height: 30px;
background-color: #ddd;
color: #999;
font-size: 12px;
line-height: 30px;
text-align: center;
}
.tab-content{
position: relative;
}
.tab-content div{
position: absolute;/*大内容的每块内容绝对定位 到一起*/
width: 500px;
height: 400px;
background-color: #f1f1f1;
text-align: center;
line-height: 400px;
color: #666;
font-size: 50px;
}
.clearfix::after{/*清浮动的*/
content: "";
display: block;
clear: both;
}
.tab-content div:nth-child(1){/*主要代码段 1*/
z-index: 1;
}
.tab-content div:target{/*主要代码段 让目标元素 :target 跑到最上面来z-index:5 */
background-color: red;
color: #fff;
z-index: 5;
}
3.css3基础
<!-- 1.浏览器对除css3的支持 -->
<!-- IE9 -ms- -->
<!-- firefox -moz- -->
<!-- Chorme & safari -webkit- -->
<!-- opera -o- -->
0.阴影/圆角
1.border-radius:15px 50px 30px 5px;
2.box-shadow: 6px 10px 14px -4px rgb(0, 0, 0,0.5);
/* 阴影) 水平移动 上下移动 模糊半径 阴影大小 */
设置盒子阴影:
1.阴影在水平方向偏移的距离
2.阴影在垂直方向偏移的距离
3.阴影的模糊程度大小
4.阴影的大小
5.阴影的颜色
6.阴影的方向(默认为外阴影) ,也可以设置为 inset 内阴影
.box1{
box-shadow: 0px 0px 10px 0 red inset;
}
.box2{
/*设置多层的阴影(同时设置内外)*/
box-shadow: -10px 0 10px purple inset,
10px 0 10px pink,
0px -10px 10px blue,
0px 10px 10px grey;
}
1.图片边框
使用图片边框前提:必须有边框
border-style: solid;
border-width: 20px;
1.引入边框图片
border-image-source: url("border.png");
2.设置切割图片的偏移距离(简写4个方向,不需要带单位)
border-image-slice: 26;/*在上下左右的26px的地方 切一刀 那么小图片的四个角的地方就是边框的角图片 中间的就是四个边*/
3.设置图片边框的宽度
border-image-width: 36px;
4.设置图像边框超出边框的距离大小
border-image-outset: 16px;如果图片边框比较的 边框的宽度小 那么图片边框就会向里面延伸渲染
5.设置图像边框的平铺铺方式: 默认是拉伸(stretch) / repeat / round
border-image-repeat: round;
2.文本样式
1、文字阴影
和盒子阴影差不多 就是没有模糊大小和内阴影 (四个参数)
1、单个 text-shadow: 0 0 10px #000
2、多个 text-shadow: 0 0 10px #000,0 0 10px red,0 0 10px yellow;
2. /*设置文本强制换行-字母情况下*/
word-wrap: break-word;
/*设置文本的大小写转换
capitalize 单词的首个字母大写
uppercase 全部大写
lowercase 全部小写*/
text-transform:uppercase;
2./*设置文本强制不换行-汉字情况下*/
white-space: nowrap;
/*设置溢出隐藏显示*/
text-overflow: ellipsis;
overflow: hidden;
3.背景
-
设置背景大小
.box{ width: 200px; height: 200px; border: 3px dashed #000; margin: 50px auto; background-image: url("bg_flower.gif"); background-repeat: no-repeat; } .box1{ 1. /*设置背景图片大小 :(宽度 高度): 百分比 ,像素值 可以设置 一个参数:宽度 ,高度则按照宽度的比例等比例缩放 那超出盒子的就不要了 两个参数:宽度 和高度 */ /background-size:100%;/ background-size: 200px; } .box2{ 2. /contain 属性值: 保证宽和高的方向有一个铺满 (哪个方向容易铺满就哪个方向)/ background-size: contain; } .box3{ 3. /cover 属性值 :保证所有的方向都能沾满,图像按等比例宽高进行缩放/ background-size: cover; }
#example1 { background-image: url(img_flwr.gif), url(paper.gif);//允许加多个背景图片 background-position: right bottom, left top; background-repeat: no-repeat, repeat; padding: 15px; }
3.background-clip 下面有 规定背景的绘制区域,从哪个位置开始裁剪图片(外面的不要 padding-box content-box
2.设置背景的区域
2.background-Origin:
规定背景图片的定位区域, 从哪个位置开始放背景图片
1、/*设置背景的区域 :默认 padding-box */
background-origin: padding-box;
2、/*背景会从边框的位置开始,会在边框的下层: border-box*/
background-origin: border-box;
3、/*背景会从内容的位置开始,会在内容的下层: content-box*/
background-origin: content-box;
3.设置背景的裁剪区域
/* 默认: 网页的背景是从盒子模型中的内边距开始的*/
1、 /*背景被裁剪到边框位置*/
background-clip: border-box;}
2、 /*背景被裁剪到内边距位置*/
background-clip: padding-box; }
3、 /*背景被裁剪到内容位置*/
background-clip: content-box; }
4.背景固定
1、background-attachment:无论怎么滚动 图片都在可视区域里面
height: 1500px;
background: url("bg2.jpg") no-repeat;
/*设置背景相对可视区域固定*/
background-attachment: fixed;
5.背景样式简写
背景色 背景图片 背景重复 定位 背景大小 背景固定
background: #ff0000 url("bg2.jpg") no-repeat 0 0 / 100% 100% fixed;
4.字体(小图标)
1、引用字体
@font-face {
font-family: myFirstFont;/*自己取名字*/
src: url(sansation_bold.woff);/*引入进来*/
font-weight: bold;
font-style: normal;
}
2、给需要的文字元素用 p{
font-family:myFirstFont ;/*用自己取的名字的字体*/
font-size: 20px;
}
2、引入矢量图标
/*1.导入图标*/
@font-face {
font-family: icon;
src: url(./fonts2/iconfont.eot),
url(./fonts2/iconfont.svg),
url(./fonts2/iconfont.woff),
url(./fonts2/iconfont.ttf);
}
/*2.使用字体图标*/
span{
font-family: icon;
color: deepskyblue;
font-weight: bold;
}
/*3.在html中用起来*/
<span></span>
3.在伪类中使用iconfont字体
p span{
font-family: icon;
}
p span::before{
font-family: icon;
}
.yl::before{
content: "\e68b";
}
<span class="yl">银联支付</span>
5.透明度
1、background: rgba(0, 0, 0, 0.5); 背景
2、 opacity: 0.5; 背景+内容
3、 filter: alpha(opacity=80);/*针对IE8以及更早版本*/
4、background-color:transparent;
6.渐变
background-image
1.线性渐变
linear-gradient(方向 , 渐变色1 , 渐变色2....)
to right
to left ...
to top right 从左下角到右上角
1、 单词
background-image: linear-gradient(to top right,red,#fff);
2、 角度
background-image: linear-gradient(0deg,red,#fff);(0deg颜色是从下往上的,90deg就是左到右...)
3、可写多个颜色
background-image: linear-gradient(90deg,red 0%,yellow 50%,green 60%,pink);
2.径向渐变
radial-gradient([ [ <shape> || <size> ] [ at <position> ]?, | at <position>, ],渐变颜色1,渐变的颜色2...)
shape : circle (圆形) | ellipse(椭圆形)
size : 设置渐变的半径大小
at <position> : 渐变的开始位置 / 结束位置
1、圆形渐变(默认从中心开始
background-image: radial-gradient(circle,red,green);
2、渐变的半径
background-image: radial-gradient(100px 150px,red,green);
3、指定位置at position(默认中心位置嘛 但是可以直接改
background-image: radial-gradient(circle at center,red,green);默认就是center开始
background-image: radial-gradient(circle at 20% 0%,red,green);右走20% 下走0%
background-image: radial-gradient(circle at 0px 0px,red,green);写具体像素也行 左上角
background-image: radial-gradient(circle at 50% 50%,red,green);中心位置**
4、多写几个颜色
background-image: radial-gradient(circle at 100px 150px,red,yellow,green);
7.filter属性-滤镜
/*filter 属性 : 滤镜
grayscale(100%) 色彩灰度
hue-rotate(90deg); 给图像应用色相旋转
saturate(100%); 调整色相饱和度
brightness() 调整明暗程度
contrast()调整对比度
blur(px) 调整高斯模糊
*/
filter: grayscale(100%);
filter: hue-rotate(90deg);
filter: saturate(100%);
filter: brightness(150%);
filter: contrast(150%);
filter: blur(50px);
8.resize
<textarea name="" id="" cols="30" rows="10"></textarea>
css
/* resize: none; */不允许用户改变宽高
/* resize: horizontal; */允许用户改变宽
/*resize: vertical;*/允许用户改变高
resize: both;允许用户改变宽高
4 .css动画
-
过渡transition
过渡本质 -通过制指定属性的初识状态和结束状态,在两个状态之间进行平滑过渡的方式实现动画
触发条件 -1、伪类触发::hover :active 2、js触发 3、媒体查询 只要该元素的样式与当前设置不一样的效果发生改变时都将触发过渡效果
/* [必须]1.设置允许产生过渡效果的css属性 : none / all / 具体某个css样式属性名 / transition-property: width,height; / [必须]2.设置过渡的时间(过渡动画的播放时长): 单位(s / ms) / transition-duration: 1s; / 3.设置播放动画的延迟时间:单位(s / ms) / transition-delay: 0s; / 4.设置动画播放的速度(时间曲线) :默认ease */ transition-timing-function: ease;
简写:transition: all 0.7s 0.2s ease; 参数: 1.发生变化的那个值 - all/某个单独的属性/none
2.整个动画花费的时长
3.几秒之后开始执行过度 4.过度状态(匀速linear / 慢快慢ease/慢开始 ease-in/慢结束ease-out/慢开始结束ease-in-out4.最后一个参数 linear(匀速 规定以相同速度开始至结束的过渡效果(等于 cubic-bezier(0,0,1,1))。 ease(慢快慢 规定慢速开始,然后变快,然后慢速结束的过渡效果(cubic-bezier(0.25,0.1,0.25,1))默认。 ease-in(慢开始 规定以慢速开始的过渡效果(等于 cubic-bezier(0.42,0,1,1))。 ease-out(慢结束 规定以慢速结束的过渡效果(等于 cubic-bezier(0,0,0.58,1))。 ease-in-out (慢开始结束 规定以慢速开始和结束的过渡效果(等于 cubic-bezier(0.42,0,0.58,1))。
-
动画animation
1.创建帧动画
@keyframes heartJump {
0% {
transform: scale(0.6);
}
25% {
transform: scale(1.2);
opacity: 0.6;
}
...
100% {
transform: scale(0.6);
}
}
2.使用动画
/* [必须]1.设置需要使用的帧动画名称 */
animation-name: heartJump;
/* [必须]2.设置动画播放的时间: 单位(s / ms ) */
animation-duration: 0.8s;
/* 3.设置动画播放的实际曲线 默认: ease */
animation-timing-function: ease;
/* 4.设置动画播放的延迟时间:单位 (s / ms) */
animation-delay: 0ms;
/* 5.设置动画播放的次数 : 数字 、 infinite(无限)*/
animation-iteration-count: infinite;
/* 6.设置动画的轮流反向播放 : alternate 轮流反向 */
animation-direction: alternate;一个来回
/* 8.设置动画的填充模式: 在动画的执行前和执行后的位置 */
animation-fill-mode: both;
#heart:hover {
/* 7.设置动画的播放状态 :paused 暂停 */
animation-play-state: paused;
}
-----------------------------------------------------------------------------------------
8. 8.设置动画的填充模式
none 默认:布局开始的地方开始 动画在播放结束后,会回到最初的布局位置
forwards :布局开始的地方开始,元素最终会停留保持在 最后一帧(100%样式状态)动画的位置
backwards: (需要配合延迟效果)元素在动画的 第一帧(0%)位置出现 然后再回到元素布局开始的地方*/
both : (需要配合延迟效果)元素在动画的 第一帧(0%)位置出现 动画结束后会保留在动画的最后一帧 */
3.简写
animate:
1.动画名称
2.动画的播放时长
3.动画的时间曲线
4.动画的延迟
5.动画的播放次数
6.动画轮流反向播放
7.填充模式
2.animation: name1 3s ease 1s infinite alternate both;
/* 1.名字
2.几秒钟执行完毕
3. 快慢(ease 默认先快后慢
4.次数1.2...infinite无限循环 alternate又倒回来*/
3. 2D/3D转换transform
1)2D:
transform
1、translate():位移,根据左(X轴)和顶部(Y轴)位置给定的参数,从当前元素位置移动。一个参数就只是水平方向
2、rotate() :旋转,在一个给定度数顺时针旋转的元素 负值是逆时针旋转。
3、scale() :放大,该元素增加或减少的大小,取决于宽度(X轴)和高度(Y轴)的参数:
4、skew() :倾斜,包含两个参数值,分别表示X轴和Y轴倾斜的角度,如果第二个参数为空,则默认为0,参数为 负表示向相反方向倾斜。
skewX(<angle>);表示只在X轴(水平方向)倾斜。
skewY(<angle>);表示只在Y轴(垂直方向)倾斜。
5、matrix() :matrix()方法和2D变换方法合并成一个。(表示上面所有)
matrix 方法有六个参数,包含旋转,缩放,移动(平移)和倾斜功能。
1.位移 translate
/*translate()一个参数时,只表示水平方向, 如果两个参数才是水平和垂直*/
transform: translateX(50px);向右
transform: translateY(-50px);向上
transform: translate(50px,50px);
2.旋转 rotate
transform: rotate(90deg);
3.缩放 scale
/*scale() 一个参数 ,则默认宽高同时缩放*/
transform: scaleX(1.5);
transform: scaleY(1.5);
transform: scale(1.5,0.6);
4.拉伸 skew
transform: skewX(45deg);
transform: skewY(90deg);
transform: skew(45deg,45deg);
5.矩阵 matrix
1、 /*2D矩阵规律1: 使用矩阵代替位移,第5 , 6参数代表位移的X , Y*/
transform: matrix(1, 0, 0, 1, 50, 50);
2、/*2D矩阵规律2:使用矩阵代替缩放 第1 ,4 代替x , y 的缩放*/
transform: matrix(1.5, 0, 0, 1.5, 0, 0);
3、 /*a 角度 = 45deg*/
/* 2D 矩阵规律3: matrix(cos(a),sin(a),-sin(a),cos(a),0,0);/!*cos(a)和sin(a)是指旋转度*!/*/
transform: matrix(0.53,0.82,-0.82,0.53,0,0);
4、 /*2D 矩阵规律4:matrix(1,tan(ay),tan(ax),1,0,0)/!*tan(ax)和tan(ay)是对应的倾斜角度*!/*/
transform: matrix(1,1,1,1,0,0);
2)3D:
translate3d(x,y,z) 移动
scale3d(sx,sy,sz) 缩放
scaleZ(sz)
rotateX(a),rotateY(a),rotateZ(a) 旋转多少度
1.3D样式的使用
/*1.设置模拟的舞台距离(透视距离): 一般正常为 1000px 左右*/
perspective: 1000px;
/*2.设置允许模拟子元素的3D显示效果*/
transform-style: preserve-3d;
-
3D - 位移
transform: translateZ(1000px); transform:translate3d(100px,200px,300px);
3.3D - 旋转
1、 /*X旋转 : 类似于跳水运动员落水动作 往前往后仰*/
transform: rotateX(-90deg);
2、 /*Y旋转: 类似于 开门动作旋转*/
transform: rotateY(90deg);
3、 /*Z旋转:类似于2D旋转。画面顺时针和逆时针旋转*/
transform: rotateZ(90deg);
4、 /*注意: 此时参数为4个 rotate3d(x矢量值,y矢量值,z矢量值,基数) , 绕一个固定的旋转中心点旋转*/
transform: rotate3d(1,1,1,360deg);
5、 /*此种方案在实现布局的时候更容易控制元素的角度位置 , 逐个旋转,中心点会发生变化*/
transform: rotateX(360deg) rotateY(360deg) rotateZ(360deg);
4.3D -缩放
transform: scaleX(1.5);
transform: scaleY(1.5);
transform: scale3d(1.5,1.5,1.5);
3)设置旋转中心点transform-origin
没有设置旋转中心点的时候 ,默认是x , y 的中心位置
transform-origin: x y z;
x , y : 参数值可以是数值px , 百分比 ,关键字:left , center right
z : 只能具体的像素值
4.css3性能优化
css3性能优化:
其实在css样式渲染中,效果越酷炫,浏览器的渲染就需要更多的系统资源进行计算和绘制画面,如果说一定要使用这些高级的2D ,3D特效,我们建议:能使用3d的方法实现的尽量不用2d去实现。
例如在transform属性中,translateX() = > 就是一个2d方法
translate3d(100px,0,0) = > 3d方法
rotate(45deg) == rotateZ(45deg)
因为浏览器在渲染的时候其实也是知道上面的这个性能问题,所以在浏览器的内核中渲染css3中3d方法的渲染计算全部直接由硬件直接处理 = 》 “开启硬件加速”
( 因为知道是3d过后 浏览器就会直接把这个丢给CPU 或者GPU处理 会省去一部分引擎处理过程 可以提高一部分性能
就是“开启硬件加速” 直接用硬件处理 )
其实webkit就是chrome浏览器中用于解析和渲染css + html的一个程序
虽然css样式和html在渲染之前需要由浏览器的内核 (中间商)程序进行计算 ,但是程序都是由cpu这个硬件才能做的事情
举例子来讲:
消费者就是html js css
商贩就是引擎
经销商就是浏览器
厂家就是cpu
5.计算器常识
一台正常能够工作的计算机,必备的硬件有以下:
CPU: 负责整个计算机硬件的协调,运算和逻辑判断 (核心)
内存条:暂存运行的程序(程序在执行时存储的数据,重启会清空)
硬盘:永久存储的设备(存储计算机的操作系统和用户的数据)(目前市面上:1.机械硬盘 2.固态硬盘)
显卡:负责将程序处理完的数据渲染成画面用于供用户看
主板:连接各个硬件,能够协调工作
电源:给各个硬件供电
6.封装思想案例
使用基础的面像对象思想进行封装 - 处理兼容问题
封装思想: 把实现业务的复杂流程封装在一个(对象,函数,类)内部,对外提供一个简便的操作方法,外界不需要去理解内部实现
主旨:把复杂的业务拆成诺干个可用于重复调用的小块(函数代码块)。
函数功能单一职责
在js的函数中都有一个方法 bind() 强制装换this指针
1.火狐DOMMouseScroll--e.detail > 0 其他onmousewheel -- e.wheelDelta < 0 (向下
2.var Slide = {
container:null, 整个大的盒子
sections:null,每一屏
topH:[],存入每一屏距离顶部的距离 section[i].offsetTop
index:0,对应屏幕slide盒子需要向上滚动多少 topH[index]
isScroll:true,8.用来节流的 当事件调用时开 事件处理函数时候马上关掉 再里面的最后搞个定时器开
slideSection:function(){},6.切换屏的方法 transform: translateY(-?px)
slideDown:function(){},5.向下滑.. index++
slideUp:function(){},4.向上滑.. index--
scrollEvent:function(){},3.这里写负责处理鼠标滚轮事件 滚轮事件触发后就需要判断是往下还是往滑动
bindEvent:function(){},2.这里写判断的绑定事件onmousewheel和DOMMouseScroll的操作,兼容性的问题,要两个 然后对应的方法就指向scrollEvent里面去 两个兼容事件就可以指向同一个方法了
init:function(){bindEvent()}提供整个封装对象对外的操作接口 和对象的一些数据初始化操作
}
//外部调用初始化所有
Slide.init()
5.多媒体播放
1.方法
controls :显示播放的控件
autoplay :自动播放(有的浏览器的带着muted 才能使用
loop :循环播放
preload :预加载模式:none(网页加载后不会自动加载音频文件,设置了自动播放除外哈)
auto(网页加载后自动加载)
metadata(网页加载后会预先加载音频文件的元数据)
pasued :媒体是否暂停(只读)
ended :媒体是否播放完毕(只读)
duration :开始到播放到现在用的时间
currentTime : 媒体总时间(只读)
volume :0.0-1.0 的音量相对值
muted :是否静音
play() :媒体播放
pause() :媒体暂停
事件:
timeupdate() :时间更新
canplay() :可以播放
2.案例-视频播放器
var flag = 1;
//1.点击播放
playBtn.onclick = function () {
video.play()
this.style.display = 'none'
pauseBtn.style.display = 'block'
}
//2.点击暂停
pauseBtn.onclick = function () {
video.pause()
this.style.display = 'none'
playBtn.style.display = 'block'
}
console.dir(video)
//3.写入总时间
video.addEventListener('canplay', function () {
// console.log(toMs(video.duration))
durationTime.innerHTML = toMs(video.duration)
})
video.addEventListener('timeupdate', function () {
// console.log(video.currentTime)
//4.在流动播放的时间
currentTime.innerHTML = toMs(video.currentTime)
var p = video.currentTime / video.duration * 100
//5.视频进度条 (流动播放的时间 / 总时间)
playerProgressBar.style.width = p + '%'
playerProgress.onclick = function (e) {
//6.点击进度条 视频进度和 进度条都去到对应的地方
console.log(e)
var clickLength = e.offsetX;
var totalLength = this.offsetWidth;
var b = clickLength / totalLength;//=点击的地方到左边的距离 / 进度条总的宽度
playerProgressBar.style.width = b * 100 + '%';
//视频进度也得更新嘛c/d=b
video.currentTime = b * video.duration;
}
//7.是否静音
isMuted.onclick = function () {
if (flag == 1) {
this.setAttribute('src', './img/muted.png')
video.volume = false
flag = 0
} else {
this.setAttribute('src', './img/voiceplay.png')
video.volume = true
flag = 1
}
}
//8.声音控制条
playerVolume.onclick = function (e) {
var clickLengthV = e.offsetX;
var totalLengthV = this.offsetWidth;
var bV = clickLengthV / totalLengthV
console.log(bV)
playerVolumeBar.style.width = bV * 100 + '%'
if (flag == 1) {
video.volume = bV
}
}
//9.全屏
playerFullscreen.onclick = function () {
video.webkitRequestFullScreen()
}
})
//转换时间00:00的方法
function toMs(num) {
var m = Math.floor(num / 60)
m = m < 10 ? '0' + m : m;
var s = Math.ceil(num % 60)
s = s < 10 ? '0' + s : s;
return m + ':' + s
}
6.canvas
1.基础开始
<div class="container">
<!-- width="800" height="800" 设置宽高属性: 指定canvas画布的尺寸,具有多少像素点 -->
<canvas id="canvas" width="800" height="800">您的浏览器版本太低,暂时不支持!</canvas>
</div>
<script>
var canvas = document.querySelector("#canvas");
//获取canvas上下文环境 (获取一支2d画笔)
var ctx = canvas.getContext("2d");
//绘制一条直线
ctx.moveTo(0,0);//绘制起点
ctx.lineTo(800,800);//绘制终点(下一个点)
//设置描边的样式 (需要在进行描边之前设置)
ctx.strokeStyle = "red";//颜色值: rgb , rgba ,十六进制,关键字
ctx.lineWidth = 5;///设置描边的线条粗细
//将路径绘制在canvas 上 (描边)
ctx.stroke();
2.绘制三角形
//绘制三角形
ctx.beginPath()
ctx.moveTo(0,0);
ctx.lineTo(400,400);
ctx.lineTo(800,0);
// ctx.lineTo(0,0);
ctx.closePath()
ctx.stroke();
//设置填充样式
ctx.fillStyle = "rgba(255,0,0,.5)";
//填充路径图像
ctx.fill();
3.绘制矩形
//绘制矩形 - 路径
//确定一个矩形需要 开始绘制位置(x,y)宽 (w) 高(h)
ctx.rect(300,300,200,200);
ctx.stroke();
// 绘制矩形 - 带描边
ctx.strokeRect(300,300,200,200);
//绘制矩形 - 带填充
ctx.fillRect(300,300,200,200);
//清除矩形区域 (制作canvas动画的时候使用的非常多 ,需要把canvas画布清除后再绘制新的画面)
ctx.clearRect(300,300,200,200);
4.绘制圆形
//绘制圆形: 确定圆形(弧线段)的要素: 圆心坐标(x,y) 半径(r)角度(开始 ,结束角度)
//绘制弧线的时候使用的是弧度制(rad) 并非角度制(deg)
//2π(弧度制) == 360°(角度制)
(1°=π/180° ===> 30°=π/6)
(顺序 0°/360°(2π) -> 90°(π/2) -> 180°(π) -> 270°(3/2*π))
//在js 中π 用 Math.PI 表示
ctx.arc(400,400,200,0,Math.PI*2,true); //true 逆时针绘制
ctx.stroke();
四分之一圆
ctx.beginPath();
//添加开始路径
ctx.moveTo(400,400);
//在js 中π 用 Math.PI 表示
ctx.arc(400,400,200,0,Math.PI/2,false); //true 逆时针绘制 , 默认为false 顺时针
ctx.closePath();
ctx.stroke();
5.贝塞尔曲线
//绘制二次贝塞尔曲线
ctx.moveTo(0,0);//设置起点
ctx.quadraticCurveTo(300,800,800,0);
ctx.stroke();
//绘制三次贝塞尔曲线
ctx.moveTo(0,0);//设置起点
ctx.bezierCurveTo(200,800,600,-400,800,400);
ctx.stroke();
6.canvas 位移缩放旋转
1.位移
//绘制之前修改原点坐标位置
ctx.translate(400,400);//本来是以(0,0)左上角坐标开始画的,这样改了就是以(400,400)的左上角坐标开始画
//在canvas中 旋转是绕原点坐标进行的 ,如果要指定旋转中心点可以通过修改原点坐标位置实现。
//位移: 其实就是修改绘图中默认的原点坐标 (0,0)的位置 ,默认是在canvas画布的左上角
ctx.fillRect(0,0,200,100);
2.缩放
//缩放绘制的大小比例
ctx.scale(0.5,1.5);
3.旋转
//设置旋转 : 注意 角度为 弧度制 , 旋转中心为 原点坐标位置
ctx.rotate(Math.PI / 180 * 45);
7.画笔状态
ctx.save();//保存当前环境下的画笔状态 , 以便于恢复
//恢复画笔状态至上一次保存位置
ctx.restore();
//每画一个小块或者一整个大块都用save 和 restore 包起来
8.canvas的渐变
1.线性渐变
//1.使用线性渐变: 选择渐变模式 - 》 创建线性渐变对象
var g = ctx.createLinearGradient(300,0,300,600); 从上到下
//var g = ctx.createLinearGradient(0,600,600,0); 从左下角 到右上角
//2.配置渐变的颜色
g.addColorStop(0,"red");
g.addColorStop(0.5,"purple");
g.addColorStop(1,"green");
//3.使用渐变
ctx.fillStyle= g;
ctx.fillRect(0,0,600,600);
2.径向渐变
var g = ctx.createRadialGradient(300,300,0,300,300,300);
(开始的x圆心坐标,y的,半径, 结束的x,y,半径)
2.配置渐变的颜色
3.使用渐变
9.图形组合方式
ctx.globalCompasiteOpreation
//1.先绘制蓝色的正方形
ctx.fillStyle="blue";
ctx.fillRect(250,250,150,150);
//设置图形组合方式 : 默认(source-over) 后来居上(图层重叠时后面绘制的在上方)
// ctx.globalCompositeOperation ="source-over";
//destination-over 新绘制图形在原图形之下
//source-in 只显示‘新’绘制图形与原图形 交集 中的新图形部分,其他透明
//destination-in 只显示‘原有’图形与新图形 重叠部 分中的原图形,其他透明
//source-out 只显示‘新’图形中与原图形不重叠部分 ,其他透明
//destination-out 只显示‘原有’图形与新图形不重叠部分 ,其他透明
//source-atop 显示‘原’图形 和 新绘制图形中与原图形重叠部分在上面
//destination-atop 显示'新'绘制图形, 和原图形与新图形重叠部分在上面
//lighter 重叠部分色彩会混合
//xor 重叠部分不可见,显示不重叠部分
//copy 只显示新图形 ,原图形不重叠部分全部透明不见
//lighten 保留重叠颜色中比较亮的颜色
//darken 相当于ps正片叠底, 保留重叠部分颜色较暗的色彩
//完整看 :https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Compositing
ctx.globalCompositeOperation ="darken";
//2.绘制一个红色的圆形
ctx.arc(400,400,75,0,Math.PI*2);
ctx.fillStyle = "red";
ctx.fill();
10,绘制阴影
//设置画笔阴影的状态
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
ctx.shadowColor = '#ccc';
ctx.shadowBlur=100;
ctx.arc(300,300,200,0,Math.PI*2);
ctx.fillStyle="#fff";
ctx.fill();
11.绘制图像
可以使用canvas 绘制图像(视频) drawImage()
//用法一: drawImage(img,x,y) 将img图片绘制在xy位置 , img是图片对象
//用法二: drawImage(img,x,y,w,h) 将img图片按w,h宽高绘制在xy位置
//用法三: drawImage(img,sx,sy,sw,sh ,dx,dy,dw,dh) 将img图像中指定位置宽高大小的图片内容绘制到canvas指定位置和大小( 需要的图片里面的坐标和宽高---到 绘制在那个坐标和宽高(所以这里宽高可以控制大小))
在网页中有两种方式获取图片对象
//1. img 标签 = 》 img dom 对象
// var img = document.getElementById("img");
//2. new Image() = > img 对象 暂时什么都没
var img = new Image();
img.src = "img/html5.jpg"; //给img对象设置Src路径
//为了保证图像能成功加载处理再绘制
img.onload = function(){
//用法1:
ctx.drawImage(img,0,0);
//用法2:还可控制图片大小
ctx.drawImage(img,0,385,200,100);
//用法3:
ctx.drawImage(img,135,90,235,265,240,385,100,110);
}
12.绘制视频
var img = new Image();
img.src="img/logo.svg";
var ctx = canvas.getContext("2d");
setInterval(function(){
ctx.drawImage(video,0,0);//这是绘制页面中已经有的video标签已经获取过了
//绘制水印
ctx.drawImage(img,460,10,100,24);
},1000/60);
绘制页面中没有video标签的
var img = new Image();
img.src="img/logo.svg";
var video =document.createElement("video");//创建video 对象
video.src="img/vedio.mp4";
var ctx = canvas.getContext("2d");
var p = 1400;
setInterval(function(){
p--;
ctx.clearRect(0,0,1440,610);
ctx.fillStyle ="#000";
ctx.fillRect(0,0,1400,610);
ctx.drawImage(video,200,0,900,600);
//绘制水印
ctx.drawImage(img,460,10,100,24);
//绘制文字 :
ctx.fillStyle ="#fff";
ctx.fillText("这是一个弹幕!!!",p,100)
},1000/60);
13.图像平铺
var img = new Image();
img.src = "img/icon.jpg";
img.onload = function(){
var g = ctx.createPattern(img,"repeat-y"); //创建平铺对象 , no-repeat
ctx.fillStyle = g;
ctx.fillRect(0,0,600,600);
}
14.绘制文字
//设置字体的样式 (参照css样式中的font属性)
ctx.font = "italic bold 50px 微软雅黑";
风格 粗细 大小 字体
//设置文字的对齐方式 : center / left / right
ctx.textAlign = "center";
//设置文字的垂直对齐方式:top / middle / bottom
ctx.textBaseline = "bottom";
//绘制文字 - 描边
ctx.strokeText("教育改变生活 - 描边",300,200);
//绘制文字 - 填充
ctx.fillText("教育改变生活 - 填充",300,400);
15.base64编码图片
在网页中使用 base64图片 和 直接引用图片 的区别
base64:
1.使用的base64其实是将图片放入到网页文件中,属于网页文件中的内容
2.使用base64图片无法使用缓存
3.使用base64图片可以减少网页的http请求次数
直接引用图片:
1.使用图片地址其实是引用的图片
2.引用图片地址,浏览器会对加载过同一个地址的图片进行缓存,所以如果多处使用同一个图片文件,浏览器只需要加载一次
总结建议:如果只是非常小的图标建议使用base64,如果图片文件稍大不建议使用
16.toDataURL 保存canvas图片
//点击canvas保存图片
canvas.onclick = function(){
//保存图片 toDataURL(图片类型,图片的质量(压缩比值)) 0 - 1
// png 图片格式是不支持压缩的 , 所以要压缩的使用jpg / jpeg
// 注意: 默认导出为png格式 ,如果需要导出为jpeg ,需要填充背景
// console.log(canvas.toDataURL('image/jpeg'));
//网页中实现下载功能 实现:通过a标签实现
var a = document.createElement("a");
a.href = canvas.toDataURL('image/jpeg',0.1); //压缩的比值默认为 0.92
a.download = new Date().getTime() + '下载图片';//设置下载图片的名字
a.click();//模拟点击a标签
//导出的图片可以是base64编码, 也有是二进制对象数据 Blob 二进制大对象
canvas.toBlob(function(blob){
console.log(blob);
})
}
17.图像数据getImageData
//获取canvas画布中的图像数据
var imgData = ctx.getImageData(0,0,600,600);
console.log(imgData);
//是一个一维数组 顺序是从左到右 从上到小
/*
图像数据 :
图像就是由像素点构成的 , 所以获取的图像数据就是canvas画布中的像素的色彩信息
色彩的构成: R G B A(透明度) - 》 每一个像素点
canvas的尺寸 600 * 600 其实就是横向600个像素点 ,纵向也是 600个像素点
当前画布中有 = 600 * 600 36万像素
每个像素点 : RGBA 构成
所以当前画布数据中包含 = 36万 * 4 = 1440000 个数据
所有的数据都集中在一个一维数组中 ,每个点占4个数据位置
举例:
数据中的 0 1 2 3 索引位置 就是代表的是canvas中第一个像素点的信息
R G B A (每个色彩信息的取值范围都是 0 - 255)
*/
//尝试修改图像数据(第二排的第一个 4X600=2400)
imgData.data[2400] = 255;
imgData.data[2401] = 0;
imgData.data[2402] = 0;
imgData.data[2403] = 255;
//将修改完的数据重新放回到canvas中 (重绘)putImageData
ctx.putImageData(imgData,0,0);
18.绘制视频数据
timer = setInterval(function () {
ctx.drawImage(video, 0, 0);
//获取图像数据
var imgData = ctx.getImageData(0, 0, 600, 450);
//通过一定算法处理图像数据
for(var i=0;i<imgData.data.length;i+=4){
//反相原理:
//修改每一个像素点的数据 i = > 像素点中R的值 i+1 => G i+2 = >B i+3 = >A
// imgData.data[i] = 255 - imgData.data[i];//修改的R
// imgData.data[i+1] = 255 - imgData.data[i+1];//修改的G
// imgData.data[i+2] = 255 - imgData.data[i+2];//修改的B
//仿PS灰度模式: (rgb的值一样就是灰色调)
var light = 1.5;
var p = (Math.floor(imgData.data[i] + imgData.data[i+1] + imgData.data[i+2]) / 3) * light;
imgData.data[i] = p;//修改的R
imgData.data[i+1] = p;//修改的G
imgData.data[i+2] = p;//修改的B
}
//将修改完的数据重新绘制
ctx.putImageData(imgData,0,0);
//绘制水印
ctx.drawImage(img,460,10,100,24);
}, 1000 / 60);
19.canvas的其他高级接口
方法:
getImageData() 获取canvas上的图像数据
createImageData() 创建图像数据
putImageData() 将图像数据绘制到canvas
arcTo() 设置两条切线间的弧线段(设置圆角大小)
ellipse() 绘制椭圆形
isPointInPath() 判断某个点十分在当前绘制的路径中 ,返回布尔值
属性:
1、filter 滤镜 ctx.filter = "blur(5px)".....;
2、lineJoin 两条线连接的地方 ctx.lineJoin = "miter";(默认)
miter(棱形) /bevel斜角(三角形的底部) / round 圆角
3、lineCap 线条的结束端点 设置或返回线条的结束端点样式。butt / round / square
4、globalAlpha 透明度 用来描述在canvas上绘图之前,设置图形和图片透明度的属性。 数值的范围 从 0.0 (完全透明)到1.0 (完全不透明) ctx.globalAlpha =值;
5、miterLimit 设置最大的斜角长度 相交时的尖角长度
*/
ctx.moveTo(50, 50);
ctx.lineTo(450, 50);
ctx.arcTo(500, 50, 500, 100, 50);
ctx.lineTo(500, 400);
//设置端点的样式, 默认是方形butt / round / square(线段末端以方形结束,但是增加了一个宽度和 线段相同,高度是线段厚度一半的矩形区域
ctx.lineCap = "round";
// 设置相交线段的拐角样式 默认尖角 miter /bevel斜角 / round 圆角
// ctx.lineJoin = "round";
// 设置最大的斜角长度 相交时的尖角长度
// ctx.miterLimit=5;
ctx.lineWidth = 10;
ctx.stroke();
20.canvas插件-数据可视化
数据可视化:
所谓的数据可视化就是将大量的数据通过图形或列表的方式的呈现(更易于分析数据的规律)
例如生活场景:
1. 支付宝账单 (月度的消费情况)
2. 疫情地图 (每日新增对比,地图标注)
3. 双11的时候,在双11的成交金额监控平台呈现实时的交易金额
....
-----------------解决方案------------------------
专门用于绘制图表数据:扇形图, 条形图,折线图,k线图,地图,雷达图...
1.echarts (百度) --里面有已经配好的例子
2.charts (相对而言功能比echarts少一些)
专门用于绘制:流程图 ,结构图 ...
3.go.js
4.three.js 专门用于处理canvas3D 效果
echarts的使用
<script>
//1.开始在上面去设置好容器的宽高等
var container = document.getElementById('container')
// 2.基于准备好的dom,初始化echarts实例
var myChart = echarts.init(container);
// 3.指定图表的配置项和数据
option = {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
},
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: [50, 200, 36, 120, 150, 200]
}]
};
// 4.使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
7.requestAnimationFrame()
解释
requestAnimationFrame() 相当于setTimeout()
但是requestAnimationFrame() 不用设置固定的间隔时间 会自动按照最佳的时间刷新
1.差异点
1.如果我们使用定时器就会存在一个问题:
无法精确设置一个最佳的时间(频率),因为js是一个单线程的任务,如果频率太快,就会导 致任务处理量过多 容易线程堵塞(卡死),如果频率过低,会导致动画不流畅
2.requestAnimationFrame的特点:
1.requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或者回流中就完成,并且重绘和回流的时间间隔会紧紧跟随浏览器的刷新频率
2.在隐藏或者不可见的元素中,requestAnimationFrame将不会进行重绘或者回流,这当然就意味着更少的cpu。gpu 和内存使用量
3.requestAnimationFrame是由浏览器专门为动画设置的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活的状态下的话,动画会暂停,有效的节省的cpu开销
使用
var box = document.getElementsByClassName('box')[0]
var timer = null
var left = 0
function animate() {
left++
box.style.left = left + 'px'
// timer = setTimeout(animate, 1000 / 60)
timer=requestAnimationFrame(animate)
if(left>=500){
cancelAnimationFrame(timer)
}
}
animate()
8.H5离线存储
web存储:主要是为web应用提供存储数据操作(存储用户信息,访问记录,资源的文件内容等等..)
1.浏览器缓存
缓存可以说是性能优化中简单高效的一种优化方式了。
一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷。
浏览器的缓存机制需要与后端配合使用,无需前端额外配置(目的就是将一些静态资源文件进行缓存,减少再次访问的加载数据次数,提升响应速度,说白了就是第二次直接从浏览器缓存读取,而不需要从服务器另行下载)
1)Memory Cache (内存中的缓存,内存是临时存储,关机重启就释放 , 一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。)
2)Disk Cache (硬盘上的缓存,持久化存储,除非手动删除(或强制刷新))
2.离线存储
在线的时候空闲时间先把需要缓存的资源下载好 ,即使离线了也可以正常访问
一旦被离线存储缓存的文件内容,后续无法通过重新加载或刷新实现更新内容(关闭浏览器也不会清除),需要手动清除浏览器的缓存记录。
可以存储一些web应用使用的资源文件 ,只要配置好缓存清单即可。
使用步骤:
1)服务器端开启支持缓存清单文件 (文件mime类型: text/cache-manifest)
以xampp搭建的http服务举例说明使用:
在xampp安装目录下,找到apache的文件目录下 ,conf/mime.types ,在最后位置添加一条记录:
text/cache-manifest appcache
修改完配置,记得重启apache服务
2)配置前端页面的缓存清单:其实浏览器就是根据这个配置的缓存清单文件,进行资源的缓存
在项目的根目录下,创建一个 home.appcache 文件 添加以下配置:
CACHE MANIFEST
#这是注释 ,配置以下内容需要进行缓存
CACHE:
login.html?v=1234
NETWORK:
# 指的是不会被缓存的文件, 以下文件需要在有网的情况下访问
FALLBACK:
#如果无法建立英特网请求(如404),而打开的文件
3)关联页面的缓存清单关系:在网页中设置,需要使用哪个缓存清单文件
<!-- 设置当前页面需要关联缓存的清单文件 -->
<html lang="en" manifest="home.appcache">
H5离线缓存如何更新:如果有修改资源文件,必须通过修改mainfest文件来刷新被缓存的文件列表
H5离线缓存的优点:1>完全离线;2>资源被缓存,加载更快;3>降低server负载
3.cookie
cookie(曲奇,饼干)存储在浏览器客户端的用户数据(用户的身份信息,行为记录...)
特点:
1.每次发起http请求,都会默认携带当前访问站点的所有cookie信息(服务器端也可以去操作cookie)
2.存储在浏览器客户端(安全性不高 ,不会存储特别隐私的数据)
3.前端可以使用js操作(如果设置onlyHttp就不可以了) , 后端也可以通过http请求/响应包头操作(读取,写入)
4.浏览器每个站点下只能存储20条(视浏览器情况而定)cookie , 每条cookie的存储不超过4kb
5.cookie受同源策略限制(xss跨站攻击)无法跨站点读取cookie
6.可以设置存活时间,浏览器关闭只要在存活周期内都不会丢失(手动删除肯定会丢失)
设置一个cookie:
name cookie的名字(类似于json对象的属性名)
value 值
expires cookie的存活周期
以下为安全考虑的设置属性:
domain 域名(规定当前的cookie作用的域名)
path 规定当前cookie在当前域名下的那个路径下可用(有点像变量的作用域)/根目录(所有的都可以访问 , /user 表示只能在当前域名下的/user目录下可访问)
onlyHttp (用于设置是否仅http环境下可访问 , 无法使用js读取cookie信息,杜绝xss攻击的风险 )
secure 只能通过https协议的情况下发送给服务器
samesite(设置访问站点在不同情况下是否发送cookie)年初的时候chrome有更新过策略 (strict / lax / none)
不足:涉及到一些安全问题容易被跨站攻击(XSS),这个问题是可以解决的 ,读取,存储的时候很不方便。
TOKEN (令牌):常用于web应用登录的身份校验标识
网站临时访问(用户标识:user-key = > uuid)
插件推荐
推荐 js-cookie.js 插件 可以提供对cookie的增删改查操作
自己封装的cookie插件
html-JavaScript
//1.设置cookie
Cookies.set('name1', 'strawberry1', 365)
Cookies.set('name2', 'peach2', 365)
Cookies.set('name3', 'orange3', 365)
//2.根据键名获取相应的value值
var getCookie = Cookies.get('name3')
console.log(getCookie)//orange3
// //3.删除cookie
Cookies.remove('name1')
//4.清空cookie
Cookies.clear()
/** 封装一个cookie操作方法
* 1.set(key,value,expires,path) 设置
* 2.get(key) 根据key获取相应的cookie值
* 3.clear() 清空
* 4.remove(key) 删除指定key的cookie
*
*
* */
(function (win) {
// 1.定义一个设置cookie的方法
function setCookie(key, value, expires, path) {
//1.1 设置参数
var expires = expires || 30//默认存储的天数
var dateTime = Date.now() + (expires * 24 * 60 * 60 * 1000) + 8 * 60 * 60 * 1000//截止时间戳1588364775578
dateTime = new Date(dateTime).toUTCString()//获取截止时间GMT时间-Fri, 01 May 2020 20:26:26 GMT
// console.log(dateTime)
var path = path || '/'//存储cookie的路径
//1.2 写入cookie
document.cookie = key + '=' + encodeURI(value) + ';Expires=' + dateTime + ';path=' + path//encodeURI 解决中文会乱码的问题
console.log( document.cookie)
}
//4.定义一个根据键名获取相应的value值
function getCookie(key) {
var cookie = document.cookie
// console.log(cookie)//name1=strawberry1; name2=peach2; name3=orange3
var a = cookie.split(';')
var obj = {}
for (var i = 0; i < a.length; i++) {
var tmpARR = a[i].split('=')
obj[tmpARR[0].replace(/\s/g, '')] = tmpARR[1]
}
// console.log(obj)
return obj[key]
}
//5.删除cookie方法
function removeCookie(key) {
// document.cookie = key + '= ;Expires=-1'//只会删掉value
document.cookie = key + '= ;Expires=' + new Date(0).toUTCString()
}
//6.清空cookie的方法
function clearCookie() {
// var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
var name = document.cookie.split('; ')
var nameArr = []
for (var i = 0; i < name.length; i++) {
var b = name[i].split('=')
nameArr.push(b[0])
}
console.log(nameArr);
console.log(new Date(0))
for (var i = 0; i < nameArr.length; i++) {
// document.cookie = nameArr[i] + '= ;Expires=' + new Date(0).toUTCString()
document.cookie = nameArr[i] + '= ;Expires=-1'
}
}
//2.暴露一个cookies对象,提供对外使用
var Cookies = {
set: setCookie,
get: getCookie,
remove: removeCookie,
clear: clearCookie
}
//3.暴露为全局对象, 其实就是挂载到window对象下面
win.Cookies = Cookies
})(window)
4.session
session (会话) 存储在服务器端的会话数据(用户信息...)会在浏览器访问网页的时候,在服务器中创建一个session会话(会跟当前访问的浏览器进行关联,会在浏览器中存储一个cookie,记录对应访问在服务器端的session_id 标识)
特点:
1.存储少量的数据
2.存储在服务器端
3.存储的数据比cookie更加安全
4.无法设置存活周期,浏览器关闭,自动销毁
5.本地存储 - localStorage / sessionStorage
( 前端优化的一项重要策略手段 )
5.本地存储(h5) - localStorage / sessionStorage
localStorage:持久化存储本地数据 ,存储的内容比较大(4m),不需要设置存储周期,只要不删除就是永久存储。
应用场景:
1.存储一些万年不变的静态资源 ,可以减少加载的时间提高访问速度,降低服务器压力
2.存储用户记录数据(用户的基本访问历史记录 token ...)
3.小程序(混合app)主要就是靠localStorage 来存储数据
sessionStorage:使用方式与localStorage相似(具有相同的API),内容存储比较大,只要浏览器关闭就会自动销毁。
1.都受浏览器的同源策略保护,无法实现跨站点访问存储数据。
2.存储数据不会跟随http协议的请求发给服务器, 仅提供客户端本地操作。
3.操作接口,比cookie更为人性化。
(需要http环境)改变存储的时候会触发一个 window窗口上的 storage 事件 ,该事件 为了避免事件的死循环 ,不会在触发当前修改存储的页面中触发该事件,也就是在同一个浏览器的其他标签页或窗口触发。
如果存取的数据是对象类型的话记得一定要转成字符串类型,不然就是[object Object]!!!
自己:
1、本地存储(webstorage)-在客户端本地存储的
1.存储量是5M--(比cookie大
2.客户端完成,不会发送请求让服务器处理,不会浪费资源,浪费带宽
3.sessionStorage数据是不共享的
localStorage共享的
2、分为两类:sessionStorage-临时
窗口的临时存储 页面一关闭,本地存储就消失
localStorage-永久存储
如果不人为的删除 数据就永远还在
3、web storage常用方法
setItem()
-设置数据
key/value类型,类型都是字符串
getItem()
-获取数据
通过key 来获取相应的value
removeItem()
-删除数据
通过key来删除相应的value
inputs[1].onclick = function () {
window.localStorage.setItem('name1', inputs[0].value)
}
inputs[2].onclick = function () {
alert(window.localStorage.getItem('name1'))
}
inputs[3].onclick = function () {
window.localStorage.removeItem('name1')
}
4、web storage 事件(storage)
当有数据的修改和删除的情况下,就会触发这个storage事件
在对数据进行改变的窗口对象上是不会触发的
Key:修改和删除的key的值
newValue:新设置的值
oldValue:调用改变前的value值
storageArea:当前的storage对象
url:触发该脚本变化的文档的url
window.addEventListener('storage', function (e) {
alert('发s生变化了')
console.log('修改和删除的key的值: ' + e.key)
console.log('新设置的值: ' + e.newValue)
console.log('调用改变前的value值: ' + e.oldValue)
console.log('当前的storage对象: ' + e.storageArea)
console.log('触发该脚本变化的文档的url: ' + e.url)
})
-
方法,属性,事件
本地存储: localStorage 方法: setItem(key,value) 设置对应的键key 和value值 getItem(key) 获取对应的key的值 removeItem(key) 删除指定键名key的数据 clear() 清空 删除所有 key(index) 返回所有存储数据中指定索引位置的键名 属性: length 返回存储记录数量 事件: storage 只要当前浏览器下(同一个站点下的) localStorage 存储内容有发生改变 即会触发该事件。
2.使用
console.log(window.localStorage);//Storage {height: "1.8", age: "11", name: "apple", length: 3}
//设置存储数据
localStorage.setItem('name','apple');
localStorage.setItem('age','11');
localStorage.setItem('sex','男');
localStorage.setItem('height','1.8');
//获取指定的键值
console.log(localStorage.getItem('name'));//apple
//删除指定的键
localStorage.removeItem('sex');
//返回所有存储数据中指定索引位置的键名
console.log(localStorage.key(0))//age
//清空所有的存储数据
localStorage.clear();
3.案例-4.将请求的样式存储到本地存储
<div class="container">
<div class="page-header">
<h2>使用Ajax加载样式 - 并存储到本地数据</h2>
</div>
</div>
<script src="js/jquery-1.12.4.min.js"></script>
<script>
//4.访问的时候需要判断本地是否存储过了,如果已经存储则使用存储的数据 ,没有则ajax请求
var bootstrapStyle = window.localStorage.getItem('bootstrap.min.css');
// console.log(bootstrapStyle);
if (bootstrapStyle) {//有
console.log('有读取到数据');
applyStyle(bootstrapStyle);
} else {
console.log('没有读取到数据');
//1.使用js 将加载的css样式存储到本地
$.ajax({
url: "/css/bootstrap.min.css",
success: function (data) {
console.log(data);
//2.使用css样式
applyStyle(data);
//3.存储到本地
localStorage.setItem("bootstrap.min.css", data);
}
})
}
//2.定义一个应用css样式代码的函数
function applyStyle(data) {
var style = $('<style>' + data + '</style>');
$("head").append(style);
}
</script>
6.websql / indexD
新增的用于提供浏览器端能够像后端一样的数据库存储数据(主要提供数据的存储,删除,更新,查询操作)
IndexedDB 具有以下特点。
(1)键值对储存。 IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以"键值对"的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误。
(2)异步。 IndexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作,这与 LocalStorage 形成对比,后者的操作是同步的。异步设计是为了防止大量数据的读写,拖慢网页的表现。
(3)支持事务。 IndexedDB 支持事务(transaction),这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
(4)同源限制 IndexedDB 受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。
(5)储存空间大 IndexedDB 的储存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有上限。
(6)支持二进制储存。 IndexedDB 不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。