40

image

1. 认识HTML5

HTML5并不仅仅只是作为HTML标记语言的一个最新版本,更重要的是它制定了Web应用开发的一系列标准,成为第一个将Web做为应用开发平台的HTML语言。

HTML5定义了一系列新元素,如新语义标签、智能表单、多媒体标签等,可以帮助开发者创建富互联网应用,还提供了一系列Javascript API,如地理定位、重力感应、硬件访问等,可以在浏览器内实现类原生应用,甚至结合Canvas我们可开发网页版游戏,同时结合CSS3的过渡、转换、动画等特性,可以极大的增强用户体验,提升开发功能的可应用性。

我们日常讨论的H5其实是一个泛称,它指的是由HTML5 + CSS3 + Javascript等技术组合而成的一个应用开发平台。

2. 语法规范

随着Web技术的更新,HTML也先后经历了HTML4.01XHTML1.0HTML5几个重要的版本,在版本的演变过程中新增或废弃了一些属性,同时对语法规范也做了一些调整,为了能够保证浏览器可以兼容不同版本语法规范的,我们可以使用<!DOCTYPE>指示浏览器应该如何处理我们的HTML

常用的DOCTYPE声明:

1、HTML5

<!DOCTYPE html>

2、HTML 4.01 Strict

4.01的严格版本,该DTD包含所有HTML元素和属性,但不包括展示性的和弃用的元素(比如font)。不允许框架集(Framesets)。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

3、HTML 4.01 Transitional

DTD包含所有HTML元素和属性,包括展示性的和弃用的元素(比如font)。不允许框架集(Framesets)。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

4、HTML 4.01 Frameset

DTD等同于HTML 4.01 Transitional,但允许框架集内容。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">

5、XHTML 1.0 Strict

DTD包含所有HTML元素和属性,但不包括展示性的和弃用的元素(比如font)。不允许框架集(Framesets)。必须以格式正确的XML来编写标记。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

6、XHTML 1.0 Transitional

DTD包含所有HTML元素和属性,包括展示性的和弃用的元素(比如font)。不允许框架集(Framesets)。必须以格式正确的XML来编写标记。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

7、XHTML 1.0 Frameset

DTD等同于XHTML 1.0 Transitional,但允许框架集内容。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

8、XHTML 1.1

DTD等同于XHTML 1.0 Strict,但允许添加模型(例如提供对东亚语系的ruby支持)。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

3. 语义化标签

HTML5提供了新的元素来创建更好的页面结构:
标签 描述
<article> 定义页面独立的内容区域(文章)。
<aside> 定义页面的侧边栏内容(侧边栏)。
<bdi> 允许您设置一段文本,使其脱离其父元素的文本方向设置。
<command> 定义命令按钮,比如单选按钮、复选框或按钮
<details> 用于描述文档或文档某个部分的细节
<dialog> 定义对话框,比如提示框
<summary> 标签包含details元素的标题
<figure> 规定独立的流内容(图像、图表、照片、代码等等)。
<figcaption> 定义<figure>元素的标题
<footer> 定义sectiondocument的页脚。
<header> 定义了文档的头部区域
<mark> 定义带有记号的文本。
<meter> 定义度量衡。仅用于已知最大和最小值的度量。
<nav> 定义导航链接的部分。
<progress> 定义任何类型的任务的进度。
<ruby> 定义ruby注释(中文注音或字符)。
<rt> 定义字符(中文注音或字符)的解释或发音。
<rp> ruby注释中使用,定义不支持ruby元素的浏览器所显示的内容。
<section> 定义文档中的节(section、区段)。
<time> 定义日期或时间。
<wbr> 规定在文本中的何处适合添加换行符。

本质上新语义标签与<div><span>没有区别,只是其具有语义性,使用时除了在HTML结构上需要注意外,其它和普通标签的使用无任何差别,可以理解成<div class="nav">相当于<nav>。不要好奇,它只是一个标签!

尽量避免全局使用headerfooteraside等语义标签。

4. HTML5 浏览器支持

对于目前主流的浏览器来说,都已经支持HTML5了,但是到了Internet Explorer 9IE才开始支持HTML5,对于之前的旧版本,我们就需要考虑到兼容性问题。

1、将 HTML5 元素定义为块元素

HTML5 新增了几个具有语义化的标签,这些标签都是块级元素,在不支持HTML5新标签的浏览器里,会将这些新的标签解析成行内元素(inline)对待,所以我们只需要在初始化的时候将其转换成块元素(block)即可使用。
header, section, footer, aside, nav, main, article, figure {
    display: block; 
}

2、通过 js 动态创建标签

IE9版本以下,并不能正常解析这些新标签,但是却可以识别通过document.createElement('tagName')创建的自定义标签,于是我们的解决方案就是将HTML5的新标签全部通过document.createElement('tagName')来创建一遍,这样IE低版本也能正常解析HTML5新标签了。
<style>
    header,section,nav...{
        display:block;
    }
</style>

<script type="text/javascript">
      document.createElement("header");
      document.createElement("section");
      document.createElement("nav");
                 .
                 .
                 .
</script>

注意:通过document.createElement创建出来的标签时行内元素,所以同样的需要将它们转换成块级元素。

3、Shiv 解决方案

在实际开发中我们更多采用的是通过检测IE浏览器的版本来加载第三方的一个JS库来解决兼容问题,这个库文件会帮自动通过document.createElement('tagName')创建所有HTML5的新标签。针对IE浏览器html5shiv是比较好的解决方案。html5shiv主要解决HTML5提出的新的元素不被IE6-8识别,这些新元素不能作为父节点包裹子元素,并且不能应用CSS样式的问题。

引入本地html5shiv.min.js文件:

<!--[if lte IE 8]>
     <script type="text/javascript" src="html5shiv.min.js"></script>
<![endif]-->

lte:表示小于等于;当浏览器版本小于等于IE8的时候,引用html5shiv.min.js文件。

引入远程静态资源库:

<!--[if lte IE 8]>
  <script src="http://cdn.static.runoob.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<![endif]-->

以上的注释代码只有在IE浏览器下次才会识别里面的内容,其他浏览器直接当注释识别。

完整示例代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>兼容性处理</title>
<!--[if lte IE 8]>
  <script src="http://cdn.static.runoob.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<![endif]-->
</head>
 
<body>
 
<h1>我正在处理兼容性</h1>
 
<article>我在IE下也能显示</article>
 
</body>
</html>

注意:html5shiv.js引用代码必须放在<head>元素中,因为IE浏览器在解析HTML5新元素时需要先加载该文件。

5. 表单

伴随着互联网富应用以及移动开发的兴起,传统的Web表单已经越来越不能满足开发的需求,所以HTML5Web表单方向也做了很大的改进,如拾色器、日期/时间组件等,使表单处理变的更加高效。

5.1 表单控件

html5中新增的一些表单控件,例如email属性的输入框,它可以检测你的输入内容是否符合一个邮箱的格式,自动进行表单校验。

1、表单域:form

我们都知道<form>标签用于为用户输入创建HTML表单。表单能够包含input元素,比如文本字段、复选框、单选框、提交按钮等等。表单还可以包含menustextareafieldsetlegendlabel元素。

表单用于向服务器传输数据。

html5<form>表单域添加了两个新的属性:"autocomplete: no/yes"、"novalidate":

  • autocomplete:规定是否启用表单的自动完成功能,默认on。(自动完成允许浏览器预测对字段的输入。当用户在字段开始键入时,浏览器基于之前键入过的值,应该显示出在字段中填写的选项。)。
  • novalidate:如果使用该属性,则提交表单时不进行验证(关闭控件自动校验功能)。

2、邮箱:email

<form>
    邮箱:<input type="email" name="email">
</form>

效果图:

image

3、网址:url

协议、域名都要输入进去(https://www.baidu.com,如果直接www.baidu.com会提示输入错误的),否则触发表单校验。
<form>
    网址:<input type="url" name="url">
</form>

效果图:

image

4、数字:number

输入表单数number属性的时候,在表单尾部会有一个上下的箭头,用来选择数字。另外表单里的step属性表示:点击的时候每一次增加或减少的步数;max属性表示:增加到的最大范围,min属性表示减小到的最小范围。
<form>
    年龄:<input type="number" name="" step="3" max="120" >
</form>

效果图:

image

5、电话号码:tel

<form>
     电话号码: <input type="tel" name="tel">
</form>

6、颜色:color

<form>
    邮箱:<input type="color" name="color">
</form>

效果图:

image

7、时间:time

<form>
     时间:<input type="time" name="time">
</form>

效果图:

image

8、日期:date

<form>
     日期: <input type="date" name="date">
</form>

效果图:

image

9、时间日期:datetime

<form>
     时间日期: <input type="datetime" name="datetime">
</form>

10、周:week

<form>
     周: <input type="week" name="week">
</form>

效果图:

image

11、月:month

<form>
     月: <input type="month" name="month">
</form>

效果图:

image

12、滑块:range

max:规定允许的最大值,min:规定允许的最小值。
<form>
    滑块: <input type="range" name="range" min="1" max="20">
</form>

效果图:

image

5.2 表单元素

不是所有浏览器都支持HTML5新的表单元素的,但是不影响使用,即使不支持仍然可以显示常规的表单。

1、datalist

Web设计中,经常会用到如输入框的自动下拉提示,这将大大方便用户的输入。在以前,如果要实现这样的功能,必须要求开发者使用一些Javascript的技巧或相关的框架进行ajax调用,需要一定的编程工作量。但随着HTML5的慢慢普及,开发者可以使用其中的新的DataList标记就能快速开发出十分漂亮的AutoComplete组件的效果。

datalist有点类似于select下拉菜单,datalist元素规定输入域的选项列表。列表是通过datalist内的 option元素创建的。如需把datalist绑定到输入域,请用输入域的list属性引用datalistid

<p>
    浏览器版本:<input list="words">
</p>

<datalist id="words">
    <option value="Internet Explorer">
    <option value="Firefox">
    <option value="Chrome">
    <option value="Opera">
    <option value="Safari">
    <option value="Sogou">
    <option value="Maxthon">
</datalist>

效果图:

image

5.3 表单属性

HTML5中, <form><input>标签添加了几个新属性。其中<form>标签的autocompletenovalidate属性,我们在上面都讲过了,现在我们来看看<input>提供了哪些新的属性。

1、autocomplete 自动完成

autocomplete属性规定forminput域应该拥有自动完成功能。当用户在自动完成域中开始输入时,浏览器应该在该域中显示填写的选项。

提示:autocomplete属性有可能在form元素中默认是开启的,而在input元素中是关闭的。需要手动添加"on"。

示例代码:

<input type="text" autocomplete="on">

2、placeholder 占位符

placeholder属性提供一种提示(hint),描述输入域所期待的值。简短的提示在用户输入值前会显示在输入域上。

示例代码:

用户名:<input type="text" placeholder="请输入用户名">

效果图:

image

3、autofocus 自动获得焦点

autofocus属性是一个boolean属性。autofocus属性规定在页面加载时,域自动地获得焦点。

示例代码:

用户名:<input type="text" name="username" autofocus>

4、multiple 多文件上传

multiple属性是一个boolean属性。multiple属性规定<input>元素中可选择多个值。

示例代码:

<form action="xxx.php">
  选择图片: <input type="file" name="img" multiple>
  <input type="submit">
</form>

此时上传文件时就可以同时上传多个文件了。

5、form 绑定输入域

当一个输入表单input,不在一个表单域form中的时候。通过form属性和表单域的id可以将输入表单绑定到表单域中。

示例代码:

<form action="xxx.php" id="form1">
    用户名: <input type="text" name="username"><br>
    <input type="submit" value="提交">
</form>
    密码: <input type="text" name="pwd" form="form1">

点击提交按钮,表单域外部的“密码”输入框内容也会提交。

6、required 必填项

required属性是一个boolean属性。required属性规定必须在提交之前填写输入域(不能为空)。

示例代码:

用户名: <input type="text" name="usrname" required>

7、pattern 自定义验证

pattern属性描述了自定义一个正则表达式用于验证<input>元素的值。

示例代码:

<form action="">
    用户名: <input type="text" name="username" pattern="[A-Za-z]{3}" title="三位英文字母">
    <input type="submit">
</form>

效果图:

image

5.4 表单事件

这里给大家介绍两个表单事件oninput:用户输入的时候触发的事件;oninvalid:表单验证无法通过时候触发的事件

示例代码:

<form action="">
    用户名:<input type="text" name="username" id="user">
    <!-- 限定密码格式只能是数字 -->
    密 码: <input type="text" name="pwd" id="pwd" pattern="\d+">
    <input type="submit">
</form>

<script type="text/javascript">
    var user = document.getElementById('user');
    var pwd = document.getElementById('pwd');
    
    // 用户输入的时候触发
    user.oninput = function(){
        alert(1);
    }
    // 验证无法通过的时候触发
    pwd.oninvalid = function(){
        alert(2);
    }
</script>

效果图:

image

当验证无法通过的时候,可以通过setCustomValidity方法添加或修改提示内容:

pwd.oninvalid = function(){
    this.setCustomValidity("密码格式错误"); 
}

效果图:

image

5.5 表单样式

这里主要是说下如何修改placeholder的默认样式。
  • 火狐: input::-moz-placeholder{}
  • 谷歌: input::-webkit-input-placeholder {}

通过双伪元素选择器,即可改变placeholder文字的样式。

6. 多媒体标签

HTML5之前,在网页上播放音频/视频的通用方法是利用Flash来播放,但是大多情况下,并非所有用户的浏览器都安装了Flash插件,由此使得处理音频/视频播放变的非常复杂,并且移动设备的浏览器并不支持Flash插件。

6.1 音频

HTML5通过<audio>标签来解决音频播放的问题。

示例代码:

<!-- 通过src指定音频文件路径即可 -->
<audio src="./xxx.mp3"></audio>

播放格式

由于版权等原因,不同的浏览器可支持播放的格式是不一样的,如下图供参考:

image

处理兼容性

<audio></audio>之间你需要插入浏览器不支持的<audio>元素的提示文本 。<audio>元素允许使用多个 <source>元素。<source> 元素可以链接不同的音频文件,浏览器将使用第一个支持的音频文件。
<audio>
    <!-- 通过source标签指定多格式音频文件 -->
    <source src="xxx.ogg" type="audio/ogg">
    <source src="xxx.mp3" type="audio/mpeg">
    <source src="xxx.wav" type="audio/wav">
    您的浏览器不支持 audio 元素。
</audio>

音频控制属性

通过附加属性可以更友好控制音频的播放.
  • autoplay 自动播放
  • controls 是否显示控制条
  • loop 循环播放

6.2 视频

HTML5通过<video>标签来解决音频播放的问题。

示例代码:

<!-- 通过src指定视频文件路径即可 -->
<video src="./xxx.mp4"></video>

播放格式

由于版权等原因,不同的浏览器可支持播放的格式是不一样的,如下图供参考:

image

处理兼容性

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

6.3 音频/视频方法

通过附加属性可以更加友好的控制音频、视频的播放。

1、autoplay 自动播放

autoplay属性设置或返回音视频是否在加载后即开始播放。

设置autoplay属性:

audio|video.autoplay=true|false

返回autoplay属性:

audio|video.autoplay

启用自动播放,并重载视频:

var video=document.getElementById("video1");
video.autoplay = true;
video.load();

2、buffered 已缓冲部分

buffered属性返回TimeRanges对象。TimeRanges对象表示用户的音视频缓冲范围。缓冲范围指的是已缓冲音视频的时间范围。如果用户在音视频中跳跃播放,会得到多个缓冲范围。

返回值:

TimeRanges对象,表示音视频的已缓冲部分。

TimeRanges对象属性:

  • length - 获得音视频中已缓冲范围的数量
  • start(index) - 获得某个已缓冲范围的开始位置
  • end(index) - 获得某个已缓冲范围的结束位置

注意:首个缓冲范围的下标是0

示例代码:

获得视频的第一段缓冲范围(部分),以秒计:

var video = document.getElementById("video1");
alert("Start: " + video.buffered.start(0) + " End: " + video.buffered.end(0));

3、controls 是否显示控制条

controls属性设置或返回浏览器应当显示标准的音视频控件。

设置controls属性:

audio|video.controls=true|false

返回controls属性:

audio|video.controls

启用视频控件:

var video = document.getElementById("video1");
video.controls = true;

4、currentSrc 返回当前资源的URL

currentSrc熟悉返回当前音频/视频的URL。如果未设置音频/视频,则返回空字符串。

获得当前视频的URL

video = document.getElementById("video1");
alert(video.currentSrc);

5、currentTime 当前播放位置(时间s)

属性 描述
autoplay 资源加载完成后自动播放视频或音频
buffered 返回表示音频/视频已缓冲部分的TimeRanges对象
controls 是否显示控制条
currentSrc 返回当前音频/视频的URL
currentTime 设置或返回音频/视频中的当前播放位置(以秒计)
defaultMuted 设置或返回音频/视频默认是否静音
defaultPlaybackRate 设置或返回音频/视频的默认播放速度
duration 返回当前音频/视频的长度(以秒计)
ended 返回音频/视频的播放是否已结束
error 返回表示音频/视频错误状态的MediaError对象
loop 设置或返回音频/视频是否应在结束时重新播放
mediaGroup 设置或返回音频/视频所属的组合(用于连接多个音频/视频元素)
muted 设置或返回音频/视频是否静音
networkState 返回音频/视频的当前网络状态
paused 设置或返回音频/视频是否暂停
playbackRate 设置或返回音频/视频播放的速度
played 返回表示音频/视频已播放部分的TimeRanges对象
preload 设置或返回音频/视频是否应该在页面加载后进行加载
readyState 返回音频/视频当前的就绪状态
seekable 返回表示音频/视频可寻址部分的TimeRanges对象
seeking 返回用户是否正在音频/视频中进行查找
src 设置或返回音频/视频元素的当前来源
startDate 返回表示当前时间偏移的Date对象
textTracks 返回表示可用文本轨道的TextTrackList对象
videoTracks 返回表示可用视频轨道的VideoTrackList对象
volume 设置或返回音频/视频的音量

7. DOM 扩展

7.1 获取元素

html5中新添了两个查找元素的属性,分别是:querySelectorquerySelectorAll
<ul>
     <li class="one"><a href="#">文字1</a></li>
     <li class="two"><a href="#">文字2</a></li>
     <li class="three"><a href="#">文字3</a></li>
</ul>

<script type="text/javascript">
    //获取元素的方式
    var a= document.querySelector(".one a");
    a.style.color="red";
    
    //通过该方式可以将所有对应的元素选中 返回的是一个伪数组
    var a1= document.querySelectorAll("a");  

</script>

7.2 类名操作

html5中新添加了一个操作类名的对象:classList。我们可以通过它里面的方法对元素的类进行操作。

1、添加类(add

添加类的时候,获取到元素之后,通过classListadd方法添加一个类名,但是一次只能添加一个类名,否则会报错。
<style type="text/css">
    .bgc {
        width: 300px;
        height: 300px;
        background-color: pink;
    }
    .fonts{
        font-size: 26px;
    }
</style>

<div>文字</div>

<script type="text/javascript">
      var div=document.querySelector("div");
          // 添加样式 只能单独添加
          div.classList.add("bgc");    
        div.classList.add("fonts");
</script>

2、移除类(remove

移除类的时候,获取到元素之后,通过classListremove方法移除一个类名。
<style type="text/css">
    .bgc {
        width: 300px;
        height: 300px;
        background-color: pink;
    }
    .fonts{
        font-size: 26px;
    }
</style>

<div class="bgc fonts">文字</div>

<script type="text/javascript">
      var div=document.querySelector("div");
          // 移除样式 只能单独移除
          div.classList.remove("bgc");    
        div.classList.remove("fonts");
</script>

3、切换类(toggle

当元素上没有某个类时,它就新增这个类;如果元素已经有了这个类,它就是删除它,就是切换操作。
<style type="text/css">
    .bgc {
        width: 300px;
        height: 300px;
        background-color: pink;
    }
</style>

<div class="bgc">文字</div>

<script type="text/javascript">
      var div=document.querySelector("div");
          // 切换样式 因为元素已经有“bac”这个类名了,所以这里是移除的功能
          div.classList.toggle("bgc");
</script>

4、是否存在某个类(contains

判断获取的元素中是否存在某个类名,返回值为true或者false
<style type="text/css">
    .bgc {
        width: 300px;
        height: 300px;
        background-color: pink;
    }
</style>

<div class="bgc">文字</div>

<script type="text/javascript">
      var div=document.querySelector("div");
          // 判断元素是否拥有某个类名
          div.classList.contains("bgc");    // true
</script>

7.3 自定义属性

HTML5规定可以为元素添加非标准的属性,但要添加前缀data-,目的是为元素提供与渲染无关的信息,或者提供语义信息。这些属性可以任意添加、随便命名,只要以data-开头。

如:

<p data-info="tags"></p>

获取自定义属性(dataset['自定义属性名称'])

通过Node.dataset['info'] 我们便可以获取到自定义的属性值。
<p data-info="describe" data-num="123">这是一段描述</p>

<script>
    var tag = document.querySelector('p');
    var data = tag.dataset;

    console.log(data);   // 打印的是一个对象 DOMStringMap
    console.log(data['info']);  // "describe"
    console.log(data['num']);  // "123"
</script>

image

Node.dataset是以对象形式存在的,当我们为同一个DOM节点指定了多个自定义属性时,Node.dataset则以键值对的形式存储了所有的自定义属性的值。

设置自定义属性(dataset['自定义属性名称']="设定属性值")

通过过Node.dataset['info']="值" 我们便可以设置自定义的属性值。
<p data-info="describe" data-num="123">这是一段描述</p>

<script>
    var tag = document.querySelector('p');
    var data = tag.dataset;

    data['name'] = "Ryan";
    console.log(data);     // 多了一个name属性
</script>

注意

当自定义属性中除了data-之外中间出现“-”连接符时,设置和获取的时候需要将属性名转成驼峰的格式才能正常的设置和获取。
<p data-my-info="information">这是一段描述!</p>

<script>
    var tag = document.querySelector('p');
    var data = tag.dataset;

    data['myInfo'] = "info";
    console.log(data);     // {myInfo:"info"}
</script>

8. 网络状态

我们可以通过window.navigator.onLine来检测,用户当前的网络状况,返回一个布尔值

通过给window绑定监听事件,可以监测浏览器的一些状态信息

  • 网络从无到有时触发“online”方法
window.addEventListener('online', function(){
    // online是网络从无网到有网的 时候触发
})
  • 网络从有到无时触发“offline”方法
window.addEventListener('offline', function(){
    // online是网络从有网到无网的时候触发
})

9. 地理定位

HTML规范中,增加了获取用户地理信息的API,这样使得我们可以基于用户位置开发互联网应用,即基于位置服务 (Location Base Service)

9.1 获取地理信息方式

获取地理信息的方式一共有三种分别是:
  • IP地址
  • 三维坐标

    • GPSGlobal Positioning System,全球定位系统)
    • Wi-Fi
    • 手机信号
  • 用户自定义数据

如下表:

下表对不同获取方式的优缺点进行了比较,浏览器会自动以最优的方式去获取用户地理位置
数据源 优点 缺点
IP 地址 任何地方都可以用,在服务器端处理 不精确(经常出错,一般精确到城市级)运算代价大
GPS 很精确 定位时间长,耗电量大;室内效果差;需要额外硬件设备支持
Wi-Fi 精确,可在室内使用,简单、快捷 在乡村这些Wi-Fi接入点少的地区无法实现用
手机信号 相当准确,可在室内使用,简单、快捷 需要能够访问手机或其 modem 设备
用户自定义 可获得比程序定位服务更准确的位置数据,用户自行输入可能比自动检测更快 可能很不准确,特别是当用户位置变更后

9.2 隐私

HTML5 Geolocation规范提供了一套保护用户隐私的机制。必须先得到用户明确许可,才能获取用户的位置信息。

9.3 使用地理定位

有两个方法都可以获取到当前的地理定位,只是功能上稍微有点区别。
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options) // 方法:获取当前地理信息

navigator.geolocation.watchPosition(successCallback, errorCallback, options) // 重复获取当前地理信息

当成功获取地理信息后

会调用succssCallback,并返回一个包含位置信息的对象position
position.coords.latitude  // 纬度
position.coords.longitude // 经度

成功对象position

image

属性 描述
coords.latitude 十进制数的纬度
coords.longitude 十进制数的经度
coords.accuracy 位置精度
coords.altitude 海拔,海平面以上以米计
coords.altitudeAccuracy 位置的海拔精度
coords.heading 方向,从正北开始以度计
coords.speed 速度,以米/每秒计
timestamp 响应的日期/时间

当获取地理信息失败后

会调用errorCallback,并返回错误信息error

返回无符号的、简短的错误码,详见下表:

相关联的常量 描述
1 PERMISSION_DENIED 用户不允许地理定位
2 POSITION_UNAVAILABLE 无法获取当位置
3 TIMEOUT 超时操作

示例代码:

获取当前位置的经纬度
window.navigator.geolocation.getCurrentPosition(function(position){
    // 纬度
    var lat = position.coords.latitude;
    // 经度
    var long = position.coords.longitude;

    console.log('你当前的纬度为:' + lat + '经度为:' + long)

},function(err){  // 错误时回调信息
    if(err.code == 1){
        alert('没有权限')
    }else if(err.code == 2){
        alert('内部错误');
    }else{
        alert('超时')
    }
},{
    // 超时设置
    timeout: 5000
});

9.4 百度地图的用法

结合百度地图的API,我们可以使用它上面的一些功能,比如在地图上定位等等等...

进入百度地图开放平台官网:

网址:http://lbsyun.baidu.com/

找到Web开发 -> javascript API

image

直接找到示例DEMO,复制源代码,需要获取密钥 (自己申请,需要一到两个工作日)

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
        body,
        html,
        #allmap {
            width: 100%;
            height: 100%;
            overflow: hidden;
            margin: 0;
            font-family: "微软雅黑";
        }
    </style>
    <script type="text/javascript" src="你申请的秘钥"></script>
    <title>地图展示</title>
</head>

<body>
    <div id="allmap"></div>
</body>

</html>
<script type="text/javascript">
    // 百度地图API功能
    var map = new BMap.Map("allmap"); // 创建Map实例
    map.centerAndZoom(new BMap.Point(116.404, 39.915), 11); // 初始化地图,设置中心点坐标和地图级别
    map.addControl(new BMap.MapTypeControl()); //添加地图类型控件
    map.setCurrentCity("北京"); // 设置地图显示的城市 此项是必须设置的
    map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
</script>

获取当前所在位置,设置到地图上

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
        body,
        html,
        #allmap {
            width: 100%;
            height: 100%;
            overflow: hidden;
            margin: 0;
            font-family: "微软雅黑";
        }
    </style>
    <script type="text/javascript" src="你申请的秘钥"></script>
    <title>地图展示</title>
</head>

<body>
    <div id="allmap"></div>
</body>

</html>
<script type="text/javascript">
    window.navigator.geolocation.getCurrentPosition(function (pos) {
        // 纬度
        var lat = pos.coords.latitude;
        // 经度
        var long = pos.coords.longitude;

        console.log('你当前的纬度为:' + lat + '经度为:' + long)

        // 百度地图API功能
        var map = new BMap.Map("allmap"); // 创建Map实例
        map.centerAndZoom(new BMap.Point(long, lat), 15); // 初始化地图,设置中心点坐标和地图级别
        map.addControl(new BMap.MapTypeControl()); //添加地图类型控件
        map.setCurrentCity("北京"); // 设置地图显示的城市 此项是必须设置的
        map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放

    }, function (err) {
        if (err.code == 1) {
            alert('没有权限')
        } else if (err.code == 2) {
            alert('内部错误');
        } else {
            alert('超时')
        }
    }, {
        // 超时设置
        timeout: 5000
    });
</script>

效果图:

image

10. WEB 存储

随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,传统方式我们以document.cookie来进行存储的,但是由于其存储大小只有4k左右,并且解析也相当的复杂,每一次发送请求都会携带上cookie,会造成带宽的浪费,给开发带来诸多不便,HTML5规范则提出解决方案。web存储的含义是将数据存储到用户的电脑上,这样可以缓解服务器的压力,并且提高体验。

10.1 特性

  • 设置、读取方便
  • 容量较大,sessionStorage5MlocalStorage20M
  • 只能存储字符串,可以将对象JSON.stringify()转成字符串后存储

10.2 方法详解

  • setItem(key, value)设置存储内容
  • getItem(key)读取存储内容
  • removeItem(key)删除键值为key的存储内容
  • clear()清空所有存储内容
  • key(n)以索引值来获取键名
  • length 存储的数据的个数

示例代码:

// 在本地存储了一个键为:username 值为 Ryan's 的这个一个对象
// 在chrome的控制台的application里面的Storage可以查看
window.localStorage.setItem('username1',"Ryan's");
window.localStorage.setItem('username2',"Levi's");

window.sessionStorage.setItem('username1',"Ryan's");
window.sessionStorage.setItem('username2',"Levi's");

// 索引键的名字
alert(window.localStorage.key(0));
alert(window.sessionStorage.key(0));

// 取数据 
alert(window.localStorage.getItem('username1'));
alert(window.sessionStorage.getItem('username1'));

// 获取本地数据的长度
alert(window.localStorage.length);
alert(window.sessionStorage.length);

// 删除数据
window.localStorage.removeItem('username1');
window.sessionStorage.removeItem('username1');

// 清空所有的数据
window.localStorage.clear();
window.sessionStorage.clear();

10.3 sessionStorage

特点:

  • 生命周期为关闭当前页面窗口
  • 不能多窗口下数据共享(同源策略)
  • 通过跳转可以解决,页面跳转的时候可以通过session实现数据共享

10.4 localStorage

特点:

  • 生命周期为永久有效,除非手动删除或用代码删除
  • 可以多窗口共享(同源策略)
  • 一些不涉及到安全的一些数据(不要太过庞大)都可以存储到本地

示例代码:

window.localStorage.setItem('age',18)

效果图:

image

10.5 差异性

比较cookiesessionlocal三者之间的相同点和不同点

相同点:

  • 都是存储数据,存储在web端,并且都是同源

不同点:

  • (1)cookie只有4K大小 并且每一次请求都会带上cookie体验不好,浪费带宽
  • (2)sessionlocal直接存储在本地,请求不会携带,并且容量比cookie要大的多
  • (3)session是临时会话,当窗口被关闭的时候就清除掉 ,而local永久存在,cookie有过期时间
  • (4)cookielocal都可以支持多窗口共享,而session不支持多窗口共享 但是都支持a链接跳转的新窗口

11. 文件读取

通过FileReader对象我们可以读取本地存储的文件,可以使用File对象来指定所要读取的文件或数据。其中File对象可以是来自用户在一个<input>元素上选择文件后返回的FileList对象,也可以来自由拖放操作生成的DataTransfer

1、FileList 对象

由于HTML5中我们可以通过为表单元素添加multiple属性,因此我们通过<input>上传文件后得到的是一个FileList对象(伪数组形式)。

2、FileReader 对象

HTML5新增内建对象,可以读取本地文件内容。var reader = new FileReader;可以实例化一个对象。
var data = file.files[0];
// 创建一个读取对象
var fr = new FileReader();
// 读取文件

fr.readAsDataURL(data);

readAsDataURL()DataURL形式读取文件

3、事件监听

onload当文读取完成时调用
fr.addEventListener('load', function(){
    //获取读取的结果  
    //result属性里面存储的就是读取文件的结果
    var result = fr.result;    
})

完整代码:

<input type="file" multiple name="" id="">
<button>点击读取文件</button>

<script type="text/javascript">
var btn = document.querySelector('button');
var file = document.querySelector('input[type="file"]');
var fr = [];
btn.onclick = function(){        
    // 读取文件
    for(var i = 0; i < file.files.length; i++){
        fr[i] = new FileReader();
        fr[i].readAsDataURL(file.files[i]);
    }
    // fr.readAsDataURL(data);
    // 读取文件是一个耗时的操作,所以需要用事件监听读取完毕,
    // load事件是文件读取完毕之后触发的事件
    for(var j = 0; j < fr.length; j++){
        fr[j].addEventListener('load', function(){
            //获取读取的结果  
            //result属性里面存储的就是读取文件的结果
            console.log(fr);
            var result = this.result;    
            // 创建图片对象
            var img = document.createElement('img');
            img.src = result;
            document.body.appendChild(img); 
        })
    }    
}

</script>

12. 拖拽

HTML5的规范中,我们可以通过为元素增加draggable="true"来设置此元素是否可以进行拖拽操作,其中图片、链接默认是开启的。

1、拖拽元素

页面中设置了draggable="true"属性的元素,可以被拖拽,其中<img><a>标签默认是可以被拖拽的。

2、目标元素

页面中任何一个元素都可以成为目标元素。

3、事件监听

根据元素类型的不同,需要设置不同的事件监听:

(1)、拖拽元素

  • ondrag 应用于拖拽元素,整个拖拽过程都会调用
  • ondragstart 应用于拖拽元素,当拖拽开始时调用
  • ondragend 应用于拖拽元素,当拖拽结束时调用

(2)、目标元素

  • ondragenter 应用于目标元素,当拖拽元素进入时调用
  • ondragleav 应用于目标元素,当鼠标离开目标元素时调用
  • ondragver 应用于目标元素,当停留在目标元素上时调用
  • ondrop 应用于目标元素,当在目标元素上松开鼠标时调用

示例代码: 将图片拖拽到浏览器内显示在div

<style>
    .info {
        width: 500px;
        height: 500px;
        border: 1px solid #000;
        position: absolute;
        left: 50%;
        top: 50%;
        line-height: 500px;
        text-align: center;
        transform:translate(-50%,-50%);
        box-shadow: 0 0 10px 2px rgba(0,0,0,.5); 
        border-radius: 5px;
    }
    .info img {
        width: 100%;
        height: 100%;
    }
</style>

    
<!-- 目标元素 -->
<div class="info">将图片拖拽至此</div>
    

<script type="text/javascript">
    var info = document.querySelector('.info');
    // 获取html元素
    var oHtml = document.documentElement;

    // 问题:浏览器默认会将外部拖拽的文件直接打开,我们需要阻止掉
    // 将外部文件拖拽进浏览器里面松开鼠标的时候其实就是在html页面上触发了drop事件,我们只需要在drop事件的时候阻止默认事件
    oHtml.ondrop = function(e){
        // 阻止默认事件
        e.preventDefault();
    }
    /*drop事件默认是被阻止的,所以还需要在dragover的时候阻止默认事件*/
    oHtml.ondragover = function(e){
        e.preventDefault();
    }

    info.ondrop = function(e){
        // 获取外部拖拽进来的文件
        // console.log(e);
        var data = e.dataTransfer.files[0];        
        var fr = new FileReader();
        fr.readAsDataURL(data);
        fr.addEventListener('load',function(){
            var result = fr.result;
            var img = document.createElement('img');
            img.src = result;
            info.innerHTML = '';
            info.appendChild(img);
        })
    }
</script>

效果图

image


深海丶Deepsea
3.9k 声望1.4k 粉丝

Trust yourself,You know more than you think you do.