欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

一文入门HTML5

程序员文章站 2022-11-27 15:34:52
1.HTML5 上节回顾:一文读懂ES6(附PY3对比) | 一文入门NodeJS 演示demo: 参考文档: | HTML5主要目的是为了在移动设备上支持多媒体,eg: 、``(PS:Flash太重量级) 这么多年下来了,有些API被广泛支持,有些API逐渐淡化在视线中了(eg: 、`Indexe ......

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:websqlindexeddb等)

我们来看下常用的新特性:

  1. 取消了过时的一些显示效果标记,eg:<font><center>
    • ps:用css实现
  2. 新表单元素引入
    • eg:input新的type:numberurlemail...
  3. 新语义标签的引入
    • eg:<nav><header><footer>...
  4. 多媒体以及图形方面的扩展
    • eg:<canvas><video><audio>
  5. web本地存储
    • eg:localstorage
  6. 一些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>

浏览器基本上都是支持的
一文入门HTML5

但是低版本不能识别(eg:ie8
一文入门HTML5

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>

兼容解决:
一文入门HTML5

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的宽屏)

一文入门HTML5

大致框架: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

主要属性:

  1. controls:显示控件
  2. muted:静音
  3. autoplay:自动播放
  4. loop:循环播放
  5. 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:大家有没有发现,现在视频网站都是自动播放,很多默认都是静音?

但是需要注意下不同浏览器的兼容格式:
一文入门HTML5
一文入门HTML5

上面代码的兼容写法如下:

<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:这几款播放器用的挺多:(推荐加粗项目)

  1. video.js(开源2.45w+
    • url:
    • vue版:
  2. cyberplayer(百度)
  3. tencentplayer(腾讯)
    • url:
  4. webtorrent(开源1.9w+)
    • url:
  5. flv.js(bilibili开源1.4w+
  6. dplayer(开源5.3k+
  7. jwplayer(开源1.8k+
    • url:
  8. chimee组件化框架(开源1.65k+
  9. youkuplayer(优酷)
    • url:

1.3.新表单元素

1.3.1.智能表单类型

  1. email:合法邮箱
  2. url:合法url地址
  3. number:合法数字
  4. date:显示日期
  5. month:显示月份
  6. week:显示第几周
  7. time:显示时间
  8. range:滑动条
  9. search:搜索框
  10. color:拾色器

使用setcustomvalidity()设置自定义验证

1.3.2.表单属性

1.form属性

  1. autocomplete="on|off":是否自动完成
  2. novalidate="true|false":不校验|校验数据

2.input属性

  1. required:必填选项
  2. autofocus:自动获取焦点
  3. placeholder:提示信息
  4. maxlength:最大字符数
  5. autocomplete:取消候选词
    • ps:一般都是自己设置,如果不关闭会重叠(百度代码:<input value="" maxlength="255" autocomplete="off">
  6. multiple:多选效果
  7. 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.获取页面元素

获取页面元素

  1. document.queryselector("选择器"):返回符合选择器的第一个元素
  2. document.queryselectorall("选择器"):返回所有符合选择器的元素
  3. ps:选择器可以是css中的任意一种(你css怎么写的,这边就怎么写)
    • eg:document.queryselector("#id")document.queryselector(".class")document.queryselector("tag")

举个栗子:我想让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>

效果:
一文入门HTML5

通过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>

效果:
一文入门HTML5

2.类名操作

类名操作(页面元素对象的方法)

  1. xxdom.classlist.add("类名"):给当前dom元素添加类样式
  2. dom.classlist.remove("类名"):移除当前dom元素的类样式
  3. dom.classlist.contains("类名"):检测是否包含类样式
  4. 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>

效果:
一文入门HTML5

ps:es6兼容可以使用babelcnpm i babel-core@old > babel-core > browser.min.js

回顾:cnpm配置:https://www.cnblogs.com/dotnetcrazy/p/10118756.html#1.1.npm国内镜像

3.自定义属性

自定义属性:在标签中的data-自定义属性名

  1. 获取自定义属性:dom.dataset.自定义属性名 or dom.dataset["自定义属性名"]
  2. 设置自定义属性:dom.dataset.自定义属性名 = xxx or dom.dataset["自定义属性名"] = xxx
  3. 删除自定义属性:delete dom.dataset.自定义属性名 or delete dom.dataset["自定义属性名"]
  4. 一般属性:
    • 获取某个属性: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

现在可以用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-corebabel-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>

图示:
一文入门HTML5

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>

图示:
一文入门HTML5

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

  1. 是否联网:window.navigator.online
    • ps:对于app来说:一般联网就加载最新的资源,没网就加载离线资源
  2. 常用事件:主要是看当前是联网还是断网,然后监听对应的断网或者联网事件
    • 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)
};

经过实验发现,事件只会执行一次,而且属于有'我没你'的互斥现象,演示如下:

一文入门HTML5
一文入门HTML5

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演示
一文入门HTML5

扩展:小程序版地图案例:

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>

一文入门HTML5

我稍微修改了点,发下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来定位的)
一文入门HTML5


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.文章草稿案例

实际场景:保存文章草稿

先看一下正常情况:(一般就是添加一个关闭页面的提示)

但遇到浏览器卡死或者断点就没用了,对于写文章长达好几个小时的作者来说是一个悲剧。。。

一文入门HTML5

通过本地存储实现无缝缓存草稿

<!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>

效果演示:
一文入门HTML5

ps:websql、indexeddb因为安全性,现在基本上不用了(官方也不在维护了)

题外话:localstorage基本上够用了(数据库都暴露在前端了,还有啥安全性?)

扩展:canvas画布

这个几年前已经说过了,感兴趣的可以自己回顾一下:

说句实话,搞后端的不大可能自己弄画布相关的api,一般用用类似于echarts就可以了(在canvas基础上的封装实现)

坑点

canvas设置宽高的时候要通过内嵌的属性widthheight来设置,如果通过css设置则会失真

ps:通过css设置,相当于把默认画布大小(302*152左右)拉伸一下

ps:svg是矢量图,canvas是位图

h5结语

应该,貌似,没有忘记说的吧?几年前贴的思维导图(学习笔记)虽然丑了点,但知识还是挺全的,不清楚的点可以翻哦~

web大前端时代之:html5+css3入门系列:

最后贴一下demo:

  1. new:https://github.com/lotapp/basecode/tree/master/javascript/0.h5_c3/h5
  2. old:https://github.com/dunitian/lothtml5

下节预估:一文入门css3