html5学习笔记

html5学习笔记

html5是html的最新版本,2014年由W3C指定。

html5指定的目的是在移动设备上提供多媒体支持。

html5

html5简介

html5是下一代html标准。
html4.01诞生于1999年。

html5新特性:

  • canvas
  • video,audio
  • 更好的支持本地离线存储。
  • 新的语义容器:article,footer,header,nav,section等等。
  • 新的表单控件:calendar,date,time,email,url,search等等。

html5的声明必须使用:

1
<!DOCTYPE html>

html5文档实例:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<title>文档标题</title>
</head>

<body>
</body>

</html>

html5的改进

  • 新元素
  • 新属性
  • 完全支持css3
  • video,audio
  • 2D、3D制图
  • 本地存储
  • 本地sql数据
  • web应用

html5多媒体

video和audio元素。

html5应用

  • 本地数据存储
  • 访问本地文件
  • 本地sql数据
  • 缓存引用
  • js worker
  • XHTMLHttpRequest2

html5图形

  • canvas
  • 内联svg
  • css3 2D转换,3D转换

html5使用css3

  • 新选择器
  • 新属性
  • 动画
  • 2D、3D转换
  • 圆角
  • 阴影
  • 可下载字体

语义元素

html5添加了很多语义元素:

html5表单

新表单元素,新属性,新输入类型,自动验证。

已删除的元素

以下的4.01中的元素在html5已经被删除。

  • acronym
  • applet
  • basefont
  • big
  • center
  • dir
  • font
  • frame
  • frameset
  • noframes
  • strike

html5浏览器支持

IE9以下的版本兼容html5的方法,使用html5shiv包:

1
2
3
<!--[if lt IE 9]>
<script src="http://cdn.static.runoob.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<![endif]-->

载入后,初始化新标签的css:

1
2
3
4
5
6
7
8
9
10
11
article,
aside,
dialog,
footer,
header,
section,
nav,
figure,
menu {
display: block;
}

html5浏览器支持

可以让一些老旧的浏览器支持html5。

现代浏览器都支持html5.
浏览器对于无法识别的元素都会作为内联元素处理。

将html5元素定义为块元素

html5定义了8个语义元素,这些元素都是块级元素。

为了让旧的浏览器正确显示,可以设置css:

1
2
3
4
5
6
7
8
9
10
header,
section,
footer,
aside,
nav,
main,
article,
figure {
display: block;
}

自定义新元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<title>为 HTML 添加新元素</title>
<script>
document.createElement("myHero")
</script>
<style>
myHero {
display: block;
background-color: #ddd;
padding: 50px;
font-size: 30px;
}
</style>
</head>

<body>
<h1>我的第一个标题</h1>
<p>我的第一个段落。</p>
<myHero>我的第一个新元素</myHero>
</body>

</html>

IE浏览器问题

以上的方法可以为IE浏览器添加html5元素,但是不支持IE8及更早的版本。

我们可以使用 Sjoerd Visscher 创建的 “HTML5 Enabling JavaScript”, “ shiv” 来解决该问题:

1
2
3
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

上面的作用是对于IE9以下的版本读取html5.js文件并解析。

1
2
3
<!--[if lt IE 9]>
<script src="http://cdn.static.runoob.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<![endif]-->

针对IE浏览器html5shiv 是比较好的解决方案。html5shiv主要解决HTML5提出的新的元素不被IE6-8识别,这些新元素不能作为父节点包裹子元素,并且不能应用CSS样式。

完美的shiv解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<title>渲染 HTML5</title>
<!--[if lt IE 9]>
<script src="http://cdn.static.runoob.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<![endif]-->
</head>

<body>
<h1>我的第一篇文章</h1>
<article>
菜鸟教程 —— 学的不仅是技术,更是梦想!!!
</article>
</body>

</html>

html5新元素和移除的元素

html5新元素

新的多媒体元素:

  • canvas:定义图形,基于js的绘图API。
  • video:定义视频。
  • audio:定义音频。
  • source:定义video和audio的文件源。
  • embed:定义嵌入的内容,比如插件。
  • track:为video和audio之类的元素的媒介规定外部文本轨道。

新的表单元素:

  • datalist:定义选项列表,与input配合使用。
  • keygen:规定用于表单的秘钥的生成器字段。
  • output:定义不同类型的输出,比如脚本的输出。

新的语义容器和结构元素:

  • article:定义页面独立的内容区域。
  • aside:定义页面的侧边栏内容。
  • bdi:设置文本方向。
  • command:定义命令按钮,比如单选按钮、复选框、按钮。
  • details:用于描述文档的细节。
  • dialog:对话框。
  • summary:包含details元素的标题。
  • figure:图像、图标、照片、代码。
  • fugcaption:定义figure元素的标题。
  • footer:定义全局或局部的页脚。
  • header:定义文档头部。
  • mark:定义标记文本。
  • meter:定义度量。
  • nav:定义导航链接部分。
  • progress:定义任务进度。
  • ruby:定义ruby注释(中文注音或字符)。
  • rt:定义字符的解释或者发音。
  • rp:在 ruby 注释中使用,定义不支持 ruby 元素的浏览器所显示的内容。
  • section:定义文档中的节。
  • time:定义日期或者时间。
  • wbr:在文本合适的地方添加换行符。

html5已经移除的元素

  • acronym
  • applet
  • basefont
  • big
  • center
  • dir
  • font
  • frame
  • frameset
  • noframes
  • strike
  • tt

canvas

详细教程:https://www.runoob.com/w3cnote/html5-canvas-intro.html

canvas标签定义图形,canvas标签只是图形容器,图形需要靠js脚本绘制。

可以使用js在canvas中绘制路径、盒、圆、字符、图像。

创建画布

canvas画布是一个矩形框,默认没有边框和内容。
需要制定一个id,width和height。
一个页面可以有多个canvas。

1
<canvas id="mycanvas" width="200" height="100" style="border: 1px red solid;"></canvas>

使用js开始绘图

1
2
3
4
5
6
7
8
// 首先获得画布
var c = document.getElementById("mycanvas");
// 获得画布的context对象
var ctx = c.getContext("2d");
// 填充样式,可以有颜色、渐变、图案
ctx.fillStyle = "#f00";
// 填充一个矩形,x,y,width,height
ctx.fillRect(0, 0, 150, 75);

canvas坐标

canvas是一个二维网络,左上角为(0, 0)。

canvas路径

使用以下方法画线:

  • moveTo(x, y)定义线条开始坐标
  • lineTo(x, y)定义线条结束坐标
  • stroke()绘制线条

实例:绘制直线

1
2
3
4
5
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.moveTo(0, 0);
ctx.lineTo(200, 100);
ctx.stroke();

实例:绘制圆形

1
2
3
4
5
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(95, 50, 40, 0, 2 * Math.PI);
ctx.stroke();

canvas绘制文本

使用canvas绘制文本的属性和方法如下:

  • font,定义字体
  • fillText(text, x, y),绘制实心文本
  • strokeText(text, x, y),在canvas上绘制空心文本

实例:绘制实心文本

1
2
3
4
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Hello World", 10, 50);

实例:绘制空心文本

1
2
3
4
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.font = "30px Arial";
ctx.strokeText("Hello World", 10, 50);

canvas渐变

渐变可以用于填充矩形、圆形、线条、文本等等。

canvas渐变的方法:

  • createLinearGradient(x, y, x1, y1),创建线性渐变。
  • createRadialGradient(x, y, r, x1, y1, r1),创建径向渐变。

使用渐变必须使用两种及以上的颜色。。
addColorStop()方法指定颜色停止,参数用坐标描述,0-1。
再设置fillStyle()或者strokeStyle()的值为渐变,然后绘制形状。

实例:createLinearGradient()

1
2
3
4
5
6
7
8
9
10
11
var c = document.getElementById("mycanvas");
var ctx = c.getContext("2d");

// 创建渐变
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, "red");
grd.addColorStop(1, "white");

// 填充
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 150, 80);

实例:createRadialGradient()

1
2
3
4
5
6
7
8
9
10
11
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

// 创建渐变
var grd = ctx.createRadialGradient(75, 50, 5, 90, 60, 100);
grd.addColorStop(0, "red");
grd.addColorStop(1, "white");

// 填充渐变
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 150, 80);

canvas绘制图片

把一张图片放到canvas中,使用drawImage(image, x, y)

1
2
3
4
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("scream");
ctx.drawImage(img, 10, 10);

内联svg

html5支持内联svg。

svg是可伸缩矢量图形。
svg的特点是:

  • svg用于网络
  • svg使用XML格式定义图形
  • svg放大缩小图形质量都不会损失
  • svg是万维网联盟的标准

svg的优势:

  • svg可以通过编辑器创建和修改
  • svg可以被搜索、索引、脚本化、压缩
  • svg可伸缩
  • svg可以在任何分辨率下打印
  • svg可以再质量不损失的情况下放大

将svg嵌入html页面

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>

<body>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="190">
<polygon points="100,10 40,180 190,60 10,60 160,180" style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;">
</svg>

</body>

</html>

svg和canvas的区别

svg是使用xml描述2d图形的语言,svg基于xml故而可以使用js处理svg事件,适合有大型渲染区域的应用(地图),不适合游戏。
canvas是一个画布,通过使用js绘制2d图形,是逐像素渲染的,不支持事件处理,文本渲染能力弱,能够直接保存图像,适合图像密集型游戏。

MathML

MathML的标签是 <math></math>

MathML基于xml,是用来在网络上书写数学符号和公式的语言。

MathML代码生成:https://latexlive.com/

拖放(Drag、Drop)

拖放是html5标准的一部分,任何元素都能拖放。

拖放:抓取一个对象后拖到另一个位置。

实例

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE HTML>
<html>

<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#div1 {
width: 350px;
height: 70px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
<script>
function allowDrop(ev) {
ev.preventDefault();
}

function drag(ev) {
ev.dataTransfer.setData("Text", ev.target.id);
}

function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>

<body>

<p>拖动 RUNOOB.COM 图片到矩形框中:</p>

<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img loading="lazy" id="drag1" src="/images/logo.png" draggable="true" ondragstart="drag(event)" width="336" height="69">

</body>

</html>

解析:

  1. 首先,设置元素为可拖动
1
<img draggable="true">
  1. 拖动时的行为,ondragstart和setData()

drag():

1
2
3
function drag(ev) {
ev.dataTransfer.setData("Text", ev.target.id);
}
  1. 放到哪里ondragover

ondragover 事件规定在何处放置被拖动的数据。

默认地,无法将数据/元素放置到其他元素中。如果需要设置允许放置,我们必须阻止对元素的默认处理方式。

这要通过调用 ondragover 事件的 event.preventDefault() 方法:

1
event.preventDefault()
  1. 放置ondrop

当放置的时候回发声drop事件。

1
2
3
4
5
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
  • 调用preventDefault()来避免浏览器对数据的默认处理(drop事件的默认行为是以链接形式打开)
  • 通过 dataTransfer.getData(“Text”)方法获得被拖的数据。该方法将返回在setData()方法中设置为相同类型的任何数据。
  • 被拖数据是被拖元素的id(“drag1”)
  • 把被拖元素追加到放置元素(目标元素中

实例:来回拖动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<style type="text/css">
#div1,
#div2 {
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
<script>
function allowDrop(ev) {
ev.preventDefault();
}

function drag(ev) {
ev.dataTransfer.setData("Text", ev.target.id);
}

function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>

<body>

<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="img_w3slogo.gif" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31"></div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

</body>

</html>

Geolocation(地理定位)

Geolocation(地理定位)用于定位用户的位置(需要获得用户同意)。

获得地理位置

使用getCurrentPosition()方法获得用户位置。

实例:获取用户经纬度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var x = document.getElementById("demo");

function getLocation() {
// 检查是否支持定位
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
// 不支持定位的处理
x.innerHTML = "该浏览器不支持获取地理位置。";
}
}

// 点击按钮的事件
function showPosition(position) {
x.innerHTML = "纬度: " + position.coords.latitude +
"<br>经度: " + position.coords.longitude;
}

实例:在以上的代码中加入错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function showError(error) {
switch (error.code) {
case error.PERMISSION_DENIED:
x.innerHTML = "用户拒绝对获取地理位置的请求。"
break;
case error.POSITION_UNAVAILABLE:
x.innerHTML = "位置信息是不可用的。"
break;
case error.TIMEOUT:
x.innerHTML = "请求用户地理位置超时。"
break;
case error.UNKNOWN_ERROR:
x.innerHTML = "未知错误。"
break;
}
}

在地图中显示结果

需要使用可以使用经纬度的地图服务,谷歌地图或者百度地图:

1
2
3
4
5
6
7
function showPosition(position) {
var latlon = position.coords.latitude + "," + position.coords.longitude;

var img_url = "http://maps.googleapis.com/maps/api/staticmap?center=" +
latlon + "&zoom=14&size=400x300&sensor=false";
document.getElementById("mapholder").innerHTML = "<img src='" + img_url + "'>";
}

给定位置的信息

  • 更新本地信息
  • 显示用户周围的信息
  • GPS

getCurrentPosition()

getCurrentPosition()返回对象:

  • coords.latitude:维度
  • coords.longitude:经度
  • coords.accuracy:精度
  • coords.altitude:海拔
  • coords.altitudeAccuracy:海拔精度
  • coords.heading:方向
  • coords.speed:速度
  • timestamp:相应日期、时间

其他方法

watchPosition():持续返回用户位置。
clearWatch():停止watchPosition()

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var x = document.getElementById("demo");

function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.watchPosition(showPosition);
} else {
x.innerHTML = "该浏览器不支持获取地理位置。";
}
}

function showPosition(position) {
x.innerHTML = "纬度: " + position.coords.latitude +
"<br>经度: " + position.coords.longitude;
}

实例:百度地图获取经纬度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<title></title>
<!--引入百度 API,"ak=" 后面一串码是密钥,最好自己申请-->
<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=7a6QKaIilZftIMmKGAFLG7QT1GLfIncg"></script>
</head>

<body>
<input type="button" onclick="getLocation()" value="确认" />
<div id="position"></div>
<script type="text/javascript">
var x = document.getElementById('position');

function getLocation() {
// 创建百度地理位置实例,代替 navigator.geolocation
var geolocation = new BMap.Geolocation();
geolocation.getCurrentPosition(function(e) {
if (this.getStatus() == BMAP_STATUS_SUCCESS) {
// 百度 geolocation 的经纬度属性不同,此处是 point.lat 而不是 coords.latitude
x.innerHTML = '纬度:' + e.point.lat + '<br/>经度:' + e.point.lng;
} else {
x.innerHTML = 'failed' + this.getStatus();
}
});
}
</script>
</body>

</html>

video

html5提供了显示视频的标准。

使用

1
2
3
4
5
<video width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.ogg" type="video/ogg">
您的浏览器不支持Video标签。
</video>

标签详解:

  • 控件controls
  • width、height属性
  • source元素用于提供多个视频文件,src属性用于指定视频路径。
  • track元素定义文本轨迹

浏览器对于视频格式的支持

  • IE:mp4
  • chrome:mp4、webm、ogg
  • firefox:mp4、webm、ogg
  • safari:mp4
  • opera:mp4、webm、ogg

视频格式的MIME类型:
mp4:video/mp4
webm:video/webm
ogg:video/ogg

使用DOM控制

video和audio元素拥有相同的方法、属性和事件,并且可以使用js控制。

方法用于播放、暂停、加载。
属性(时长、音量等等)可以被读取和设置。
DOM事件通知我视频开始播放、暂停、停止等等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!DOCTYPE html>
<html>

<head> 
<meta charset="utf-8"> 
<title></title> 
</head>

<body>
<div style="text-align:center">
<button onclick="playPause()">播放/暂停</button>
<button onclick="makeBig()">放大</button>
<button onclick="makeSmall()">缩小</button>
<button onclick="makeNormal()">普通</button>
<br>
<video id="video1" width="420">
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.ogg" type="video/ogg">
您的浏览器不支持 HTML5 video 标签。
</video>
</div>
<script>
var myVideo = document.getElementById("video1");

function playPause() {
if (myVideo.paused)
myVideo.play();
else
myVideo.pause();
}

function makeBig() {
myVideo.width = 560;
}

function makeSmall() {
myVideo.width = 320;
}

function makeNormal() {
myVideo.width = 420;
}
</script>
</body>

</html>

audio

html5提供了播放音频的标准audio元素。

使用

1
2
3
4
5
<audio controls>
<source src="horse.ogg" type="audio/ogg">
<source src="horse.mp3" type="audio/mpeg">
您的浏览器不支持 audio 元素。
</audio>

controls属性提供了播放、暂停、音量控件。

可以使用多个source元素提供多个格式。

浏览器对于音频格式的支持

IE:mp3
chrome:mp3、wav、ogg
firefox:mp3、wav、ogg
safari:mp3、wav
opera:mp3、wav、ogg

三种音频格式的MIME类型:
mp3:audio/mpeg
ogg:audio/ogg
wav:audio/wav

新的input类型

  • color
  • date
  • datetime
  • datetime-local
  • email
  • month
  • number
1
数量 ( 1 到 5 之间 ): <input type="number" name="quantity" min="1" max="5">

number类型有以下几种属性可以用:disabled, max, maxlength, min, pattern, readonly, required, size, step, value

  • range
1
<input type="range" name="points" min="1" max="10">

可用的属性:max, min, step, value

  • search
  • tel
  • time
  • url
  • week

新表单元素

  • datalist
  • keygen
  • output

datalist

datalist元素规定输入域的选项列表。

datalist属性规定form或者input域应该拥有自动完成功能,当用户开始输入的时候,浏览器在该域下显示填写的选项。
实例:

1
2
3
4
5
6
7
8
9
<input list="browsers">

<datalist id="browsers">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>

keygen

keygen元素的作用是提供一种验证用户的可靠方法,它规定了用于表单的秘钥对生成器字段。

当提交表单时,会生成两个键,一个是私钥,一个公钥。
私钥(private key)存储于客户端,公钥(public key)则被发送到服务器。公钥可用于之后验证用户的客户端证书。

实例:

1
2
3
4
5
<form action="demo_keygen.asp" method="get">
用户名: <input type="text" name="usr_name">
加密: <keygen name="security">
<input type="submit">
</form>

output

output元素用于不同类型的输出(计算、脚本输出等等):

1
2
3
4
5
<form oninput="x.value=parseInt(a.value)+parseInt(b.value)">0
<input type="range" id="a" value="50">100 +
<input type="number" id="b" value="50">=
<output name="x" for="a b"></output>
</form>

新表单属性

form元素新属性:

  • autocomplete
  • novalidate

input元素新属性:

  • autocomplete
  • autofocus
  • form
  • formaction
  • formenctype
  • formmethod
  • formnovalidate
  • formtarget
  • height, width
  • list
  • min, max
  • multiple
  • pattern (regexp)
  • placeholder
  • required
  • step

autocomplete

autocomplete属性规定了form和input元素的自动完成功能。
当用户开始在元素中输入的时候,浏览器会在域中显示选项。

实例:

1
2
3
4
5
6
<form action="demo-form.php" autocomplete="on">
First name:<input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br>
E-mail: <input type="email" name="email" autocomplete="off"><br>
<input type="submit">
</form>

novalidate

novalidate属性是布尔型,规定了提交表单的时候不应该验证form或者input。

实例:这个表单无需验证

1
2
3
4
<form action="demo-form.php" novalidate>
E-mail: <input type="email" name="user_email">
<input type="submit">
</form>

autofocus

autofocus属性是一个布尔型,规定了在页面加载的时候某个域自动获取焦点。

实例:页面加载的时候,这个input元素会自动获取焦点

1
First name:<input type="text" name="fname" autofocus>

input元素的form属性

form属性规定了输入域所属的一个或者多个表单。

1
2
3
4
5
6
<form action="demo-form.php" id="form1">
First name: <input type="text" name="fname"><br>
<input type="submit" value="提交">
</form>

Last name: <input type="text" name="lname" form="form1">

input元素的formaction属性

formaction属性用于描述表单提交的url地址,该属性会覆盖form元素的action属性。

实例:两个表单提交地址

1
2
3
4
5
6
<form action="demo-form.php">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br>
<input type="submit" value="提交"><br>
<input type="submit" formaction="demo-admin.php" value="提交">
</form>

input元素的formenctype属性

formenctype属性描述了表单提交到服务器的数据编码,会覆盖form元素的enctype属性。
该属性与 type=”submit” 和 type=”image” 配合使用。

实例:

1
2
3
4
5
<form action="demo-post_enctype.php" method="post">
First name: <input type="text" name="fname"><br>
<input type="submit" value="提交">
<input type="submit" formenctype="multipart/form-data" value="以 Multipart/form-data 提交">
</form>

formmethod属性

formmethod属性定义了表单的提交方式,会覆盖form元素的method属性。
该属性可以与 type=”submit” 和 type=”image” 配合使用。

实例:

1
2
3
4
5
6
<form action="demo-form.php" method="get">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br>
<input type="submit" value="提交">
<input type="submit" formmethod="post" formaction="demo-post.php" value="使用 POST 提交">
</form>

formnovalidate属性

formnovalidate属性会覆盖form元素的novalidate属性,与submit一起使用。

实例:

1
2
3
4
5
<form action="demo-form.php">
E-mail: <input type="email" name="userid"><br>
<input type="submit" value="提交"><br>
<input type="submit" formnovalidate value="不验证提交">
</form>

formtarget属性

formtarget属性指定一个名称或者一个关键字来指明表单提交数据后的展示。
formtarget属性会覆盖form元素的target属性。
与submit和image配合使用。

实例:

1
2
3
4
5
6
<form action="demo-form.php">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br>
<input type="submit" value="正常提交">
<input type="submit" formtarget="_blank" value="提交到一个新的页面上">
</form>

width和height属性

用于指定image类型input的高度和宽度。

只能用于image类型的input元素

实例:

1
<input type="image" src="img_submit.gif" alt="Submit" width="48" height="48">

list属性

list属性规定了输入域的datalist,datalist是输入域的选项列表。

实例:

1
2
3
4
5
6
7
8
9
<input list="browsers">

<datalist id="browsers">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>

min和max属性

min、max和step属性用于包含数字的input类型,比如date pickers、number 以及 range。

实例:

1
2
3
4
5
6
7
8
Enter a date before 1980-01-01:
<input type="date" name="bday" max="1979-12-31">

Enter a date after 2000-01-01:
<input type="date" name="bday" min="2000-01-02">

Quantity (between 1 and 5):
<input type="number" name="quantity" min="1" max="5" step="1">

multiple属性

multiple属性是布尔型属性。

multiple属性规定了input元素可选择多个值,用于email和file类型。

实例:上传多个文件

1
Select images: <input type="file" name="img" multiple>

pattern属性

描述了一个正则表达式用于验证input的value,适用类型有text、search、url、tel、email、password。

实例:

1
Country code: <input type="text" name="country_code" pattern="[A-Za-z]{3}" title="Three letter country code">

placeholder属性

placeholder属性在输入域提供了提示信息。
适用于text, search, url, telephone, email 以及 password。

1
<input type="text" name="fname" placeholder="First name">

required属性

required属性是一个布尔型属性。
带有required属性的输入域必须要填写。
使用类型:ext, search, url, telephone, email, password, date pickers, number, checkbox, radio 以及 file。

1
Username: <input type="text" name="usrname" required>

语义元素

语义元素:有意义的元素,能够清楚地描述其意义以及给浏览器和开发者提示。

新的语义容器

  • header
  • nav
  • article
  • section
  • aside
  • figcaption
  • figure
  • footer

section元素

section元素定义了文档中的节,比如章节、页眉或者其他部分。

实例:

1
2
3
4
<section>
<h1>WWF</h1>
<p>The World Wide Fund for Nature (WWF) is....</p>
</section>

article元素

article元素定义独立的内容。

实例:

1
2
3
4
<article>
<h1>Internet Explorer 9</h1>
<p>Windows Internet Explorer 9(缩写为 IE9 )在2011年3月14日21:00 发布。</p>
</article>

nav元素定义了导航链接部分,不是所有的连接都包含在nav元素中。

实例:

1
2
3
4
5
6
<nav>
<a href="/html/">HTML</a> |
<a href="/css/">CSS</a> |
<a href="/js/">JavaScript</a> |
<a href="/jquery/">jQuery</a>
</nav>

aside元素

aside元素定义了主内容区域之外的内容(侧边栏),且与主内容相关。

实例:

1
2
3
4
5
6
<p>My family and I visited The Epcot center this summer.</p>

<aside>
<h4>Epcot Center</h4>
<p>The Epcot Center is a theme park in Disney World, Florida.</p>
</aside>

header元素

header定义了文档头部区域,一个文档里可以有多个header。

实例:

1
2
3
4
5
6
7
<article>
<header>
<h1>Internet Explorer 9</h1>
<p><time pubdate datetime="2011-03-15"></time></p>
</header>
<p>Windows Internet Explorer 9(缩写为 IE9 )是在2011年3月14日21:00发布的</p>
</article>

footer元素

footer定义了文档的底部区域,通常有连接、作者信息、版权等信息。

1
2
3
4
<footer>
<p>Posted by: Hege Refsnes</p>
<p><time pubdate datetime="2012-03-01"></time></p>
</footer>

figure和figcaption元素

figure元素规定了一个独立的内容区域(图片,表格,代码等)。
figure元素的内容应该与主内容相关,但如果被删除,则不应对文档流产生影响。
figcaption元素规定了figure元素的标题,一般放在figure元素中的最后面。

实例:

1
2
3
4
<figure>
<img loading="lazy" src="img_pulpit.jpg" alt="The Pulpit Rock" width="304" height="228">
<figcaption>Fig1. - The Pulpit Pock, Norway.</figcaption>
</figure>

旧版本浏览器兼容

对于不支持html5新元素的浏览器:

1
2
3
4
5
6
7
8
9
header,
section,
footer,
aside,
nav,
article,
figure {
display: block;
}

对于IE8以及更早的版本:

使用HTML5 Shiv Javascript脚本,放入html中:

1
2
3
<!--[if lt IE 9]>
<script src="html5shiv.js"></script>
<![endif]-->

上面的代码需要放在head元素中。

html5 web存储

html5 web存储是比cookie更好的本地存储方式。
html5 web存储可以在本地存储用户的浏览数据。
数据以key/value的形式存在,只对该网页开放使用。

localStorage和sessionStorage对象

客户端存储数据的两个对象是:

  • localStorage:用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去除。
  • sessionStorage:用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。

检查浏览器是否支持这两个对象:

1
2
3
4
5
6
if (typeof(Storage) !== "undefined") {
// 是的! 支持 localStorage sessionStorage 对象!
// 一些代码.....
} else {
// 抱歉! 不支持 web 存储。
}

localStorage对象

localStorage对象存储的数据没有时间限制。

实例:

1
2
3
4
5
6
// 存储一组键值对
localStorage.sitename = "菜鸟教程";
// 查找一组键值对并写入一个元素中
document.getElementById("result").innerHTML = "网站名:" + localStorage.sitename;
// 删除一组键值对
localStorage.removeItem("sitename");

localStorage对象中的数据都是键值对,sitename是一个key,菜鸟教程是一个值。

localStorage和sessionStorage可使用的API都是一样的,常用的:

  • localStorage.setItem(key, value),保存一组键值对。
  • localStorage.getItem(key),读取一个key的value。
  • localStorage.removeItem(key),删除一组键值对。
  • localStorage.clear(),删除所有数据。
  • localStorage.key(index),查询某个index的key。

键值对通常是以字符串存储。

实例:点击转化字符串为数字

1
2
3
4
5
6
7
if (localStorage.clickcount) {
// 类型转换
localStorage.clickcount = Number(localStorage.clickcount) + 1;
} else {
localStorage.clickcount = 1;
}
document.getElementById("result").innerHTML = " 你已经点击了按钮 " + localStorage.clickcount + " 次 ";

sessionStorage对象

sessionStorage仅用于session会话,关闭标签后数据删除。

实例:

1
2
3
4
5
6
if (sessionStorage.clickcount) {
sessionStorage.clickcount = Number(sessionStorage.clickcount) + 1;
} else {
sessionStorage.clickcount = 1;
}
document.getElementById("result").innerHTML = "在这个会话中你已经点击了该按钮 " + sessionStorage.clickcount + " 次 ";

html5 web sql数据库

web sql是一个独立的规范,引入了一组使用sql操作客户端数据库的API。
web sql数据库可以再safari、chrome和opera中运行。

核心方法

  • openDatabase:使用现有的数据库或者新建的数据库创建一个数据库对象。
  • transaction:用于控制一个事务以及基于这种情况执行提交或者回滚。
  • executeSql:执行sql查询。

打开数据库

使用openDatabase()打开已存在的数据库,若不存在则会创建一个新的数据库:

1
2
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
参数依次是: 数据库名称、 版本号、 描述文本、 数据库大小、 创建回调

执行查询

执行操作使用 database.transaction() 函数:

1
2
3
4
5
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
db.transaction(function(tx) {
// 创建了一个名为LOGS的表
tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
});

插入数据

在上面的基础上插入数据:

1
2
3
4
5
6
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
db.transaction(function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "菜鸟教程")');
tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "www.runoob.com")');
});

动态值插入数据:

1
2
3
4
5
6
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
db.transaction(function(tx) {
// e_id 和 e_log 是外部变量,executeSql 会映射数组参数中的每个条目给 "?"。
tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
tx.executeSql('INSERT INTO LOGS (id,log) VALUES (?, ?)', [e_id, e_log]);
});

读取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);

db.transaction(function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "菜鸟教程")');
tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "www.runoob.com")');
});

db.transaction(function(tx) {
tx.executeSql('SELECT * FROM LOGS', [], function(tx, results) {
var len = results.rows.length,
i;
msg = "<p>查询记录条数: " + len + "</p>";
document.querySelector('#status').innerHTML += msg;

for (i = 0; i < len; i++) {
alert(results.rows.item(i).log);
}

}, null);
});

完整实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
var msg;

db.transaction(function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "菜鸟教程")');
tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "www.runoob.com")');
msg = '<p>数据表已创建,且插入了两条数据。</p>';
document.querySelector('#status').innerHTML = msg;
});

db.transaction(function(tx) {
tx.executeSql('SELECT * FROM LOGS', [], function(tx, results) {
var len = results.rows.length,
i;
msg = "<p>查询记录条数: " + len + "</p>";
document.querySelector('#status').innerHTML += msg;

for (i = 0; i < len; i++) {
msg = "<p><b>" + results.rows.item(i).log + "</b></p>";
document.querySelector('#status').innerHTML += msg;
}
}, null);
});

删除记录

1
2
3
db.transaction(function(tx) {
tx.executeSql('DELETE FROM LOGS WHERE id=1');
});

删除动态id的数据:

1
2
3
db.transaction(function(tx) {
tx.executeSql('DELETE FROM LOGS WHERE id=?', [id]);
});

更新记录

1
2
3
db.transaction(function(tx) {
tx.executeSql('UPDATE LOGS SET log=\'www.w3cschool.cc\' WHERE id=2');
});

更新动态id的数据:

1
2
3
db.transaction(function(tx) {
tx.executeSql('UPDATE LOGS SET log=\'www.w3cschool.cc\' WHERE id=?', [id]);
});

完整实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
var msg;

db.transaction(function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "菜鸟教程")');
tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "www.runoob.com")');
msg = '<p>数据表已创建,且插入了两条数据。</p>';
document.querySelector('#status').innerHTML = msg;
});

db.transaction(function(tx) {
tx.executeSql('DELETE FROM LOGS WHERE id=1');
msg = '<p>删除 id 为 1 的记录。</p>';
document.querySelector('#status').innerHTML = msg;
});

db.transaction(function(tx) {
tx.executeSql('UPDATE LOGS SET log=\'www.w3cschool.cc\' WHERE id=2');
msg = '<p>更新 id 为 2 的记录。</p>';
document.querySelector('#status').innerHTML = msg;
});

db.transaction(function(tx) {
tx.executeSql('SELECT * FROM LOGS', [], function(tx, results) {
var len = results.rows.length,
i;
msg = "<p>查询记录条数: " + len + "</p>";
document.querySelector('#status').innerHTML += msg;

for (i = 0; i < len; i++) {
msg = "<p><b>" + results.rows.item(i).log + "</b></p>";
document.querySelector('#status').innerHTML += msg;
}
}, null);
});

html5应用程序缓存(Application Cache)

通过创建cache manifest 文件,可以创建离线web应用。

应用程序缓存的优势:

  • 可以离线浏览
  • 已缓存的资源加载更快
  • 减少服务器负载

cache manifest实例

1
2
3
4
5
6
7
8
<!DOCTYPE HTML>
<html manifest="demo.appcache">

<body>
文档内容......
</body>

</html>

cache manifest基础

为html标签添加manifest属性即可启用应用程序缓存:

1
2
3
4
5
<!DOCTYPE HTML>
<html manifest="demo.appcache">
...

</html>

指定了manifest的页面都会被缓存。

manifest文件的扩展名为: .appcache

manifest文件的MIME类型为: text/cache-manifest ,要在web服务器上配置。

manifest文件

manifest文件是简单的文本文件,它告诉浏览器被缓存的内容。

manifest文件的三部分:

  • CACHE MANIFEST:在此标题下列出的文件将在首次下载后进行缓存
  • NETWORK:在此标题下列出的文件需要与服务器的连接,且不会被缓存
  • FALLBACK:此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面)

这是一个manifest文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 第一行,CACHE MANIFEST,必需
CACHE MANIFEST
/theme.css
/logo.gif
/main.js

# 联网时下载
NETWORK:
login.php

# 其他所有文件都在联网时下载
NETWORK:
*

# 如果无法联网,则使用文件替换
FALLBACK:
/html/ /offline.html

更新缓存

一旦应用被缓存,它就会保持缓存直到发生下列情况:

  • 用户清空浏览器缓存
  • manifest 文件被修改(参阅下面的提示)
  • 由程序来更新应用缓存

完整的manifest文件

以 “#” 开头的是注释行,但也可满足其他用途。应用的缓存会在其 manifest 文件更改时被更新。如果您编辑了一幅图片,或者修改了一个 JavaScript 函数,这些改变都不会被重新缓存。更新注释行中的日期和版本号是一种使浏览器重新缓存文件的办法。

1
2
3
4
5
6
7
8
9
10
11
CACHE MANIFEST
# 2012-02-21 v1.0.0
/theme.css
/logo.gif
/main.js

NETWORK:
login.php

FALLBACK:
/html/ /offline.html

web workers

ref: http://www.ruanyifeng.com/blog/2018/07/web-worker.html

web workers独立于其他脚本,是运行在后台的js,不影响页面性能。

实例

index.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html>

<head> 
<meta charset="utf-8"> 
<title>菜鸟教程(runoob.com)</title> 
</head>

<body>

<p>计数: <output id="result"></output></p>
<button onclick="startWorker()">开始工作</button>
<button onclick="stopWorker()">停止工作</button>

<p><strong>注意:</strong> Internet Explorer 9 及更早 IE 版本浏览器不支持 Web Workers.</p>

<script>
var w;

function startWorker() {
if (typeof(Worker) !== "undefined") {
if (typeof(w) == "undefined") {
w = new Worker("demo_workers.js");
}
w.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
document.getElementById("result").innerHTML = "抱歉,你的浏览器不支持 Web Workers...";
}
}

function stopWorker() {
w.terminate();
w = undefined;
}
</script>

</body>

</html>

demo_workers.js:

1
2
3
4
5
6
7
8
9
var i = 0;

function timedCount() {
i = i + 1;
postMessage(i);
setTimeout("timedCount()", 500);
}

timedCount();

检测浏览器是否支持web worker

1
2
3
4
5
6
if (typeof(Worker) !== "undefined") {
// 是的! Web worker 支持!
// 一些代码.....
} else {
//抱歉! Web Worker 不支持
}

创建web worker文件

demo_workers.js:

1
2
3
4
5
6
7
8
9
var i = 0;

function timedCount() {
i = i + 1;
postMessage(i);
setTimeout("timedCount()", 500);
}

timedCount();

创建web worker对象

在html页面中调用上面写的demo_workers.js文件:

1
2
3
if (typeof(w) == "undefined") {
w = new Worker("demo_workers.js");
}

给worker添加一个onmessage事件监听器:

1
2
3
w.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};

终止web worker

1
w.terminate();

完整代码

html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>

<body>

<p>计数: <output id="result"></output></p>
<button onclick="startWorker()">开始工作</button>
<button onclick="stopWorker()">停止工作</button>

<p><strong>注意:</strong> Internet Explorer 9 及更早 IE 版本浏览器不支持 Web Workers.</p>

<script>
var w;

function startWorker() {
if (typeof(Worker) !== "undefined") {
if (typeof(w) == "undefined") {
w = new Worker("demo_workers.js");
}
w.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
document.getElementById("result").innerHTML = "抱歉,你的浏览器不支持 Web Workers...";
}
}

function stopWorker() {
w.terminate();
w = undefined;
}
</script>

</body>

</html>

web worker:

1
2
3
4
5
6
7
8
9
var i = 0;

function timedCount() {
i = i + 1;
postMessage(i);
setTimeout("timedCount()", 500);
}

timedCount();

关于DOM

web worker文件位于外部,故而web worker无法访问window、document、parent这几个对象。

服务器发送事件(Server-Sent Events)

html5服务器发送事件允许网页获得服务器的更新,用途:sns更新、新闻更新等等。

Server-Sent 事件指的是网页自动获取来自服务器的更新。

接收Server-Sent事件通知

1
2
3
4
5
6
// 创建一个新的EventSource对象,参数是服务器端处理文件路径
var source = new EventSource("demo_sse.php");
// 出发onmessage事件时更新页面内容
source.onmessage = function(event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};

检测Server-Sent事件支持

1
2
3
4
5
6
if (typeof(EventSource) !== "undefined") {
// 浏览器支持 Server-Sent
// 一些代码.....
} else {
// 浏览器不支持 Server-Sent..
}

服务器端代码

1
2
3
4
5
6
7
8
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

$time = date('r');
echo "data: The server time is: {$time}\n\n";
flush();
?>

EventSource对象

除了onmessage事件,还有onopen,onerror。

websocket

websocket(ws)是html5提供的一种在单个tcp连接上进行全双工通信的协议。

websocket使得服务器可以主动向客户端推送数据,客户端和服务器只要完成一次握手就可以一直保持连接,并且可以双向传输数据。

在websocket之前要想实现服务器向客户端推送数据需要客户端使用ajax轮询,带宽资源消耗较高。

websocket连接建立后,使用send()向服务器发送数据,使用onmessage事件接受服务器返回的数据。

1
var Socket = new webSocket(url, [protocol]);

下面的Socket对象都是这里new的。

websocket属性

属性:

  • Socket.readyState:只读,表示连接状态,0 - 表示连接尚未建立,1 - 表示连接已建立,可以进行通信,2 - 表示连接正在进行关闭,3 - 表示连接已经关闭或者连接不能打开。

  • Socket.bufferedAmount:只读,缓冲区中的字节数。

websocket事件

  • 事件open:Socket.onopen,建立连接时触发。
  • 事件message:Socket.onmessage,客户端接收服务端数据时触发。
  • 事件error:Socket.onerror,通信错误时触发。
  • 事件close:Socket.onclose,连接关闭时触发。

websocket方法

  • Socket.send():发送数据。
  • Socket.close():关闭连接。

websocket实例

websocket通信过程:

  1. 首先,客户端要向服务器发起一个http请求,附加头信息: Upgrade: WebSocket 表明这是这是websocket。
  2. 然后服务器解析头信息后应答。
  3. 这样连接就建立了。
  4. 直到客户端、服务端中一方主动关闭连接。

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE HTML>
<html>

<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>

<script type="text/javascript">
function WebSocketTest() {
if ("WebSocket" in window) {
alert("您的浏览器支持 WebSocket!");

// 打开一个 web socket
var ws = new WebSocket("ws://localhost:9998/echo");

ws.onopen = function() {
// Web Socket 已连接上,使用 send() 方法发送数据
ws.send("发送数据");
alert("数据发送中...");
};

ws.onmessage = function(evt) {
var received_msg = evt.data;
alert("数据已接收...");
};

ws.onclose = function() {
// 关闭 websocket
alert("连接已关闭...");
};
} else {
// 浏览器不支持 WebSocket
alert("您的浏览器不支持 WebSocket!");
}
}
</script>

</head>

<body>

<div id="sse">
<a href="javascript:WebSocketTest()">运行 WebSocket</a>
</div>

</body>

</html>

pywebsocket

客户端代码已经写好了,还差一个服务器端脚本用来处理websocket(需要python环境运行)。

下载pywebsocket:

1
git clone https://github.com/google/pywebsocket.git

执行:

1
2
3
4
5
python setup.py build
sudo python setup.py install

# 查看文档
pydoc mod_pywebsocket

开启服务:

1
2
# pywebsocket/mod_pywebsocket下
sudo python standalone.py -p 9998 -w ../example/

html5代码规范

  • 使用正确的文档声明
1
<!DOCTYPE html>
  • 使用小写元素名

  • 关闭所有标签

  • 关闭空标签

1
<meta charset="utf-8" />
  • 使用小写属性名

  • 属性值

用引号括起来,单引号双引号均可不过风格要统一。

  • 图片属性

图片使用alt和长宽。

  • 空格和等号

等号前后少用空格。

  • 避免一行代码过长

  • 空行和缩进

不要无故添加空行。
为每一个逻辑功能块添加空行,便于阅读。
缩进使用两个空格,不使用tab。
短代码之间不使用不必要的空行和缩进。

  • html和body标签

html5中可以省略这两个标签,不过不推荐。

  • head标签

html5中head可以省略,不过不推荐。

  • 元数据

title元素必须。
charset必须。

  • 注释
1
2
3
4
5
6
<!-- 这是注释 -->

<!--
这是一个较长评论。 这是 一个较长评论。这是一个较长评论。
这是 一个较长评论 这是一个较长评论。 这是 一个较长评论。
-->
  • 样式表
1
<link rel="stylesheet" href="styles.css">
  • 外部js
1
<script src="myscript.js">
  • 使用小写文件名

  • 文件扩展名

html: .html
css: .css
js: .js
.htm 也可以,原因是早起DOS系统扩展名只能支持三个字符。

评论