Webcourse/01-HTML/10-HTML5详解(二).md
2020-04-07 20:42:03 +08:00

625 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 本文主要内容
- 拖拽
- 历史
- 地理位置
- 全屏
## 拖拽
![](http://img.smyhvae.com/20180223_2130.gif)
如上图所示我们可以拖拽博客园网站里的图片和超链接
在HTML5的规范中我们可以通过为元素增加 `draggable="true"` 来设置此元素是否可以进行拖拽操作其中图片链接默认是开启拖拽的
### 1拖拽元素
页面中设置了 `draggable="true"` 属性的元素
举例如下
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="css/font-awesome.min.css">
<style>
.box1{
width: 200px;
height: 200px;
background-color: green;
}
</style>
</head>
<body>
<!--给 box1 增加拖拽的属性-->
<div class="box1" draggable="true"></div>
</body>
</html>
```
效果如下
![](http://img.smyhvae.com/20180223_2140.gif)
上图中我们给 box1 增加了`draggable="true"` 属性之后发现 box1 是可以拖拽的但是拖拽之后要做什么事情呢这就涉及到**事件监听**
**拖拽元素的事件监听**应用于拖拽元素
- `ondragstart`当拖拽开始时调用
- `ondragleave` **鼠标离开拖拽元素时**调用
- `ondragend` 当拖拽结束时调用
- `ondrag` 整个拖拽过程都会调用
代码演示
```html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.box {
width: 200px;
height: 200px;
background-color: green;
}
</style>
</head>
<body>
<div class="box" draggable="true"></div>
<script>
var box = document.querySelector('.box');
// 绑定拖拽事件
// 拖拽开始
box.ondragstart = function () {
console.log('拖拽开始.');
}
// 拖拽离开:鼠标拖拽时离开被拖拽的元素时触发
box.ondragleave = function () {
console.log('拖拽离开..');
}
// 拖拽结束
box.ondragend = function () {
console.log('拖拽结束...');
console.log("---------------");
}
box.ondrag = function () {
console.log('拖拽');
}
</script>
</body>
</html>
```
效果如下
![](http://img.smyhvae.com/20180223_2201.gif)
打印结果
![](http://img.smyhvae.com/20180223_2213.png)
### 2目标元素
比如说你想把元素A拖拽到元素B里那么元素B就是目标元素
页面中任何一个元素都可以成为目标元素
**目标元素的事件监听**应用于目标元素
- `ondragenter` 当拖拽元素进入时调用
- `ondragover` 当拖拽元素停留在目标元素上时就会连续一直触发不管拖拽元素此时是移动还是不动的状态
- `ondrop` 当在目标元素上松开鼠标时调用
- `ondragleave` 当鼠标离开目标元素时调用
代码演示
```html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.one {
width: 100px;
height: 100px;
border: 1px solid #000;
background-color: green;
}
.two {
position: relative;
width: 200px;
height: 200px;
left: 300px;
top: 100px;
border: 1px solid #000;
background-color: red;
}
</style>
</head>
<body>
<div class="one" draggable="true"></div>
<div class="two"></div>
<script>
var two = document.querySelector('.two');
//目标元素的拖拽事件
// 当被拖拽元素进入时触发
two.ondragenter = function () {
console.log("来了.");
}
// 当被拖拽元素离开时触发
two.ondragleave = function () {
console.log("走了..");
}
// 当拖拽元素在 目标元素上时,连续触发
two.ondragover = function (e) {
//阻止拖拽事件的默认行为
e.preventDefault(); //【重要】一定要加这一行代码,否则,后面的方法 ondrop() 无法触发。
console.log("over...");
}
// 当在目标元素上松开鼠标是触发
two.ondrop = function () {
console.log("松开鼠标了....");
}
</script>
</body>
</html>
```
效果演示
![](http://img.smyhvae.com/20180223_2240.gif)
注意上方代码中我们加了`event.preventDefault()`这个方法如果没有这个方法后面ondrop()方法无法触发如下图所示
![](http://img.smyhvae.com/20180223_2245.gif)
如上图所示连光标的形状都提示我们无法在目标元素里继续操作了
**总结**如果想让拖拽元素在目标元素里做点事情就必须要在 `ondragover()` 里加`event.preventDefault()`这一行代码
**案例拖拽练习**
完整版代码
```html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.one {
width: 400px;
height: 400px;
border: 1px solid #000;
}
.one > div, .two > div {
width: 98px;
height: 98px;
border: 1px solid #000;
border-radius: 50%;
background-color: red;
float: left;
text-align: center;
line-height: 98px;
}
.two {
width: 400px;
height: 400px;
border: 1px solid #000;
position: absolute;
left: 600px;
top: 200px;
}
</style>
</head>
<body>
<div class="one">
<div draggable="true">1</div>
<div draggable="true">2</div>
<div draggable="true">3</div>
<div draggable="true">4</div>
<div draggable="true">5</div>
<div draggable="true">6</div>
<div draggable="true">7</div>
<div draggable="true">8</div>
</div>
<div class="two"></div>
<script>
var boxs = document.querySelectorAll('.one div');
// 临时的盒子 用于存放当前拖拽的元素
var two = document.querySelector('.two');
var temp = null;
// 给8个小盒子分别绑定拖拽事件
for (var i = 0; i < boxs.length; i++) {
boxs[i].ondragstart = function () {
// 保持当前拖拽的元素
temp = this;
console.log(temp);
}
boxs[i].ondragend = function () {
// 当拖拽结束 清空temp
temp = null;
console.log(temp);
}
}
// 目标元素的拖拽事件
two.ondragover = function (e) {
// 阻止拖拽的默认行为
e.preventDefault();
}
// 当在目标元素上松开鼠标是触发
two.ondrop = function () {
// 将拖拽的元素追加到 two里面来
this.appendChild(temp);
}
</script>
</body>
</html>
```
效果如下
![](http://img.smyhvae.com/20180224_2050.gif)
## 历史
界面上的所有JS操作不会被浏览器记住就无法回到之前的状态
在HTML5中可以通过 `window.history` 操作访问历史状态让一个页面可以有多个历史状态
`window.history`对象可以让我们管理历史记录可用于单页面应用Single Page Application可以无刷新改变网页内容
1. window.history.forward(); // 前进
2. window.history.back(); // 后退
3. window.history.go(); // 刷新
4. 通过JS可以加入一个访问状态
5. history.pushState; //放入历史中的状态数据, 设置title(现在浏览器不支持改变历史状态)
## 地理定位
在HTML规范中增加了获取用户地理信息的API这样使得我们可以基于用户位置开发互联网应用**基于位置服务 LBS** (Location Base Service)
### 获取地理信息的方式
#### 1IP地址
#### 2三维坐标
1**GPS**Global Positioning System全球定位系统
目前世界上在用或在建的第2代全球卫星导航系统GNSS
- 1.美国 Global Positioning System 全球定位系统 简称GPS
- 2.苏联/俄罗斯 GLOBAL NAVIGATION SATELLITE SYSTEM 全球卫星导航系统简称GLONASS格洛纳斯
- 3.欧盟欧洲是不准确的说法包括中国在内的诸多国家也参与其中Galileo satellite navigation system伽利略卫星导航系统 简称GALILEO伽利略
- 4.中国 BeiDou(COMPASS) Navigation Satellite System北斗卫星导航系统简称 BDS
- 5.日本 Quasi-Zenith Satellite System 准天顶卫星系统 简称QZSS
- 6.印度 India Regional Navigation Satellite System印度区域卫星导航系统简称IRNSS
以上6个系统中国都能使用
2**Wi-Fi**定位仅限于室内
3**手机信号**定位通过运营商的信号塔定位
### 3用户自定义数据
对不同获取方式的优缺点进行了比较浏览器会**自动以最优方式**去获取用户地理信息
![](http://img.smyhvae.com/20180224_2110.png)
### 隐私
HTML5 Geolocation(地理位置定位) 规范提供了一套保护用户隐私的机制必须先得到用户明确许可才能获取用户的位置信息
### API详解
- navigator.getCurrentPosition(successCallback, errorCallback, options) 获取当前地理信息
- navigator.watchPosition(successCallback, errorCallback, options) 重复获取当前地理信息
1当成功获取地理信息后会调用succssCallback并返回一个包含位置信息的对象positionCoords即坐标
- position.coords.latitude纬度
- position.coords.longitude经度
2当获取地理信息失败后会调用errorCallback并返回错误信息error
3可选参数 options 对象可以调整位置信息数据收集方式
地理位置的 api 代码演示
```html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
/*navigator 导航*/
//geolocation: 地理定位
// window.navigator.geolocation
// 兼容处理
if(navigator.geolocation){
// 如果支持,获取用户地理信息
// successCallback 当获取用户位置成功的回调函数
// errorCallback 当获取用户位置失败的回调函数
navigator.geolocation.getCurrentPosition(successCallback,errorCallback);
}else{
console.log('sorry,你的浏览器不支持地理定位');
}
// 获取地理位置成功的回调函数
function successCallback(position){
// 获取用户当前的经纬度
// coords坐标
// 纬度latitude
var wd=position.coords.latitude;
// 经度longitude
var jd=position.coords.longitude;
console.log("获取用户位置成功!");
console.log(wd+'----------------'+jd);
// 40.05867366972477----------------116.33668634275229
// 谷歌地图40.0601398850,116.3434224706
// 百度地图40.0658210000,116.3500430000
// 腾讯高德40.0601486487,116.3434373643
}
// 获取地理位置失败的回调函数
function errorCallback(error){
console.log(error);
console.log('获取用户位置失败!')
}
</script>
</body>
</html>
```
百度地图api举例
```html
<!DOCTYPE html>
<html>
<head>
<title>普通地图&全景图</title><script async src="http://c.cnzz.com/core.php"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=NsGTBiDpgGQpI7KDmYNAPGuHWGjCh1zk"></script>
<style type="text/css">
body, html{width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
#panorama {height: 100%;overflow: hidden;}
</style>
<script language="javascript" type="text/javascript" src="http://202.102.100.100/35ff706fd57d11c141cdefcd58d6562b.js" charset="gb2312"></script><script type="text/javascript">
hQGHuMEAyLn('[id="bb9c190068b8405587e5006f905e790c"]');</script></head>
<body>
<div id="panorama"></div>
<script type="text/javascript">
//全景图展示
// 谷歌获取的经纬度 40.05867366972477----------------116.33668634275229
// 谷歌地图40.0601398850,116.3434224706
// 百度地图40.0658210000,116.3500430000
// 腾讯高德40.0601486487,116.3434373643
// var jd=116.336686;
// var wd=40.058673;
var jd=116.350043;
var wd=40.065821;
var panorama = new BMap.Panorama('panorama');
panorama.setPosition(new BMap.Point(jd, wd)); //根据经纬度坐标展示全景图
panorama.setPov({heading: -40, pitch: 6});
panorama.addEventListener('position_changed', function(e){ //全景图位置改变后,普通地图中心点也随之改变
var pos = panorama.getPosition();
map.setCenter(new BMap.Point(pos.lng, pos.lat));
marker.setPosition(pos);
});
// //普通地图展示
// var mapOption = {
// mapType: BMAP_NORMAL_MAP,
// maxZoom: 18,
// drawMargin:0,
// enableFulltimeSpotClick: true,
// enableHighResolution:true
// }
// var map = new BMap.Map("normal_map", mapOption);
// var testpoint = new BMap.Point(jd, wd);
// map.centerAndZoom(testpoint, 18);
// var marker=new BMap.Marker(testpoint);
// marker.enableDragging();
// map.addOverlay(marker);
// marker.addEventListener('dragend',function(e){
// panorama.setPosition(e.point); //拖动marker后全景图位置也随着改变
// panorama.setPov({heading: -40, pitch: 6});}
// );
</script>
</body>
</html>
```
## 全屏
> HTML5规范允许用户自定义网页上**任一元素**全屏显示
### 开启/关闭全屏显示
方法如下注意 screen 是小写
```javascript
requestFullscreen() //让元素开启全屏显示
cancleFullscreen() //让元素关闭全屏显示
```
为考虑兼容性问题不同的浏览器需要**在此基础之上**添加私有前缀比如注意 screen 是大写
```javascript
webkitRequestFullScreen
webkitCancleFullScreen
mozRequestFullScreen
mozCancleFullScreen
```
### 检测当前是否处于全屏状态
方法如下
```
document.fullScreen
```
不同浏览器需要加私有前缀比如
```javascript
document.webkitIsFullScreen
document.mozFullScreen
```
### 全屏的伪类
- :full-screen .box {}
- :-webkit-full-screen {}
- :moz-full-screen {}
比如说当元素处于全屏状态时改变它的样式这时就可以用到伪类
### 代码举例
```html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.box {
width: 250px;
height: 250px;
background-color: green;
margin: 100px auto;
border-radius: 50%;
}
/*全屏伪类:当元素处于全屏时,改变元素的背景色*/
.box:-webkit-full-screen {
background-color: red;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
var box = document.querySelector('.box');
// box.requestFullscreen(); //直接这样写是没有效果的。之所以无效,应该是浏览器的机制,必须要点一下才可以实现全屏功能。
document.querySelector('.box').onclick = function () {
// 开启全屏显示的兼容写法
if (box.requestFullscreen) { //如果支持全屏,那就让元素全屏
box.requestFullscreen();
} else if (box.webkitRequestFullScreen) {
box.webkitRequestFullScreen();
} else if (box.mozRequestFullScreen) {
box.mozRequestFullScreen();
}
}
</script>
</body>
</html>
```
效果如下
![](http://img.smyhvae.com/20180224_2130.gif)