拖拽接口
學(xué)習(xí)拖拽睦焕,主要是學(xué)習(xí)拖拽事件遗锣,根據(jù)應(yīng)用于被拖拽元素和應(yīng)用于目標(biāo)元素的不同生真,我們一般可以將拖拽事件分類:
- 應(yīng)用于被拖拽元素的拖拽事件:
- ondragstrat:當(dāng)拖拽開始時調(diào)用铣除;
- ondrag:當(dāng)拖拽的時候闹丐,在整個拖拽過程都會調(diào)用
- ondragleave:當(dāng)鼠標(biāo)離開拖拽元素的時候調(diào)用
- ondragend:當(dāng)拖拽結(jié)束時調(diào)用
觸發(fā)順序:
1-->ondragstart 拖拽開始
2-->ondrag 拖拽過程中(持續(xù)拖拽 持續(xù)觸發(fā))
3-->ondragleave 離開拖拽元素時
4--> ondrag 還在拖拽過程中(持續(xù)拖拽 持續(xù)觸發(fā))
5--> 拖拽結(jié)束
- 拖拽事件應(yīng)用于目標(biāo)元素:
- ondragenter:應(yīng)用于目標(biāo)元素,當(dāng)拖拽元素進(jìn)入目標(biāo)元素時調(diào)用赚导;
- ondragover:當(dāng)拖拽元素停留在目標(biāo)元素上時調(diào)用茬缩;
-
ondrop:當(dāng)拖拽元素在目標(biāo)元素上松開鼠標(biāo)放下時調(diào)用;
注意:瀏覽器有個默認(rèn)行為吼旧,默認(rèn)阻止ondrop事件:那么我們必須在ondragover中阻止瀏覽器的默認(rèn)行為凰锡。 - ondragleave:當(dāng)鼠標(biāo)離開目標(biāo)元素時調(diào)用
使用上面的這些事件,寫個簡單的拖拽案例:
<!DOCTYPE html>
<html>
<head>
<title>demo</title>
<style type="text/css">
p{
background-color: #888;
}
div{
width: 200px;
height: 200px;
border: 1px solid red;
float: left;
margin-left: 50px;
}
</style>
</head>
<body>
<div class="div1" id="div1">
<p id="pe" draggable="true">試著把我拖過去</p>
</div>
<div class="div2" id="div2"></div>
<script type="text/javascript">
//被拖拽元素
var p = document.querySelector("#pe");
p.ondragstart = function(){
console.log('ondragstart 拖拽開始了');
}
p.ondragend = function(){
console.log('ondragend 拖拽結(jié)束了');
}
p.ondragleave = function(){
console.log('ondragleave 離開拖拽元素了');
}
p.ondrag = function(){
console.log('ondrag 拖拽過程中');
}
// 拖拽目標(biāo)
var div2 = document.querySelector("#div2");
div2.ondragenter=function(){
console.log("ondragenter 拖拽元素進(jìn)入目標(biāo)元素了");
}
div2.ondragover = function(e){
// 注意:瀏覽器有個默認(rèn)行為圈暗,默認(rèn)阻止ondrop事件:那么我們必須在ondragover中(一定要這里)阻止瀏覽器的默認(rèn)行為掂为。
console.log("ondragover 拖拽元素在目標(biāo)元素上時");
e.preventDefault();
}
div2.ondrop = function(){
// 注意:瀏覽器有個默認(rèn)行為,默認(rèn)阻止ondrop事件:那么我們必須在ondragover中阻止瀏覽器的默認(rèn)行為员串。
console.log("ondrop 拖拽元素在目標(biāo)元素上松開鼠標(biāo)放下");
// 添加被拖拽的元素到當(dāng)前目標(biāo)元素勇哗。
div2.appendChild(p);
}
div2.ondragleave = function(){
console.log("ondragleave:鼠標(biāo)離開目標(biāo)元素了");
}
// 拖拽回去
var div1 = document.querySelector("#div1");
div1.ondragover = function(e){
e.preventDefault();
}
div1.ondrop = function(){
div1.appendChild(p);
}
</script>
</body>
</html>
當(dāng)上面的例子還是有很大的問題,只能指定元素拖拽到指定位置寸齐,太局限欲诺。
很多時候,我們希望多個元素能被拖拽渺鹦,同時也有多個目標(biāo)元素瞧栗,即:我希望能夠任意個被拖拽元素,拖拽到任意一個目標(biāo)元素中:
核心是:通過事件捕獲來獲取當(dāng)前被拖拽的元素海铆;先存儲起來迹恐,再通過事件捕獲找到目標(biāo)元素,然后再目標(biāo)元素中使用開始被存儲的值來添加元素卧斟。
<body>
<div class="div1" id="div1">
<p id="pe" draggable="true">試著把我拖過去</p>
</div>
<div class="div2" id="div2"></div>
<script type="text/javascript">
var obj = null;//定義當(dāng)前被拖拽的元素
//被拖拽元素
document.ondragstart = function(e){
// 通過事件捕獲來獲取當(dāng)前被拖拽的元素殴边;
// e.target事件源對象
e.target.style.opacity = '.5';
e.target.parentNode.style.borderWidth = "3px";
//將被拖拽的元素放到一個全局對象中保存,當(dāng)拖拽的結(jié)束的時候添加到目標(biāo)元素中珍语。
obj = e.target;
}
document.ondragend = function(e){
e.target.style.opacity = '1';
e.target.parentNode.style.borderWidth = "1px";
}
// 拖拽目標(biāo)
document.ondragover = function(e){
e.preventDefault();
}
document.ondrop = function(e){
e.target.appendChild(obj);
}
</script>
</body>
當(dāng)時這種情況有個問題:使用了一個全局變量obj锤岸;一般情況下我們不到最后的時候都不要使用全局變量,以為使用全局變量有兩個問題:
1.不安全板乙,全局變量任何人都能使用是偷,你也可以該,我也可以該募逞;
2.全局變量會導(dǎo)致內(nèi)存泄漏蛋铆;
為了解決上述問題 ,我們使用另外一種方式來存儲這個全局對象放接;
通過dataTransfer來實(shí)現(xiàn)數(shù)據(jù)的存儲和獲却汤病:
通過事件對象e中的dataTransfer里的setData()來實(shí)現(xiàn)數(shù)據(jù)的存儲和獲取
setData(format,data);
format:數(shù)據(jù)類型,一般有兩種:text/html纠脾、text/uri-list
data:數(shù)據(jù):一般來說是字符串
這里設(shè)置的值玛瘸,只能在ondrop里面取得蜕青;
存儲
e.dataTransfer.setData("text/html",e.target.id)
獲取:
var id = e.dataTransfer.getData("text/html");
e.target.appendChild(document.getElementById(id));
完整代碼:
<!DOCTYPE html>
<html>
<head>
<title>demo</title>
<style type="text/css">
p{
background-color: #888;
}
div{
width: 200px;
height: 200px;
border: 1px solid red;
float: left;
margin-left: 50px;
}
</style>
</head>
<body>
<div class="div1" id="div1">
<p id="pe" draggable="true">試著把我拖過去</p>
</div>
<div class="div2" id="div2"></div>
<script type="text/javascript">
//被拖拽元素
document.ondragstart = function(e){
e.target.style.opacity = '.5';
e.target.parentNode.style.borderWidth = "3px";
obj = e.target;
// 通過事件對象e中的dataTransfer里的setData()來實(shí)現(xiàn)數(shù)據(jù)的存儲和獲取
// setData(format,data);
// format:數(shù)據(jù)類型糊渊,一般有兩種:text/html右核、text/uri-list
// data:數(shù)據(jù):一般來說是字符串
//這里設(shè)置的值,只能再ondrop里面取得渺绒;
e.dataTransfer.setData("text/html",e.target.id);
}
document.ondragend = function(e){
e.target.style.opacity = '1';
e.target.parentNode.style.borderWidth = "1px";
}
// 拖拽目標(biāo)
document.ondragover = function(e){
e.preventDefault();
}
document.ondrop = function(e){
// 通過dataTransfer.setData()存儲的數(shù)據(jù)只能再ondrop事件中獲群睾取;
var id = e.dataTransfer.getData("text/html");
e.target.appendChild(document.getElementById(id));
}
</script>
</body>
</html>
地理定位
Geolocation(地理定位)芒篷,用于獲取用戶位置的信息搜变;
在H5規(guī)范中采缚,增加獲取用戶地理定位信息的API针炉,我們可以發(fā)送一個位置信息的請求,用戶同意后扳抽,瀏覽器會返回一個包含經(jīng)度和維度的位置信息篡帕!那么我們可以基于用戶位置開發(fā)互聯(lián)網(wǎng)應(yīng)用,即基于位置服務(wù)贸呢;
了解獲取位置的方式:
1.IP地址:任何能上網(wǎng)的電腦都可以镰烧,不夠精確
2.GPS:精準(zhǔn),但是時間長楞陷,耗電怔鳖。
3.WiFi:精準(zhǔn),但在鄉(xiāng)村接入點(diǎn)少
4.手機(jī)信號:相當(dāng)精準(zhǔn)固蛾,但需要能夠訪問手機(jī)設(shè)備等
5.用戶自定義:可能不夠精準(zhǔn)结执,特別是當(dāng)用戶位置改變。
注意:
瀏覽器是自動選擇定位方式艾凯,我們無法設(shè)置献幔;
瀏覽器默認(rèn)地理位置為私密信息,所以瀏覽器會彈出一個請求趾诗,是否用戶允許獲取位置蜡感。
語法:
navigator.geolocation.getCurrentPosition(successCallback,errorCallback,option);
navigator.geolocation.getCurrentPosition(success,error,option);
第一個參數(shù):success;獲取當(dāng)前地理信息成功時的回調(diào)
第二個參數(shù):error;獲取當(dāng)前地理信息失敗時的回調(diào)
第三個參數(shù):option;可以設(shè)置獲取數(shù)據(jù)的方式,如:
enableHighAccuracy:true/false;表示是否使用高精度
timeout:設(shè)置超時時間,單位ms;
maximumAge:可以設(shè)置瀏覽器重新獲取地理信息的時間間隔,單位也時ms;
如:
navigator.geolocation.getCurrentPosition(showPosition,showError,{
enableHighAccuracy:true,
timeout:3000,
});
成功獲取定位后的回調(diào)
當(dāng)獲取地理信息成功時, getCurrentPosition() 方法會返回一個對象,這個地理信息對象,會通過參數(shù)傳遞給成功后的回調(diào),如下position就是代表獲取成的地理信息對象
function showPosition(position){
div.innerHTML="Latitude:" + position.coords.latitude ;
}
注意:這個返回的地理信息對象會有一個坐標(biāo)信息,對應(yīng)很多屬性:
coords.latitude 十進(jìn)制數(shù)的緯度
coords.longitude 十進(jìn)制數(shù)的經(jīng)度
coords.accuracy 位置精度
coords.altitude 海拔恃泪,海平面以上以米計(jì)
coords.altitudeAccuracy 位置的海拔精度
coords.heading 方向郑兴,從正北開始以度計(jì)
coords.speed 速度,以米/每秒計(jì)
timestamp 響應(yīng)的日期/時間
失敗獲取定位時回調(diào),也會有一個對象贝乎,如下error
function showError(error){
switch(error.code) {
case error.PERMISSION_DENIED:
x.innerHTML="用戶拒絕對獲取地理位置的請求杈笔。"
break;
case error.POSITION_UNAVAILABLE:
x.innerHTML="位置信息是不可用的。"
break;
case error.TIMEOUT:
x.innerHTML="請求用戶地理位置超時糕非。"
break;
case error.UNKNOWN_ERROR:
x.innerHTML="未知錯誤蒙具。"
break;
}
}
錯誤代碼:
Permission denied - 用戶不允許地理定位
Position unavailable - 無法獲取當(dāng)前位置
Timeout - 操作超時
代碼:
script type="text/javascript">
var div =document.getElementsClassName("demo")[0];
function getLocation(){
// 能力測試,看是否支持或者用戶是否允許;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition,showError,{});
}else{
x.innerHTML = "Geolocation is not supported by this browser";
}
}
function showPosition(position){
div.innerHTML="Latitude:" + position.coords.latitude + "<br/> Longitude:" + position.coords.longitude;
}
function showError(error){
switch(error.code) {
case error.PERMISSION_DENIED:
x.innerHTML="用戶拒絕對獲取地理位置的請求球榆。"
break;
case error.POSITION_UNAVAILABLE:
x.innerHTML="位置信息是不可用的。"
break;
case error.TIMEOUT:
x.innerHTML="請求用戶地理位置超時禁筏。"
break;
case error.UNKNOWN_ERROR:
x.innerHTML="未知錯誤持钉。"
break;
}
}
</script>
當(dāng)既然我們個人無法獲取地理信息,我們可以通過第三方的接口API來獲取篱昔,如百度地圖每强,谷歌地圖;
例子:借助百度地圖提供的接口,來實(shí)現(xiàn)當(dāng)前地理定位:
可以查看:百度地圖開放平臺
很多都寫好了
注意:一般需要密鑰州刽,即授權(quán)碼
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的密鑰"></script>
<!DOCTYPE html>
<html>
<head>
<title>普通地圖&全景圖</title>
<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=您的密鑰"></script>
<style type="text/css">
body, html{width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微軟雅黑";}
#panorama {height: 50%;overflow: hidden;}
#normal_map {height:50%;overflow: hidden;}
</style>
</head>
<body>
<div id="panorama"></div>
<div id="normal_map"></div>
<script type="text/javascript">
//全景圖展示
var panorama = new BMap.Panorama('panorama');
panorama.setPosition(new BMap.Point(120.320032, 31.589666)); //根據(jù)經(jīng)緯度坐標(biāo)展示全景圖
panorama.setPov({heading: -40, pitch: 6});
panorama.addEventListener('position_changed', function(e){ //全景圖位置改變后空执,普通地圖中心點(diǎn)也隨之改變
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(120.320032, 31.589666);
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>