# 前端基础知识归纳

返回:大前端

🐎 HTML5 新特性详解 🐎 css 变量
less 学习 sass 学习
Jquery 闭包太难了
JS 规范 JavaScript 运行机制
svg js 基础知识
位运算 网络
html 基础标签 FormData 对象
MIME 类型 私有属性【#】

# JavaScript 来编写你的 CSS 样式代码——JSS

# 度量单位

返回顶部

单位

浏览器当前支持 16 种度量单位:像素英寸皮卡厘米毫米百分比emrem,视口尺寸(vwvh),exchvmax(最大视口)和vmin (viewportmin)在这16个单位中有两类:相对长度和绝对长度。
在 CSS 中有许多距离单位,比如 px | em | rem | %,还有 CSS3 中的 vh | vw 等单位

# 度量单位简介

返回顶部

  • 基础单位 px
    px 是我们最早接触到的单位了,不过我们在移动端自适应的要求下,使用的频率不是很高
    比较小的图案
    1px 细线问题
    字体大小(基本都是用 rem 作为单位)
  • 相对单位 rem
    rem 是 CSS3 新增的一个相对单位(root em),即相对 HTML 根元素的字体大小的值
    rem 应该是自适应使用的最广泛的单位了
  • 相对单位 em
    em 也是一个相对单位,却是相对于当前对象内文本的字体大小
    line-height:一般建议在 line-height 使用 em。因为在需要调整字体大小的时候,只需修改 font-size 的值,而 line-height 已经设置成了相对行高了
    首行缩进两个字符:在存在首行缩进的需求,我也会使用这个单位
  • 视口单位 vw | vh
    vw: 1vw = 视口宽度的 1%
    vh: 1vh = 视口高度的 1%
$vm_fontsize: 75;
@function rem($px) {
     @return ($px / $vm_fontsize ) * 1rem;
}
$vm_design: 750;
html {
    font-size: ($vm_fontsize / ($vm_design / 2)) * 100vw;
    @media screen and (max-width: 320px) {
        font-size: 64px;
    }
    @media screen and (min-width: 540px) {
        font-size: 108px;
    }
}
// body 也增加最大最小宽度限制,避免默认100%宽度的 block 元素跟随 body 而过大过小
body {
    max-width: 540px;
    min-width: 320px;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 相对长度

它们会在其他物体上获得尺寸,这些尺寸在您要设定尺寸的元素之外或相对于它们,例如,父级的尺寸字体大小视口尺寸

# 百分比

百分比基于其父元素。 因此,如果一个元素为200px * 200px,并且该元素的子元素的宽度为 50%,高度为 50%,则该子元素的等效尺寸为100px * 100px,因为 200px 的 50%为 100px。

# 视口尺寸

当前有四种类型的视口尺寸单位,vw(视口宽度),vh(视口高度),vmin(视口最小)和 vmax(视口最大)。 使用这些单位时要知道的第一件事是,它们会自动将浏览器的屏幕划分为 100 x 100 的不可见网格,网格中的每个正方形或单位将根据情况代表一个 vw,vh,vmin 或 vmax。

ee2ba99e8e524918b8200b31d18aa40c.jpg

# vh 与 vw

因此,让我们更深入地研究这两个。
如果我们声明一个元素的宽度为 50vw 且高度为 50vh,我们将看到该元素将恰好占据页面高度的一半,并且占据页面宽度的一半,每个 vw 或 vh 现在相当于那个不可见的 100 中的一个单元,所以如果我们声明一个元素为 50vw,它将是浏览器宽度的一半,下面我们来看一个示例。

# vmin 和 vmax

这些单位比较棘手。
因此,这些单元的工作方式是将使用高度或宽度的最大或最小长度

现在进入 vmin。类似 vmax,按照最小的视口尺寸来获取

.parentBox {
  font-size: xx-large;
  width: 50vmax;
  background-color: rgba(255, 0, 0, 0.8);
}
1
2
3
4
5
<div class="parentBox">parent-box</div>
1
  • 浏览器的宽度为800px,高度为500px,则父框的宽度为400px,因为宽度大于高度,所以 元素将从浏览器的水平部分的不可见网格中获取 50 个单位
  • 如果浏览器的高度为1000px,宽度为500px,则父框的宽度现在为500px,因为浏览器的高度现在大于宽度,因此父元素 box 将占据浏览器垂直边 100 平方中的 50 平方,并使用它来声明父对象的框宽

# 基于字体属性的单位

响应式开发最不好不要杂合使用rem

# ex 和 ch

我从未使用过这些单元,但让我们看看它们是如何工作的。
所以首先让我们从ex开始。 这个单位测量您正在使用的任何字体系列的字母" X"的高度,这是指字母" X"的高度,
因此,如果此" X"的高度为 10px(字面的字母为" X"),则 1ex 将为 10px,假设您使用的是另一个字体系列中的" X",其中" X"的高度为 9px,所以现在 1ex 是 9px。
ch的行为方式非常相似,不同之处在于1ch的长度将基于字体家族的字母" O"的宽度,因此,如果字母" O"的宽度为 5px,则 1ch 将等于 5px 。

# em

此单位响应父元素的字体大小,因此,如果父元素的字体大小为 10px,则每个 em 现在等于 10 px。

.parentBox {
  /* font-size: xx-large; */
  width: 50vmax;
  height: 30vh;
  font-size: 15px;
  background-color: rgba(255, 0, 0, 0.8);
}
.childBox {
  height: 15em;
  width: 15em;
  background-color: rgba(23, 26, 23, 0.5);
  color: beige;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="parentBox">
  parent
  <div class="childBox">child</div>
</div>
1
2
3
4

2020-03-31_094905.gif

# rem

现在,rem 与 em 有所不同,因为 rem 基于根字体大小而不是父字体来确定其尺寸。 rem一词的意思是" root em",这解决了我们在 em 元素级联时遇到的问题,通过基于 root 取其维度,rem 值在整个文件中都相同。 因此,让我们看一下相同的示例,但带有 rem。

# 绝对长度

绝对长度不会根据其他因素或页面,父级,视口等其他因素来决定其大小。

# 英寸,厘米和毫米

因此,我觉得关于这些度量单位的解释很多。 如果您将某物声明为1in,则无论屏幕大小如何,该值都将为 1in。 厘米和毫米也一样

# Points 和 Picas

因此,points和picas是印刷术语point是1/72英寸,因此很小,12 点活字就是 12 点或 1/6 英寸。

# 像素

现在,像素是绝对长度,但是它们的大小可能取决于您所使用的设备,某些设备的像素比其他设备大,这取决于它们的密度和分辨率

# SVG

返回顶部

Web 动画

其实包含了以下三大类:

  • 1、CSS3 动画
  • 2、javascript 动画(canvas)
  • 3、html 动画(SVG)

# SVG 线条动画基础入门知识

# SVG 是什么

可缩放矢量图形,即 SVG,是 W3C XML 的分枝语言之一,用于标记可缩放的矢量图形。(摘自 MDN)
先谈谈 svg 标签:

  • version: 表示 <svg> 的版本,目前只有 1.0,1.1 两种(截至 2019.12.20)
  • xmlns:http://www.w3.org/2000/svg 固定值
  • xmlns:xlink:http://www.w3.org/1999/xlink 固定值
  • xml:space:preserve 固定值,

上述三个值固定,表示命名空间,当数据单独存在 svg 文件内时,这 3 个值不能省略

  • class:就是我们熟悉的 class 类选择器
  • width | height: 定义 svg 画布的大小
  • viewbox: 定义了画布上可以显示的区域,当 viewBox 的大小和 svg 不同时,viewBox 在屏幕上的显示会缩放至 svg 同等大小

有了 svg 标签,我们就可以愉快的在内部添加 SVG 图形了

# SVG 基本形状

MDN Web 有基本形状的文档,建议去看看。包含矩形、圆形、椭圆、线条、多边形、折线等等。
好了,有了基本的了解,我们继续今天的话题,SVG 线条动画。

# SVG 线条动画

ok,像以前一样,我们先来解析一下(按步骤实现):

  • 1、svg 画个按钮(基础形状-矩形)
  • 2、矩形只保留下方底边
  • 3、实现鼠标:hover 事件 + 动画效果

svg 画个按钮

<div class="button">
  <svg viewBox="0 0 320 60" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <rect class="shape" height="60" width="320"></rect>
  </svg>
  <div class="hover-text">Web 秀</div>
</div>
1
2
3
4
5
6

添加样式

.button {
  position: absolute;
  width: 320px;
  height: 60px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.hover-text {
  position: absolute;
  line-height: 60px;
  width: 320px;
  top: 0;
  color: #1199ff;
  font-size: 28px;
  text-align: center;
  cursor: pointer;
}
.shape {
  fill: transparent;
  stroke-width: 4px;
  stroke: #1199ff;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

button 垂直水平居中、shape 透明填充,边框宽度 4px,边框颜色#1199ff。

也许你会对 fill、stroke-width 等属性有点懵,下面看看他们的描述:

  • fill:类比 css 中的 background-color,给 svg 图形填充颜色
  • stroke-width:类比 css 中的 border-width,给 svg 图形设定边框宽度
  • stroke:类比 css 中的 border-color,给 svg 图形设定边框颜色
  • stroke-linejoin | stroke-linecap:设定线段连接处的样式;
  • stroke-dasharray:值是一组数组,没数量上限,每个数字交替表示划线与间隔的宽度;
  • stroke-dashoffset:则是划线与间隔的偏移量

重点讲讲能够实现线条动画的关键属性 stroke-dasharray 。属性 stroke-dasharray 可控制用来描边的点划线的图案范式。

SVG 矩形只留底边

这里我们给按钮添加 stroke-dasharray:

.shape {
  ... stroke-dasharray: 160 520;
  stroke-dashoffset: -460;
}
1
2
3
4

SVG hover 动画

.button:hover .hover-text {
 transition: 0.5s;
 color: pink;
}

.button:hover .shape {
 -webkit-animation: draw 0.5s linear forwards;
 animation: draw 0.5s linear forwards;
}

@keyframes draw {
 0% {
 stroke-dasharray: 160 520;
 stroke-dashoffset: -460;
 stroke-width: 4px;
 }
 100% {
 stroke-dasharray: 760;
 stroke-dashoffset: 0;
 stroke-width: 2px;
 stroke: pink;
 }s
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

hover 时,改变文字颜色,利用 stroke-dasharray 和 stroke-dashoffset 实现动画效果。

# 4 个常见且常用的 SVG 交互动画方法

返回顶部

# 什么是可交互的 SVG 动画

之前的案例我们做的都是固定不变的动画,假如我希望动画内容是个性化的信息填充,这样我们就需要让 SVG 动画变成框架动画,动画的内容由后台给出再填充动画,最后呈现给使用者。最简单的例子就是产品的轮播图。再假如,我希望动画的播放进程是根据页面滚动来触发播放,同时动画会和页面的高度百分比同步进度。那这些想法的落地就需要为 SVG 动画插上交互的翅膀,让它能够提高用户体验

先看三个例子

# 访问并修改动画的可行方案

在使用 AE 制作完动画,并使用 Bodymovin 导出动画后,我们会获得一个 data.json 文件。这个文件包含了 AE 中关于动画的所有属性和对应的值,当前端加载动画时,就会读取 json 文件中的数据并实时计算重绘制动画

根据这个流程,如果我想要临时更改动画的某一个属性,那么可操作的方案大致有三种

  • 第一种是直接访问请求到的 json 文件中的键并修改它的值,修改完再渲染播放动画。
  • 第二种是使用 lottie_api.js来访问修改 json 文件中的内容,修改完后再重新渲染动画。
  • 第三种是直接通过 JS 去更改网页中 DOM 元素的内容。

# SVG 入门指南(看完,对 SVG 结构不在陌生)

# 创建

<svg width='140' height='170' xmlns='http://wwww.w3.org/2000/svg'>
  <title>Cat</title>
  <desc>Stick Figure of Cat</desc>
  <!-- 在这里绘制图像 -->
</svg>
1
2
3
4
5

根元素 <svg> 以像素为单位定义了整个图像的 width 和 height,还通过 xmlns 属性定义了 SVG 的命名空间。
<title> 元素的内容可以被阅读器显示在标题栏上或者是作为鼠标指针指向图像时的提示,
<desc> 元素允许咱们为图像定义完整的描述信息。

# 基本形状和属性

  • 基本图形——<rect>、<circle>、<ellipse>、<line>、<polyline>、<polygon>
  • 基本属性——fill、stroke、stroke-width、transform

# Javascript 中的原型是什么

back

原型通常指的是prototype__proto__这两个原型对象,其中前者叫做显式原型对象,后者叫做隐式原型对象。

Javascript 对象从原型继承方法和属性,而 Object.prototype 在继承链的顶部。Javascript prototype 关键字还可以用于向构造函数添加新值和方法。

# Javascript 中的 DOM 是什么

DOM 是文档对象模型,它是网站的面向对象的表示形,可以使用 Javascript 进行修改

  • getElementById() - 通过 id 属性选择一个元素
  • getElementsByName() - 通过 name 属性选择一个元素
  • getElementsByTagName() - 选择所选标签的所有元素,
  • getElementsbyClassName() - 选择特定类名的所有元素
  • querySelector() - 通过 CSS 选择器选择元素。

Javascript  还提供了其他操作元素的方法,而不仅仅是获取元素,比如appendChild()innerHTML()

# 不要再用这么多 div 了,试试语义化标签

页面的最顶层通常分为三个区域:headermainfooter,这些区域还可以进一步划分成不同的 section

HTML <header> 元素用于展示介绍性内容,通常包含一组介绍性的或是辅助导航的实用元素。它可能包含一些标题元素,但也可能包含其他元素,比如 Logo、搜索框、作者名称,等等。
<header> 元素不是分段内容,因此不会往 大纲 中引入新的段落。也就是说,<header> 元素通常用于包含周围部分的标题(h1 至 h6 元素),但这不是必需的。

HTML <footer> 元素表示最近一个章节内容或者根节点(sectioning root )元素的页脚。一个页脚通常包含该章节作者、版权数据或者与文档相关的链接等信息。

# main

在文档中,<main> 元素的内容应当是独一无二的。任何同时存在于任意一系列文档中的相同、重复内容,比如侧边栏、导航栏链接、版权信息、网站 Logo,搜索框(除非搜索框为文档的主要功能),都不应当被包含在其内。
<main> 对文档的大纲(outline)没有贡献;也就是说,它与诸如 <body> 之类的元素,诸如 <h2>之类的标题等不同,<main> 不会影响 DOM 的页面结构概念。它仅有提供信息的作用。
因此 <main> 中放置的是一个页面里好的、重要的内容,它是用户为什么 访问这个页面的主要原因,而不是你的站点。换句话说,主要内容

一个文档中最多只能有一个 <main> 元素。如果文档中包含多个 <main> 元素,则其他的必须使用 hidden 属性 隐藏

# section

结构上来说,它基本上就是一个具有特殊的语义的<div>

<section> 不是通用容器元素。如果这是为了样式目的或方便编写脚本代码,那么鼓励开发者使用 <div>。一般规则是,如果元素内容需要出现在文档 大纲 中,那么这些内容就要使用 <section> 元素包装

# article

HTML <article>元素表示文档、页面、应用或网站中的独立结构,其意在成为可独立分配的或可复用的结构,如在发布中,它可能是论坛帖子、杂志或新闻文章、博客、用户提交的评论、交互式组件,或者其他独立的内容项目。​​

<article> 都要有一个标题,来标识它的含义,最好使用标题元素(<h1>~<h6>)。<article> 元素中可以包含 <header>、<footer> 和 <section> 元素,因此你确实可以用它在另一个页面中嵌入完整的文档片段及其需要的所有结构。

这个元素比其他元素更出名。因为 <nav> 是为了清楚地标识页面上的主要导航块,帮助用户导航到网站的其他部分(比如站点地图或 <header>中的链接列表)或导航当前页面(比如标识目录)。

# address

# a 标签

back

超级链接 a 的 target 属性已经是不被新规范支持了,其值有四个保留字:

  • 1._blank <a href="document.html" target="_blank">my document</a>浏览器会另开一个新窗口显示 document.html 文档
  • 2._parent <a href="document.html" target="_parent">my document</a>指向父 frameset 文档
  • 3._self <a href="document.html" target="_self">my document</a>把文档调入当前页框
  • 4._top <a href="document.html" target="_top">my document</a>去掉所有页框并用 document.html 取代 frameset 文档

# Web 中的图像技术全面总结

可以是HTML <img>,也可以是通过CSS背景生成的图片,也可以是SVG <image>。选择正确的技术很重要,并且可以在性能和可访问性方面发挥巨大作用。

# 1.4 响应式图片

<img src="small.jpg" srcset="medium.jpg 500w, large.jpg 800w" alt="" />
1

另一种选择是使用 <picture> 元素。我更喜欢这种方式,因为它更容易预测。

# 1.5 调整图片的大小

object-fit 的可能值为:fill,contain,cover,none,scale-down

# 2.1 如何使用 CSS 背景图片

多背景

.element {
  background: url("cool-1.jpg"), url("cool-2.jpg");
}
1
2
3

# 2.3 隐藏图片

我们可以在特定的视口上隐藏和显示图片,而不会让图片被下载。如果图片没有用 CSS 设置,就不会被下载。这是比使用 <img> 更多的好处。

@media (min-width: 700px) {
  .element {
    background: url("cool-1.jpg");
  }
}
1
2
3
4
5

# Web 中的图像技术全面总结-SVG

SVG 被认为是图像,它的最大功能在于缩放而不影响质量。另外,使用 SVG,我们可以嵌入 JPG,PNG 或 SVG 图像。请参见下面的 HTML:

<svg width="200" height="200">
  <image
    href="cheesecake.jpg"
    height="100%"
    width="100%"
    preserveAspectRatio="xMidYMid slice"
  />
</svg>
1
2
3
4
5
6
7
8

你是否注意到了 prepareAspectRatio?这样一来,可以使图像占据 SVG 的整个宽度和高度,而不会被拉伸或压缩。
非常类似于 CSS 中的 object-fit:coverbackground-size:cover

# html 字符实体如&nbsp

显示结果 描述 实体名称 实体编号
空格 &nbsp; &#160;
< 小于号 &lt; &#60;
> 大于号 &gt; &#62;
& 和号 &amp; &#38;
" 引号 &quot; &#34;
' 撇号 &apos;(IE 不支持) &#39;
分(cent) &cent; &#162;
£ 镑(pound) &pound; &#163;
¥ 元(yen) &yen; &#165;
欧元(euro) &euro; &#8364;
§ 小节 &sect; &#167;
© 版权(copyright) &copy; &#169;
® 注册商标 &reg; &#174;
商标 &trade; &#8482;
× 乘号 &times; &#215;
÷ 除号 &divide; &#247;

# 浏览器存储问题

返回顶部

  • localStorage - 没有时间限制的数据存储
  • sessionStorage - 针对一个 session 的数据存储

之前,这些都是由 cookie 完成的。但是 cookie 不适合大量数据的存储(cookie中每条cookie的存储空间为4k,localStorage中一般浏览器支持的是5M大小),因为它们由每个对服务器的请求来传递,这使得 cookie 速度很慢而且效率也不高
对于不同的网站,数据存储于不同的区域,并且一个网站只能访问其自身的数据

  • localStorage 拓展了 cookie 的 4K 限制
  • 目前所有的浏览器中都会把 localStorage 的值类型限定为 string 类型,这个在对我们日常比较常见的 JSON 对象类型需要一些转换
  • localStorage 本质上对字符串的读取,如果存储内容对的话会消耗内存空间,会导致页面变卡
  • localStorage 不能被爬虫抓取到
  • localStorage 在浏览器的隐私模式下面是不可读取的

localStorage 和 sessionStorage 的唯一区别是 localStorage 没有时间限制。第二天、第二周或下一年之后,数据依然可用,属于永久性存储,而 sessionStorage 属于当会话结束的时候,sessionStorage 中的键值对会被清空
首先使用 localStorage 的时候,我们需要判断浏览器是否支持 localStorage 这个属性

if(!window.localStorage){
            alert("浏览器支持localstorage");
            return false;
        }else{
            //主逻辑业务
}
1
2
3
4
5
6

locaStorage 的写入有三种方法,分别是:

if (!window.localStorage) {
  alert("浏览器不支持localStorage");
} else {
  var storage = window.localStorage;
  // 写入a字段
  storage["a"] = 1;
  // 写入b字段
  storage.b = 2;
  // 写入c字段
  storage.setItem("c", 3); //官方推荐使用
  console.log(typeof storage["a"]);
  console.log(typeof storage["b"]);
  console.log(typeof storage["c"]);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

注意:
localStorage 的使用也是遵循同源策略,不同的网站是不能直接共用相同的 localStorage 的 不知道各位读者有没有注意到,刚刚存储进去的是 int 类型,但是打印出来却是 string 类型,这个与 localStorage 本身的特点有关,localStorage 只支持 string 类型的存储

if (!window.localStorage) {
  alert("浏览器不支持localStorage");
} else {
  var storage = window.localStorage;
  // 写入a字段
  storage["a"] = 1;
  // 写入b字段
  storage.b = 2;
  // 写入c字段
  storage.setItem("c", 3);
  console.log(typeof storage["a"]);
  console.log(typeof storage["b"]);
  console.log(typeof storage["c"]);
  // 第一种读取方法
  var a = storage.a;
  console.log(a);
  // 第二种读取方法
  var b = storage["b"];
  console.log(b);
  // 第三种读取方法
  var c = storage.getItem("c"); //官方推荐使用
  console.log(c);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

改的方法其实很简单,相当于直接赋值

if(!window.localStorage){
    alert("浏览器不支持localStorage");
}else{
    var storage = window.localStorage;
    // 写入a字段
    storage["a"] = 1;
    // 写入b字段
    storage.b = 2;
    // 写入c字段
    storage.setItem("c",3);
    console.log(typeof storage["a"]);
    /*console.log(typeof storage["b"]);
    console.log(typeof storage["c"]);*/
    // 相当于直接赋值
    storage.a = 4;
console.log(storage.a);   // 4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

删除的方法有两种情况,

  • 将 localStorage 的所有内容清除
var storage = window.localStorage;
storage.a = 1;
storage.setItem("c", 3);
console.log(storage); //Storage {a: "1", c: "3", length: 2}
storage.clear(); //删除方法
console.log(storage); //Storage {length: 0}
1
2
3
4
5
6
  • 将 localStorage 中的某个键值对删除
var storage = window.localStorage;
storage.a = 1;
storage.setItem("c", 3);
console.log(storage); //Storage {a: "1", c: "3", length: 2}
storage.removeItem("a"); //删除方法
console.log(storage); //Storage {c: "3", length: 1}
1
2
3
4
5
6

loaclStorage 的键获取
使用 key()方法,向 storage 的数组中通过索引获取键值对的值

var storage = window.localStorage;
storage.a = 1;
storage.setItem("c", 3);
for (var i = 0; i < storage.length; i++) {
  var key = storage.key(i);
  console.log(key);
}
1
2
3
4
5
6
7

# loaclStorage 的类型转化事项

一般我们会将 JSON 存入 localStorage 中,但是在 localStorage 会自动将其转换成 string 类型
使用 JSON.stringify()方法将 JSON 转换为 JSON 字符串

if (!window.localStorage) {
  alert("浏览器不支持localStorage");
} else {
  var storage = window.localStorage;
  var data = {
    username: "lisi",
    password: "123456",
  };
  // JSON转化为字符串
  var b = JSON.stringify(data);
  // 写入到localStorage中
  storage.setItem("data", b);
  console.log(storage.data);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

使用 JSON.parseIn()方法,将读取之后的 JSON 字符串转化成 JSON 对象的形式

if (!window.localStorage) {
  alert("浏览器不支持localStorage");
} else {
  var storage = window.localStorage;
  var data = {
    username: "lisi",
    password: "123456",
  };
  // JSON转化为字符串
  var b = JSON.stringify(data);
  // 写入到localStorage中
  storage.setItem("data", b);
  console.log(storage.data);
  // 将JSON字符串转化成JSON对象
  var json = storage.getItem("data");
  var jsonObj = JSON.parse(json);
  console.log(typeof jsonObj);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  • 在执行登录按钮的方法上添加
// 如果用户名和密码验证成功,此时把用户输入的值存储到localStorage中
//存储localStorage,key值:username,value:用户名
localStorage.setItem("username", $scope.username);
//存储localStorage,key值:password,value:密码
localStorage.setItem("password", $scope.password);
1
2
3
4
5
  • 然后页面在加载的时候,从 localStorage 中读取出用户名和密码
//循环遍历,取key值username和password的value
for (var i = localStorage.length - 1; i >= 0; i--) {
  if (localStorage.key(i) == "username") {
    $scope.username = localStorage.getItem(localStorage.key(i));
  }
  if (localStorage.key(i) == "password") {
    $scope.password = localStorage.getItem(localStorage.key(i));
  }
}
1
2
3
4
5
6
7
8
9
  • 创建 cookie

一行代码介绍如何创建和修改一个 cookie

document.cookie = "username=Darren";
1
  • 读取 cookie
function getCookie(c_name) {
  if (document.cookie.length > 0) {
    //先查询cookie是否为空,为空就return ""
    c_start = document.cookie.indexOf(c_name + "="); //通过String对象的indexOf()来检查这个cookie是否存在,不存在就为 -1
    if (c_start != -1) {
      c_start = c_start + c_name.length + 1; //最后这个+1其实就是表示"="号啦,这样就获取到了cookie值的开始位置
      c_end = document.cookie.indexOf(";", c_start); //其实我刚看见indexOf()第二个参数的时候猛然有点晕,后来想起来表示指定的开始索引的位置...这句是为了得到值的结束位置。因为需要考虑是否是最后一项,所以通过";"号是否存在来判断
      if (c_end == -1) c_end = document.cookie.length;
      return unescape(document.cookie.substring(c_start, c_end)); //通过substring()得到了值。想了解unescape()得先知道escape()是做什么的,都是很重要的基础,想了解的可以搜索下,在文章结尾处也会进行讲解cookie编码细节
    }
  }
  return "";
}
1
2
3
4
5
6
7
8
9
10
11
12
13

当然想实现读取 cookie 的方法还有不少,比如数组,正则等,这里就不往细说了。

  • 设置 cookie 的有效期
document.cookie = "name=value;expires=date";
1

上面代码中的 date 值为 GMT(格林威治时间)格式的日期型字符串,生成方式如下:

var _date = new Date();
_date.setDate(_date.getDate() + 30);
_date.toGMTString();
1
2
3

默认情况下,只有与创建 cookie 的页面在同一个目录或子目录下的网页才可以访问,这个是因为安全方面的考虑,造成不是所有页面都可以随意访问其他页面创建的 cookie。举个例子:

  • 在 "http://www.cnblogs.com/Darren_code/" 这个页面创建一个 cookie,那么在"/Darren_code/"这个路径下的页面如: "http://www.cnblogs.com/Darren_code/archive/2011/11/07/Cookie.html"这个页面默认就能取到cookie信息。
  • 可在默认情况下, "http://www.cnblogs.com"或者 "http://www.cnblogs.com/xxxx/" 就不可以访问这个 cookie
document.cookie = "name=value;path=path";
document.cookie = "name=value;expires=date;path=path";
1
2

红色字体 path 就是 cookie 的路径,最常用的例子就是让 cookie 在跟目录下,这样不管是哪个子页面创建的 cookie,所有的页面都可以访问到了:

document.cookie = "name=Darren;path=/";
1

路径能解决在同一个域下访问 cookie 的问题,咱们接着说 cookie 实现同域之间访问的问题。语法如下:

document.cookie = "name=value;path=path;domain=domain";
1

红色的 domain 就是设置的 cookie 域的值。

例如 "www.qq.com" 与 "sports.qq.com" 公用一个关联的域名"qq.com",我们如果想让 "sports.qq.com" 下的 cookie 被 "www.qq.com" 访问,我们就需要用到 cookie 的 domain 属性,并且需要把path属性设置为 "/"。例:

document.cookie = "username=Darren;path=/;domain=qq.com";
1

注:一定的是同域之间的访问,不能把 domain 的值设置成非主域的域名。

在输入 cookie 信息时不能包含空格,分号,逗号等特殊符号,而在一般情况下,cookie 信息的存储都是采用未编码的方式。所以,在设置 cookie 信息以前要先使用 escape()函数将 cookie 值信息进行编码,在获取到 cookie 值得时候再使用 unescape()函数把值进行转换回来。如设置 cookie 时:

document.cookie = name + "=" + escape(value);
1

再看看基础用法时提到过的 getCookie()内的一句:

return unescape(document.cookie.substring(c_start, c_end));
1

这样就不用担心因为在 cookie 值中出现了特殊符号而导致 cookie 信息出错了。