1.HTML5
上節回顧:一文讀懂ES6(附PY3對比) | 一文入門NodeJS
演示demo:https://github.com/lotapp/BaseCode/tree/master/javascript/0.H5_C3/H5
參考文檔:https://www.w3cschool.cn/html5 | 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,有利於盲人閱讀等,官方文檔:http://www.w3school.com.cn/html/html5_semantic_elements.asp
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效果沒語義標簽好
效果圖
可以看看我幾年前寫的文章:http://www.cnblogs.com/dunitian/p/5123741.html
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]-->
來個語義化的頁面演示:https://github.lesschina.com/html5/
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
官方文檔:http://www.w3school.com.cn/html5/html_5_audio.asp and http://www.w3school.com.cn/html5/html_5_video.asp
主要屬性:
- 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+
)cyberplayer
(百度)- PS:基於
video.js
- URL:https://cloud.baidu.com/doc/MCT/Web-SDK.html
- PS:基於
tencentplayer
(騰訊)webtorrent
(開源1.9w+
)Flv.js
(Bilibili開源1.4w+
)DPlayer
(開源5.3k+
)jwplayer
(開源1.8k+
)- Chimee組件化框架(開源
1.65k+
) youkuplayer
(優酷)
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.擴展說明
這個之前也說的很詳細了,這邊列了常用屬性就完事了,感興趣可以去老文章看看:https://www.cnblogs.com/dunitian/p/5125371.html
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的問題:http://www.cnblogs.com/dotnetcrazy/p/10061671.html#3.4.特殊的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:解決回顧:https://www.cnblogs.com/dotnetcrazy/p/10061671.html#業余拓展
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演示
)
擴展:小程序版地圖案例:https://www.cnblogs.com/dotnetcrazy/p/10597311.html#_map17
2.地圖案例
PS:很多公司官網介紹里面的地圖其實就是通過地圖生成器
生成的:http://api.map.baidu.com/lbsapi/createmap/index.html
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畫布
這個幾年前已經說過了,感興趣的可以自己回顧一下:http://www.cnblogs.com/dunitian/p/5149156.html
說句實話,搞后端的不大可能自己弄畫布相關的API,一般用用類似於Echarts
就可以了(在Canvas基礎上的封裝實現)
坑點
給canvas
設置寬高的時候要通過內嵌的屬性width
和height
來設置,如果通過CSS設置則會失真
PS:通過CSS設置,相當於把默認畫布大小(
302*152
左右)拉伸一下
PS:SVG
是矢量圖,Canvas
是位圖
H5結語
應該,貌似,沒有忘記說的吧?幾年前貼的思維導圖(學習筆記)雖然丑了點,但知識還是挺全的,不清楚的點可以翻哦~
Web大前端時代之:HTML5+CSS3入門系列:http://www.cnblogs.com/dunitian/p/5121725.html
最后貼一下Demo:
- new:https://github.com/lotapp/BaseCode/tree/master/javascript/0.H5_C3/H5
- old:https://github.com/dunitian/LoTHTML5
下節預估:一文入門CSS3