一文入门HTML5
1.html5
上节回顾:一文读懂es6(附py3对比) | 一文入门nodejs
演示demo:https://github.com/lotapp/basecode/tree/master/javascript/0.h5_c3/h5
参考文档: | https://developer.mozilla.org/zh-cn/docs/web/guide/html/html5
html5主要目的是为了在移动设备上支持多媒体,eg:<video>
、<audio>
、<canvas>
(ps:flash太重量级)
这么多年下来了,有些api被广泛支持,有些api逐渐淡化在视线中了(eg:websql
、indexeddb
等)
我们来看下常用
的新特性:
- 取消了过时的一些显示效果标记,eg:
<font>
、<center>
- ps:用css实现
- 新表单元素引入
- eg:input新的type:
number
、url
、email
...
- eg:input新的type:
- 新语义标签的引入
- eg:
<nav>
、<header>
、<footer>
...
- eg:
- 多媒体以及图形方面的扩展
- eg:
<canvas>
、<video>
、<audio>
- eg:
- web本地存储
- eg:
localstorage
- eg:
- 一些html5提供的api
优点:跨平台
pc端支持不是特别友好
- ps:主要是低版本浏览器不太支持新特性
1.1.语义标签
有利于seo,有利于盲人阅读等,官方文档:
https://developer.mozilla.org/zh-cn/docs/web/guide/html/sections_and_outlines_of_an_html5_document
1.1.1.基础
常用语义化标签:
<nav>导航区域</nav> <header>头部区域</header> <main>主内容区</main> <footer>尾部区域</footer> <article>文章区域</article> <aside>侧栏区域</aside> <section>内容组/节</section>
ps:可以将网站首页划分为简介、内容、联系信息等内容组(section
)
官方给的语义化标签:
标签 描述 <article> 定义文章。 <aside> 定义页面内容以外的内容。 <details> 定义用户能够查看或隐藏的额外细节。 <figcaption> 定义 <figure> 元素的标题。 <figure> 规定自包含内容,比如图示、图表、照片、代码清单等。 <footer> 定义文档或节的页脚。 <header> 规定文档或节的页眉。 <main> 规定文档的主内容。 <mark> 定义重要的或强调的文本。 <nav> 定义导航链接。 <section> 定义文档中的节。 <summary> 定义 <details> 元素的可见标题。 <time> 定义日期/时间。
ps:<div>没有语义的标签</div>
,使用方面和语义标签一样,但seo效果没语义标签好
效果图
可以看看我几年前写的文章:
1.1.2.兼容
先看看最关心的兼容性问题:
低版本会把语义标签当成用户自定义的标签,eg:
<!doctype html> <html> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <title>page title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> nav { height: 200px; background-color: red; } div { height: 200px; background-color: blue; } </style> </head> <body> <!-- 导航 --> <nav>语义标签的导航</nav> <div>没有语义的导航</div> </body> </html>
浏览器基本上都是支持的
但是低版本不能识别(eg:ie8
)
1.1.3.解决
现在基本上都是引用一下兼容的库,我们先看看本质是啥:
<!doctype html> <html> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <title>page title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> nav { height: 200px; background-color: red; /* ie创建自定义标签默认是行级元素,height不生效,所以需要设置block */ display: block; } div { height: 200px; background-color: blue; } </style> <script> // 创建自定义标签 document.createelement("nav") </script> </head> <body> <!-- 本质就是因为不能识别,那就创建自定义标签,ie默认创建的为行级标签,那就设置为块级元素 --> <nav>语义标签的导航</nav> <div>没有语义的导航</div> </body> </html>
兼容解决:
ps:本质就是因为不能识别这些语义化标签,那就需要创建自定义的标签。而ie默认创建的标签为行级标签,height就不生效了,所以就需要设置为块级元素
兼容方案
推荐一个兼容旧版本语义标签的库:https://github.com/afarkas/html5shiv
<!doctype html> <html> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <title>page title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> nav { height: 200px; background-color: red; display: block; } div { height: 200px; background-color: blue; } </style> <!-- if lt ie 9:低于`ie9`版本会加载 --> <!--[if lt ie 9]> <script type="text/javascript" src="../js/html5shiv.min.js"></script> <![endif]--> </head> <body> <nav>语义标签的导航</nav> <div>没有语义的导航</div> </body> </html>
ps:小知识点
-
[if ie]
:ie
浏览器 -
[if !ie]
:不是ie
浏览器 -
[if lt ie 9]
:低于ie9
-
[if lte ie 8]
:<=ie8
ps:我们一般使用modernizr
即可(默认包含了html5shiv
)
还可以解决其他兼容性问题
<!--[if lte ie 9]> <script type="text/javascript" src="https://cdn.staticfile.org/modernizr/2.8.3/modernizr.min.js"></script> <![endif]-->
来个语义化的页面演示:
ps:目前只适配了ipad、pc和ie9以上浏览器(移动端为了帮大家省流量准备单独搞个页面)
先看效果:(我开源了,感兴趣的可以去fork)
ps:主打宽屏(逆天是1920的宽屏)
大致框架:https://github.com/lotapp/h5blog
<header> <div class="logo"></div> <!-- nav>ul>li*5>a:link --> <nav> <ul> <li><a href="#">首页</a></li> <li><a href="#">资讯</a></li> <li><a href="#">专业</a></li> <li><a href="#">生活</a></li> <li><a href="#">国学</a></li> <li><a href="#">资源</a></li> <li><a href="#">实验</a></li> </ul> </nav> <div class="search"></div> </header> <div class="banner"> <!-- ul>li*5 --> <ul> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> </div> <!-- 主体内容 --> <main> <!-- 文章部分 --> <article> <!-- 最新文章 --> <section class="new_article"> <header> <nav> <ul> <li>首页</li> <li>资讯</li> <li>专业</li> <li>生活</li> <li>国学</li> <li>资源</li> </ul> </nav> </header> <!-- 对应菜单的内容 --> <div class="new_tabs"> <!-- div.new_item*5 --> <div class="new_item">内容</div> <div class="new_item">内容</div> <div class="new_item">内容</div> <div class="new_item">内容</div> <div class="new_item">内容</div> </div> </section> <!-- 文章列表 --> <section class="blog_lsit"> <h2>推荐文章</h2> <!-- ul>li*15 --> <ul> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> </section> <!-- 分页栏 --> <footer> <!-- ul>li*5(也可以直接使用a标签) --> <ul> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> </footer> </article> <!-- 侧边栏,相关文章 --> <!-- aside>sestion*5>h2+div --> <aside> <sestion> <h2></h2> <div></div> </sestion> <sestion> <h2></h2> <div></div> </sestion> </aside> </main> <!-- 尾部信息 --> <footer> <address>xxx</address> </footer>
1.2.多媒体标签
video and audio
官方文档: and
主要属性:
- controls:显示控件
- muted:静音
- autoplay:自动播放
- loop:循环播放
- preload:预加载
<video src="http://www.w3school.com.cn/i/movie.mp4" controls autoplay loop muted>您的浏览器不支持video标签</video> <audio src="http://www.w3school.com.cn/i/song.mp3" controls autoplay loop muted>您的浏览器不支持</audio>
ps:大家有没有发现,现在视频网站都是自动播放,很多默认都是静音?
但是需要注意下不同浏览器的兼容格式:
上面代码的兼容写法如下:
<video controls> <source src="http://www.w3school.com.cn/i/movie.mp4"> <source src="http://www.w3school.com.cn/i/movie.ogg"> 您的浏览器不支持video标签 </video> <audio controls> <source src="http://www.w3school.com.cn/i/song.mp3"> <source src="http://www.w3school.com.cn/i/song.ogg"> 您的浏览器不支持audio标签 </audio>
扩展
这个部分几年前讲过,记得还做了个播放器,就不去讲了,项目里也基本上用大厂开源的库:
ps:这几款播放器用的挺多:(推荐加粗项目)
-
video.js
(开源2.45w+
)- url:
- vue版:
-
cyberplayer
(百度)- ps:基于
video.js
- url:https://cloud.baidu.com/doc/mct/web-sdk.html
- ps:基于
-
tencentplayer
(腾讯)- url:
-
webtorrent
(开源1.9w+
)- url:
-
flv.js
(bilibili开源1.4w+
) -
dplayer
(开源5.3k+
) -
jwplayer
(开源1.8k+
)- url:
-
chimee组件化框架(开源
1.65k+
) -
youkuplayer
(优酷)- url:
1.3.新表单元素
1.3.1.智能表单类型
email
:合法邮箱url
:合法url地址number
:合法数字-
date
:显示日期 -
month
:显示月份 -
week
:显示第几周 -
time
:显示时间 -
range
:滑动条 -
search
:搜索框 color
:拾色器
使用setcustomvalidity()
设置自定义验证
1.3.2.表单属性
1.form属性
autocomplete="on|off"
:是否自动完成-
novalidate="true|false"
:不校验|校验数据
2.input属性
required
:必填选项autofocus
:自动获取焦点placeholder
:提示信息maxlength
:最大字符数-
autocomplete
:取消候选词- ps:一般都是自己设置,如果不关闭会重叠(百度代码:
<input value="" maxlength="255" autocomplete="off">
)
- ps:一般都是自己设置,如果不关闭会重叠(百度代码:
-
multiple
:多选效果 form="表单id
:把不在表单域里面的input添加到表单中
<select multiple> <option>11</option> <option>22</option> <option>33</option> <option>44</option> </select> <input type="text" list="list_id" /> <datalist id="list_id"> <option>11</option> <option>22</option> </datalist>
1.3.3.扩展说明
这个之前也说的很详细了,这边列了常用属性就完事了,感兴趣可以去老文章看看:
ps:有些是真方便,但表单验证一般不太用(不同浏览器表现ui不同,产品经理会打你的哦~)
1.4.常用api
1.4.1.dom相关api(必看)
这个高版本ie都支持,而且出了dom相关api后,现在基本上不太用jq了
ps:有些项目需要兼容老版本浏览器的另说
1.获取页面元素
获取页面元素
:
-
document.queryselector("选择器")
:返回符合选择器的第一个元素 -
document.queryselectorall("选择器")
:返回所有符合选择器的元素 - ps:选择器可以是css中的任意一种(你css怎么写的,这边就怎么写)
- eg:
document.queryselector("#id")
、document.queryselector(".class")
、document.queryselector("tag")
- eg:
举个栗子:我想让python变成红色,用css可以这么写:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>选择器</title> <style> li span { color: red; } </style> </head> <body> <ul> <li><span>python</span></li> <li>javascript</li> </ul> </body> </html>
效果:
通过api可以这么干:(选择器写法和css一样)
<!doctype html> <html> <head> <meta charset="utf-8"> <title>选择器</title> </head> <body> <ul> <li><span>python</span></li> <li>javascript</li> </ul> <script> // 只能选中第一个元素(单个) document.queryselector("li span").style.color = "red"; </script> </body> </html>
全部变成红色可以这么干:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>选择器</title> </head> <body> <ul> <li><span>python</span></li> <li>javascript</li> </ul> <script> // 选中所有符合的元素(列表) dom_list = document.queryselectorall("li"); // 用法很像c# dom_list.foreach(item => { item.style.color = "red"; }); </script> </body> </html>
效果:
2.类名操作
类名操作
(页面元素对象的方法)
-
xxdom.classlist.add("类名")
:给当前dom元素添加类样式 -
dom.classlist.remove("类名")
:移除当前dom元素的类样式 -
dom.classlist.contains("类名")
:检测是否包含类样式 -
dom.classlist.toggle("类名")
:切换类样式- ps:有就删除,没有就添加
举个栗子:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>类名操作</title> <style type="text/css"> .dis { background-color: red; width: 300px; height: 50px; } </style> </head> <body> <div class="demo"></div> <div> <input type="button" value="添加类名" class="add mmd"> <input type="button" value="移除类名" class="remove"> <input type="button" value="切换类名" class="toggle"> <input type="button" value="是否包含类名" class="contains"> </div> <script> // 演示对象 let demo_obj = document.queryselector(".demo"); // 给几个按钮对象注册点击事件 // 添加 document.queryselector(".add").onclick = () => { demo_obj.classlist.add("dis"); }; // 移除 let remove_btn = document.queryselector(".remove").onclick = () => { demo_obj.classlist.remove("dis"); }; // 切换 let toggle_btn = document.queryselector(".toggle").onclick = () => { demo_obj.classlist.toggle("dis"); // 没则添加,有则移除 }; // 是否包含 let contains_btn = document.queryselector(".contains").onclick = () => { let b = demo_obj.classlist.contains("dis"); console.log(b); }; </script> </body> </html>
效果:
ps:es6兼容可以使用babel
:cnpm i babel-core@old
> babel-core
> browser.min.js
回顾:
cnpm
配置:https://www.cnblogs.com/dotnetcrazy/p/10118756.html#1.1.npm国内镜像
3.自定义属性
自定义属性
:在标签中的data-自定义属性名
- 获取自定义属性:
dom.dataset.自定义属性名
ordom.dataset["自定义属性名"]
- 设置自定义属性:
dom.dataset.自定义属性名 = xxx
ordom.dataset["自定义属性名"] = xxx
- 删除自定义属性:
delete dom.dataset.自定义属性名
ordelete dom.dataset["自定义属性名"]
- 一般属性:
- 获取某个属性:
dom.getattribute("属性名")
- 删除某个属性:
dom.removeattribute("属性名")
- 设置某个属性:
dom.setattribute("属性名", "值")
- 是否包含属性:
dom.hasattribute("属性名")
- 获取某个属性:
举个栗子:
<div class="test" data-name="mmd" data-test-one="test">自定义属性</div> <script> // 获取标签的自定义属性值 let list = document.queryselector(".test").dataset; // 获取:dom.dataset.自定义属性名(属性名不包含`data-`) console.log(list.name); // ps:test-one名字会改成驼峰命名的变量:testone console.log(list.testone) // 设置:dom.dataset.自定义属性名 = xxx or dataset[自定义属性名] = xxx list.name = "小明"; // 标签中对应值会变成小明 list.age = 23; // 添加一个属性 // ps:设置为data-test-two list.testtwo = "test2"; </script>
输出效果:
现在可以用html5
把上次的shopee案例改写了:小计:shopee批量删除修复~附脚本
// 核心代码: setinterval(function () { var btn = document.queryselector(".delete-button"); // 只有选择之后才会出现按钮 if (btn) { // 如果包含disabled类就删除 if (btn.classlist.contains("disabled")) { btn.classlist.remove("disabled"); } // 如果包含disabled属性 if (btn.hasattribute("disabled")) { btn.removeattribute("disabled"); } } }, 1000);
ps:妈妈再也不要担心依赖jquery
了
扩展:ie下classlist的兼容解决方案
这个摸索好久,网上都是手写js去兼容,然后拿过来用发现。。。。你懂得
本来都准备不用classlist这么方便的api了,后来发现了神器:classlist
贴一下我的前端兼容方案:(modernizr
上面说了)
<!--[if lte ie 9]> <script type="text/javascript" src="https://cdn.staticfile.org/modernizr/2.8.3/modernizr.min.js"></script> <script type="text/javascript" src="https://cdn.staticfile.org/classlist/1.2.20180112/classlist.min.js"></script> <![endif]-->
ps:如果想要兼容es6
基础语法、async/await
,可以使用这两个库:babel-core
、babel-polyfill
// balel-core这个版本是最新的(再新的就不兼容ie了) <script type="text/javascript" src="https://cdn.staticfile.org/babel-core/5.8.38/browser.min.js"></script>
1.4.2.文件相关api
1.filereader
常用读取文件的方法:
-
reader.readastext
:将文件读取为文本 -
reader.readasdataurl
:将文件读取为dataurl(base64) -
reader.readasbinarystring
:将文件读取为二进制编码 - ps:返回结果在
reader.result
中
2.filereader
中含有的事件:
-
onabort
:中断时触发 -
onerror
:出错时触发 -
onload
:文件读取成功完成时触发 -
onloadend
:读取完成触发,无论成功或失败 -
onloadstart
:读取开始时触发 -
onprogress
:读取中
1.文本上传案例
<!doctype html> <html> <head> <meta charset="utf-8"> <title>文本读取</title> </head> <body> <input class="file" type="file" name=""> <script> let file_btn = document.queryselector("input"); // 注意一下this的问题:<http://www.cnblogs.com/dotnetcrazy/p/10061671.html#3.4.特殊的this(重要)> file_btn.onchange = function () { // 获取文件 let file = this.files[0]; // type只能识别常用格式,`.md`就不能识别 console.log(file); // 开始读取(创建读取器) let reader = new filereader(); // python不写new // 用读取文本的方式来读取 reader.readastext(file); // 没有返回值 // 取代完成后执行 reader.onload = () => { console.log(reader.result); }; }; </script> </body> </html>
图示:
2.图片上传案例
<!doctype html> <html> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <title>图片读取-base64</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <div><p><input type="file" /></p></div> <script> let img_exts = [".png", ".gif", ".jpg", ".jpeg", ".bmp", ".svg", ".ico"]; // 获取input对象 let input_obj = document.queryselector("input"); // 文件上传 input_obj.onchange = function () { // 获取文件信息 let file = input_obj.files[0]; // 获取文件后缀 let ext = file.name.substring(file.name.lastindexof('.')); // 不是图片 if (img_exts.indexof(ext) == -1) { alert("请上传图片,这个文件格式不支持哦~"); return } // 实例化文件读取器 let reader = new filereader(); // base64的方式读取文件 reader.readasdataurl(file); // 没有返回值 // 读取完成后执行 reader.onload = () => { // 创建一个img对象 let img_obj = document.createelement("img"); // 把读取结果设置为img的src img_obj.src = reader.result; // 创建的img对象插入到div中 document.queryselector("div").appendchild(img_obj); } } </script> </body> </html>
图示:
ps:核心代码:
// 获取input对象 let input_obj = document.queryselector("input"); // 文件上传 input_obj.onchange = function () { // 获取文件信息 let file = input_obj.files[0]; // 实例化文件读取器 let reader = new filereader(); // base64的方式读取文件 reader.readasdataurl(file); // 没有返回值 // 读取完成后执行 reader.onload = () => { console.log(reader.result); } }
ps:一般小文本文件或者图片会用,多个文件或者大文件读取不推荐使用
2.this知识的扩展
注意一下this的问题:
普通函数的this ==> 谁调用就是谁(经常变:谁调用是谁)
function show() { alert(this); // 1,2,3,4 console.log(this); // [1, 2, 3, 4, show: ƒ] } let arr = [1, 2, 3, 4]; arr.show = show; arr.show();
箭头函数的this ==> 在谁的环境下this就是谁(不变:当前作用域)
let arr = [1, 2, 3, 4]; arr.show = () => { alert(this); // [object window] console.log(this); // window } arr.show();
ps:解决回顾:
1.4.3.获取网络状态api
- 是否联网:
window.navigator.online
- ps:对于app来说:一般联网就加载最新的资源,没网就加载离线资源
- 常用事件:主要是看当前是联网还是断网,然后监听对应的断网或者联网事件
-
window.ononline
:联网触发 -
window.onoffline
:离线时候触发
-
ps:主要是移动端用的比较多
演示案例:
// 获取网络状态 var state = window.navigator.online; if (state) { console.log("当前网络可用"); } else { console.warn("断网提醒:当前网络不可用"); } // 断网执行的事件 window.onoffline = () => { document.write("网络已断开"); console.log(window.navigator.online) } // 联网执行的事件 window.ononline = () => { document.write("网络已连接"); console.log(window.navigator.online) };
经过实验发现,事件只会执行一次,而且属于有'我没你'的互斥现象,演示如下:
ps:如果已经是联网状态,只会执行断开的事件,重新连接也不会执行联网事件。反之一样~
1.4.4.获取地理位置api(推荐)
geolocation
:定位
原理:
- pc端:按照ip地址定位(ip库)
- ps:没硬件支持,只能ip走起
- 移动:按照wifi|gps模块定位(硬件定位)
1.简单案例
知识点
:
res.coords.longitude
:经度res.coords.latitude
:纬度-
res.coords.speed
:移动速度- 实时定位的时候用的多
-
res.coords.accuracy
:精确度- 一般低于50,经纬数据就偏差太多
案例:
console.log(window.navigator.useragent); // ps:agent也是可以获取的 let position = window.navigator.geolocation.getcurrentposition(res => { // 获取成功执行 console.log("获取成功", res.coords); console.log(res.coords.longitude, res.coords.latitude,"location in canada"); }, ex => { console.log("获取失败", ex); });
动态演示:(ps:没fq的可以使用ie演示
)
扩展:小程序版地图案例:
2.地图案例
ps:很多公司官网介绍里面的地图其实就是通过地图生成器
生成的:
ps:1.2版本不用密钥但是和地图生成器有点渲染的bug,你可以使用对应的api(
<script type="text/javascript" src="http://api.map.baidu.com/getscript?v=1.2"></script>
)
分享一下我的密钥:b3g90mwbie2vascccupcxjhj
<script type="text/javascript" src="http://api.map.baidu.com/getscript?v=2.0&ak=b3g90mwbie2vascccupcxjhj"></script>
我稍微修改了点,发下demo:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>百度地图api自定义地图</title> <script type="text/javascript" src="http://api.map.baidu.com/getscript?v=2.0&ak=b3g90mwbie2vascccupcxjhj"></script> </head> <body> <!-- ps:你的宽和高是多少,它就填充多少 --> <div id="baidumap" style="width:1000px;height:500px;"></div> <script src="../js/baidumap.js"></script> <script> window.onload = () => { window.navigator.geolocation.getcurrentposition(res => { // 初始化百度地图 initmap("baidumap", res.coords.longitude, res.coords.latitude); }, ex => { console.warn("获取失败", ex); }); } </script> </body> </html>
ps:你的宽和高是多少,它就填充多少
baidumap.js:
var map; //创建地图 function createmap(id_str, lng, lat) { map = new bmap.map(id_str); map.centerandzoom(new bmap.point(lng, lat), 15); } //设置地图事件 function setmapevent() { map.enablescrollwheelzoom(); map.enablekeyboard(); map.enabledragging(); map.enabledoubleclickzoom() } // 图标单击事件 function addclickhandler(target, window) { target.addeventlistener("click", function () { target.openinfowindow(window); }); } //向地图添加覆盖物 function addmapoverlay(lng, lat, content) { var markers = [{ content: content, // 一般写详细地址 title: "", imageoffset: { width: -46, height: -21 }, position: { lng: lng, lat: lat } }, ]; for (var index = 0; index < markers.length; index++) { var point = new bmap.point(markers[index].position.lng, markers[index].position.lat); var marker = new bmap.marker(point, { icon: new bmap.icon("http://api.map.baidu.com/lbsapi/createmap/images/icon.png", new bmap.size(20, 25), { imageoffset: new bmap.size(markers[index].imageoffset.width, markers[index].imageoffset.height) }) }); var label = new bmap.label(markers[index].title, { offset: new bmap.size(25, 5) }); var opts = { width: 200, title: markers[index].title, enablemessage: false }; var infowindow = new bmap.infowindow(markers[index].content, opts); marker.setlabel(label); addclickhandler(marker, infowindow); map.addoverlay(marker); }; var labels = []; for (var index = 0; index < labels.length; index++) { var opt = { position: new bmap.point(labels[index].position.lng, labels[index].position.lat) }; var label = new bmap.label(labels[index].content, opt); map.addoverlay(label); }; var plopts = []; var plpath = []; for (var index = 0; index < plopts.length; index++) { var polyline = new bmap.polyline(plpath[index], plopts[index]); map.addoverlay(polyline); } } //向地图添加控件 function addmapcontrol() { var scalecontrol = new bmap.scalecontrol({ anchor: bmap_anchor_bottom_left }); scalecontrol.setunit(bmap_unit_imperial); map.addcontrol(scalecontrol); var navcontrol = new bmap.navigationcontrol({ anchor: bmap_anchor_top_left, type: 0 }); map.addcontrol(navcontrol); var overviewcontrol = new bmap.overviewmapcontrol({ anchor: bmap_anchor_bottom_right, isopen: true }); map.addcontrol(overviewcontrol); } //创建和初始化地图函数:id字符串,经度,纬度,详细信息 function initmap(id_str, lng, lat, content) { console.info(id_str, lng, lat, content); if (content == undefined) { content = "i am here"; //`lng:${lng},lat:${lat}`; // es6语法(默认参数也是es6语法) console.info("没有详细描述"); } createmap(id_str, lng, lat); //创建地图 setmapevent(); //设置地图事件 addmapcontrol(); //向地图添加控件 addmapoverlay(lng, lat, content); //向地图添加覆盖物 }
效果:(也进一步验证了,pc端是根据ip来定位的)
1.4.5.本地存储相关api(必看)
-
cookie
:浏览器和服务器共享(4k) -
localstorage
:浏览器独享(5m)- 每个域名5m,没有过期时间(用户不清理的情况下)
-
sessionstorage
:当前会话使用的存储- 用法和localstorage一样,页面关闭就消失了
1.基础案例
知识点
:
- 设置值:
localstorage.setitem("key", "value")
- 获取值:
localstorage.getitem("key")
- 删除值:
localstorage.removeitem("key")
来个案例:
console.log("-------------设置值---------------------") // 设置值:setitem(key,value) localstorage.setitem("id", 11); localstorage.setitem("name", "小明"); // 其他实现 localstorage.age = 23; // 这种方式也可以 localstorage["gender"] = 1; // 这种方式设置也可以 console.log("-------------获取值---------------------") //获取值:getitem(key) localstorage.getitem("id"); // 其他实现 console.log(localstorage.age); // 这种方式也可以 console.log(localstorage.mmd); // 如果key不存在=>`undefined` console.log(localstorage["gender"]); // 这种方式也可以 console.log(localstorage["mmd"]); // 如果key不存在=>`undefined` console.log("-------------删除值---------------------") // 删除值 localstorage.removeitem("id"); // 其他实现 delete localstorage.age; delete localstorage["gender"]; console.log("-------------遍历值---------------------") // 官方推荐的遍历方式 for (let i = 0; i < localstorage.length; i++) { let key = localstorage.key(i); let value = localstorage.getitem(key); console.log(key, value); }
输出:
-------------设置值--------------------- -------------获取值--------------------- 23 undefined 1 undefined -------------删除值--------------------- -------------遍历值--------------------- name 小明
ps:for in 的方式会把方法也遍历出来,不是我们需要的key-value
2.文章草稿案例
实际场景:保存文章草稿
先看一下正常情况:(一般就是添加一个关闭页面的提示)
但遇到浏览器卡死或者断点就没用了,对于写文章长达好几个小时的作者来说是一个悲剧。。。
通过本地存储实现无缝缓存草稿
<!doctype html> <html> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <title>本地草稿</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <div> <div>文章内容</div> <textarea id="article" rows="20" cols="50"></textarea> <input type="button" value="发布文章" /> </div> <script> window.onload = () => { // 获取文本框对象 let text_obj = document.queryselector("#article"); // 根据文章编号,把草稿内容读取出来(如果没有就为空字符串) text_obj.value = localstorage["5547"] || ''; // 文本内容改变了就执行(输入事件) text_obj.oninput = () => { // 假设当前文章id是5547 localstorage["5547"] = text_obj.value; } // 获取按钮对象 let btn_obj = document.queryselector("input"); btn_obj.onclick = () => { // ajax请求(我这边省略) alert("文章发布成功!"); // 清除对应文章的草稿 delete localstorage["5547"]; } } </script> </body> </html>
效果演示:
ps:websql、indexeddb
因为安全性,现在基本上不用了(官方也不在维护了)
题外话:
localstorage
基本上够用了(数据库都暴露在前端了,还有啥安全性?)
扩展:canvas画布
这个几年前已经说过了,感兴趣的可以自己回顾一下:
说句实话,搞后端的不大可能自己弄画布相关的api,一般用用类似于echarts
就可以了(在canvas基础上的封装实现)
坑点
给canvas
设置宽高的时候要通过内嵌的属性width
和height
来设置,如果通过css设置则会失真
ps:通过css设置,相当于把默认画布大小(
302*152
左右)拉伸一下
ps:svg
是矢量图,canvas
是位图
h5结语
应该,貌似,没有忘记说的吧?几年前贴的思维导图(学习笔记)虽然丑了点,但知识还是挺全的,不清楚的点可以翻哦~
web大前端时代之:html5+css3入门系列:
最后贴一下demo:
- new:https://github.com/lotapp/basecode/tree/master/javascript/0.h5_c3/h5
- old:https://github.com/dunitian/lothtml5
下节预估:一文入门css3
上一篇: 选择PHP作为网站开发语言的原因分享
下一篇: 预测python数据分析师的工资