摘要:公共變量最好不要在多個方法中公用,容易在增減的時候出現(xiàn)不必要的定時器運行到最后一天的時候要將定時器清除。程序如圖附上預(yù)覽地址更多內(nèi)容可以訂閱本人微信公眾號,一起開啟前端小白進(jìn)階的世界不給地址是不是對不起你們。
工作時被要求到的,結(jié)合百度地圖api做一個動態(tài)展示標(biāo)注變化的組件,要求地圖展示某一天的標(biāo)注,時間軸要求可以動態(tài)播放每一天的標(biāo)注變化...然后我就開始coding...
如有不好的地方,還請大家指出,我也是小白中的一員,接下來開始正文
準(zhǔn)備工作:
申請百度api密鑰(具體方法我也不多寫了,大家應(yīng)該都會)
了解一下百度地圖API的開發(fā)指南和類參考文檔(如果嫌麻煩的話 可以直接看Demo示例)
一、首先,先加載地圖,你可以用實際的經(jīng)緯度定位、瀏覽器定位、根據(jù)ip定位、根據(jù)城市名定位,這個你可以自己選擇
// 創(chuàng)建Map實例,設(shè)置地圖允許的最小/大級別
var map = this.map;
map.centerAndZoom(new BMap.Point(121.365593, 37.528502), 15); // 初始化地圖,用城市名設(shè)置地圖中心點
//map.enableScrollWheelZoom(true); //啟用滾輪放大縮小
centerAndZoom(center:Point, zoom:Number)
參數(shù)解釋:
Point(lng:Number, lat:Number) 以指定的經(jīng)度和緯度創(chuàng)建一個地理點坐標(biāo)。
zoom:number 地圖縮放級別
二、標(biāo)注的使用(覆蓋物)
結(jié)合百度地圖api示例Demo 設(shè)置點的新圖標(biāo)和添加多個點示例 結(jié)合一下,就可以改寫成添加多個地圖標(biāo)注
//編寫自定義函數(shù),創(chuàng)建標(biāo)注
addMarker: function(point, label, status) {
// var marker = new BMap.Marker(point);
var myIcon = new BMap.Icon("images/rubbish_" + status + ".png", new BMap.Size(32, 32), {
anchor: new BMap.Size(16, 32), //中心點設(shè)置
infoWindowAnchor: new BMap.Size(16, 4) //消息框位置5
});
var marker = new BMap.Marker(point, {
icon: myIcon
});
TimerLine.map.addOverlay(marker);
//跳動的動畫
// marker.setAnimation(BMAP_ANIMATION_BOUNCE);
marker.setAnimation(BMAP_ANIMATION_DROP);
var p = marker.getPosition();
var content = "
";
content = content + " 編號:" + label.content + " |
";
content = content + " 坐標(biāo):" + p.lng + "," + p.lat + " |
";
content = content + " 狀態(tài):" + status + " |
";
content += "
";
var infowindow = new BMap.InfoWindow(content);
//添加綁定事件
addEvent(marker, "click", getAttr);
function getAttr() {
this.openInfoWindow(infowindow);
}
}
百度地圖標(biāo)注添加看懂了,接下來就是動態(tài)添加標(biāo)注,并且隨和日期的變化而變化,比如展示垃圾箱的動態(tài)變化,8.3號清理了顏色為綠色,8.6號沒清理為紅色..
思想:
動態(tài):就要使用ajax異步獲取數(shù)據(jù)
變化:就要使用定時器(setInterval或者 setTimeout)
setInterval 循環(huán)調(diào)用
setTimeout 延遲調(diào)用 1次 具體區(qū)別可以自行百度
動手寫插件
function addEvent(dom, type, fn) {
//對于支持DOM2級事件處理程序addeventListener方法的瀏覽器
if (dom.addEventListener) {
dom.addEventListener(type, fn, false);
} else if (dom.attachEvent) {
//對于不支持addEventListener方法但支持attchEvent方法的瀏覽器
dom.attachEvent("on" + type, fn);
} else {
//對于不支持以上兩種,但支持on+"事件名"的瀏覽器
dom["on" + type] = fn;
}
}
var TimerLine = {
data: {
containerDiv: "timerline", //容器盒子id
datesDiv:"dates",//日期盒子id
btnsDiv:"timerlineBtns",
btns: {
play: "timerbtn-play",
stop: "timerbtn-stop",
pre:"timerbtn-pre",
next:"timerbtn-next"
},
processDiv:"processbar", //進(jìn)度條div
},
protect:{
lock_play:false,
lock_stop:false,
index_label:1,
index_process:0
},
rubbish_datas: [], //用來存儲ajax獲取到的數(shù)據(jù)
index: 0, //變化的index
Interval_label: null,
Interval_process:null,
map: new BMap.Map("allmap", {
minZoom: 14,
maxZoom: 20
}),
Utils: {
//編寫自定義函數(shù),創(chuàng)建標(biāo)注
addMarker: function(point, label, status) {
// var marker = new BMap.Marker(point);
var myIcon = new BMap.Icon("images/rubbish_" + status + ".png", new BMap.Size(32, 32), {
anchor: new BMap.Size(16, 32), //中心點設(shè)置
infoWindowAnchor: new BMap.Size(16, 4) //消息框位置5
});
var marker = new BMap.Marker(point, {
icon: myIcon
});
TimerLine.map.addOverlay(marker);
//跳動的動畫
// marker.setAnimation(BMAP_ANIMATION_BOUNCE);
marker.setAnimation(BMAP_ANIMATION_DROP);
var p = marker.getPosition();
var content = "
";
content = content + " 編號:" + label.content + " |
";
content = content + " 坐標(biāo):" + p.lng + "," + p.lat + " |
";
content = content + " 狀態(tài):" + status + " |
";
content += "
";
var infowindow = new BMap.InfoWindow(content);
//添加綁定事件
addEvent(marker, "click", getAttr);
function getAttr() {
this.openInfoWindow(infowindow);
}
},
/**
* 地圖標(biāo)注方法
* 參數(shù): datas:標(biāo)注物數(shù)組{date:"",info:{}}
* index:序數(shù)(日期)
* */
mapSetLabel: function(datas, n,isInterval) {
TimerLine.map.clearOverlays();
var index;
console.log(TimerLine.protect.index_label);
if(isInterval){
TimerLine.protect.index_label++;
if (TimerLine.protect.index_label >= TimerLine.rubbish_datas.length - 1) {
TimerLine.protect.index_label = TimerLine.rubbish_datas.length - 1;
clearInterval(TimerLine.Interval_label);
TimerLine.protect.lock_play=false;
}
}
if (n == null) {
if(TimerLine.protect.index_label==0){
TimerLine.protect.index_label=1
}
index = TimerLine.protect.index_label;
} else {
index = parseInt(n);
TimerLine.protect.index_label = index;
}
var info = datas[index].info;
var info_count=0;
var addMarker_Interval=setInterval(function(){
var p = info[info_count].point.split(",");
var p_x = parseFloat(p[0].toString()); //緯度
var p_y = parseFloat(p[1].toString()); //經(jīng)度
//創(chuàng)建label標(biāo)簽
var label = new BMap.Label(info[info_count].title, {
offset: new BMap.Size(20, -10)
});
//創(chuàng)建標(biāo)注點
var point = new BMap.Point(p_x, p_y);
//狀態(tài)(垃圾箱狀態(tài))
var status = info[info_count].status;
//添加標(biāo)注的方法
TimerLine.Utils.addMarker(point, label, status);
info_count++;
if(info_count>=info.length){
clearInterval(addMarker_Interval);
}
},0);
},
//添加日期點擊事件綁定 dates li click
bindEvent: function() {
var datesDiv = document.getElementById("dates");
addEvent(datesDiv,"click",function(e){
var event = e || window.e;
var target = event.target || event.srcElement;
for(var i=0;i
= TimerLine.rubbish_datas.length-1){
TimerLine.protect.index_process = TimerLine.rubbish_datas.length-1;
clearInterval(TimerLine.Interval_process);
TimerLine.protect.lock_play=false;
}
}
var datesDiv = document.getElementById("dates");
var processDiv = document.getElementById(TimerLine.data.processDiv);
if(index==null){
processDiv.style.width =parseInt(processDiv.style.width)+datesDiv.getElementsByTagName("li")[0].offsetWidth+"px";
}else{
processDiv.style.width =datesDiv.getElementsByTagName("li")[0].offsetWidth*parseInt(index+1)+"px";
}
}
},
//TimerLine初始化
init: function() {
this.createMap();
this.ajaxCreate();
//事件綁定
this.bindEvent();
},
createMap: function() {
// 創(chuàng)建Map實例,設(shè)置地圖允許的最小/大級別
var map = this.map;
map.centerAndZoom(new BMap.Point(121.365593, 37.528502), 15); // 初始化地圖,用城市名設(shè)置地圖中心點
//map.enableScrollWheelZoom(true); //啟用滾輪放大縮小
},
ajaxCreate: function() {
var That = this;
var containerDiv = That.data.containerDiv;
$.ajax({
type: "get",
url: "js/json.json",
dataType: "json",
success: function(data) {
containerDiv = document.getElementById(containerDiv); //容器id
That.rubbish_datas = data.result.datas; //
//console.log(That.rubbish_datas);
That.create(containerDiv, That.rubbish_datas);
//日期時間綁定
That.Utils.bindEvent();
}
});
},
create: function(containerDiv, datas) {
var That = this;
var datasDiv ="";
// var datasDiv = "";
datasDiv += "";
for (var i = 0; i < datas.length; i++) {
datasDiv += "- " + datas[i].date + "
";
}
datasDiv += "
";
document.getElementById(That.data.btnsDiv).innerHTML=""
//創(chuàng)建第一天的標(biāo)注
this.Utils.mapSetLabel(datas, 0,false);
// console.log(TimerLine.index);
That.datas = datas;
containerDiv.innerHTML = datasDiv;
},
//播放 暫停 委托事件----時間綁定
bindEvent: function() {
if (this.data.btns == null)
return;
var That = this;
addEvent(document.getElementById(That.data.btnsDiv), "click", function(e) {
var event = e || window.e;
var target = event.target || event.srcElement;
//播放事件
if (target.id == That.data.btns.play) {
if(!TimerLine.protect.lock_play){
if(TimerLine.protect.index_label >= TimerLine.rubbish_datas.length-1){
TimerLine.protect.index_label=0;
var processDiv = document.getElementById(TimerLine.data.processDiv);
var datesDiv = document.getElementById("dates");
processDiv.style.width = datesDiv.getElementsByTagName("li")[0].offsetWidth+"px";
}
if(TimerLine.protect.index_process >= TimerLine.rubbish_datas.length-1){
TimerLine.protect.index_process=0;
}
//
TimerLine.Interval_label = setInterval("TimerLine.Utils.mapSetLabel(TimerLine.rubbish_datas,null,true)", 1000);
TimerLine.Interval_process = setInterval("TimerLine.Utils.Setprocess(null,true)",1000);
$("#timerbtn-play").attr("class","iconfont icon-zanting1");
//播放枷鎖
TimerLine.protect.lock_play=true;
//暫停解鎖
TimerLine.protect.lock_stop=false;
}else if(TimerLine.protect.lock_play){
$("#timerbtn-play").attr("class","iconfont icon-zanting");
TimerLine.Interval_label&&clearInterval(TimerLine.Interval_label);
TimerLine.Interval_process&&clearInterval(TimerLine.Interval_process);
//播放解鎖
TimerLine.protect.lock_play=false;
//暫停加鎖
TimerLine.protect.lock_stop=true;
}
}
if(target.id == That.data.btns.pre){
if(TimerLine.protect.index_label==0) return;
TimerLine.Utils.mapSetLabel(TimerLine.rubbish_datas, TimerLine.protect.index_label-1,false);
TimerLine.Utils.Setprocess(TimerLine.protect.index_process-1,false);
TimerLine.protect.index_process=TimerLine.protect.index_process-1;
}
if(target.id == That.data.btns.next){
if(TimerLine.protect.index_label==TimerLine.rubbish_datas.length-1) return;
TimerLine.Utils.mapSetLabel(TimerLine.rubbish_datas, TimerLine.protect.index_label+1,false);
TimerLine.Utils.Setprocess(TimerLine.protect.index_process+1,false);
TimerLine.protect.index_process=TimerLine.protect.index_process+1;
}
});
}
}
TimerLine.init();
以上是我自己手寫的組件代碼,對設(shè)計模式了解還是一般.本來是想用原型模式寫,不過在setInterval時候,方法沒法調(diào)用原型方法,讓后我就改成了單例模式
TimeLine組件介紹
data:數(shù)據(jù)容器綁定
protect 保護(hù)屬性 (對播放、暫停、時間軸index、標(biāo)注index)
rubbish_datas 存儲ajax讀取的數(shù)據(jù)
Interval_label 百度地圖標(biāo)注定時器
Interval_process 時間軸定時器
Utils 工具類
init() TimeLine初始化
createMap() 創(chuàng)建百度地圖
ajaxCreate() 獲取數(shù)據(jù),創(chuàng)建容器(create()),時間綁定(bindEvent())
遇到的問題:
兩個定時器運行時,公共index 容易讀取錯誤,一個定時器修改了index 另一個定時器還沒修改,這樣造成了創(chuàng)建標(biāo)注與當(dāng)前時間不符合,
注:要將修改公共變量盡量寫在一個方法中。公共變量最好不要在多個方法中公用,容易在增減的時候出現(xiàn)不必要的BUG
定時器運行到最后一天的時候要將定時器清除。
程序如圖:
附上預(yù)覽地址
更多內(nèi)容可以訂閱本人微信公眾號,一起開啟前端小白進(jìn)階的世界!
不給 Demo 地址 是不是對不起你們。哈哈?
可以關(guān)注微信公眾號 回復(fù)百度地圖時間軸組件 ,即可收到 Demo 的地址。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/86903.html