自定义复杂覆盖物:
创建生成自定义覆盖物的构造函数:
//定义构造函数
function ComplexCustomOverlay(point, opt, html) {
//参数分别为经纬度位置,偏移距离,html
this._point = point;
this._opt = opt || {};
this._html = html;
}
//继承API的BMap.Overlay
ComplexCustomOverlay.prototype = new BMap.Overlay();
//初始化自定义覆盖物
ComplexCustomOverlay.prototype.initialize = function(map){
this._map = map;
var opt = this._opt;
// 创建div元素,作为自定义覆盖物的容器
var div = this._div = document.createElement("div");
div.style.position = "absolute";
div.innerHTML = this._html;
// 将div添加到覆盖物容器中
map.getPanes().floatPane.appendChild(div);
// 需要将div元素作为方法的返回值,当调用该覆盖物的show、hide方法,或者对覆盖物进行移除时,API都将操作此元素。
return div;
}
//绘制自定义覆盖物
ComplexCustomOverlay.prototype.draw = function(){
var map = this._map;
var pixel = map.pointToOverlayPixel(this._point);
this._div.style.left = pixel.x + this._opt.left + "px";
this._div.style.top = pixel.y + this._opt.top + "px";
}
//给自定义覆盖物添加事件
ComplexCustomOverlay.prototype.addEventListener = function(event,fun){
this._div['on'+event] = fun;
}
移动自定义覆盖物到可视区域:
function movePanel (pt,dom){
var _this = this;
var mapH = parseInt(_this.mapModel.getContainer().offsetHeight,10),
mapW = parseInt(_this.mapModel.getContainer().offsetWidth,10)
//获得自定义覆盖物的外部高度(包含内容、内边距、边框、外边距)
var topOffetH = (dom.outerHeight(true) + 20) + 60
var topOffetW = (dom.outerWidth(true)) + 20
//如果自定义覆盖物本身的宽度或者高度超过地图容器
if(topOffetH >= mapH || topOffetW >= mapW){
return false;
}
var anchorPos = _this.mapModel.pointToPixel(pt)
var pointX = anchorPos.x
var pointY = anchorPos.y
var panTop = (topOffetH - pointY) > 0 ? (topOffetH - pointY) : 0
var panLeft = topOffetW / 2 - pointX > 0 ? (topOffetW / 2 - pointX) : 0
this.mapModel.panBy(panLeft,panTop,{ noAnimation: false });
}
生成自定义覆盖物:
//添加自定义覆盖物
var html = $("#detailPanel").html();
var pt = new BMap.Point(data.result.longitude, data.result.latitude);
var cmpOverlay= new ComplexCustomOverlay(pt, { left: -150, top: -($("#detailPanel").outerHeight(true) - 180) / 2 - 210 }, html);
this.mapModal.addOverlay(cmpOverlay);
//移动自定义覆盖物到可视区域
_this.movePanel(pt,$("#detailPanel"));
删除自定义覆盖物:
//删除自定义覆盖物
this.mapModal.removeOverlay(cmpOverlay);
//如果页面中同时存在多个自定义覆盖物,并且想同时删除:
this.mapModal.clearOverlays();
//如果页面中同时存在多个自定义覆盖物,并且存在其他覆盖物,但是只想同时删除多个自定义覆盖物
var overlays = this.mapModel.getOverlays();
for (var i = 0; i < overlays.length; i++) {
if (overlays[i]._html) {
var removeOverlay = overlays[i];
this.mapModel.removeOverlay(removeOverlay);
}
}
如果还给地图的点击事件绑定了其他操作,那么点击自定义覆盖物会冒泡到地图上,导致也触发地图的点击事件:
之前的做法:直接给覆盖物上的DOM元素绑定事件,在这儿阻止事件冒泡是无效,因为经过实际操作,发现会先进地图的点击事件中,再进DOM元素的点击事件中。
$(document).on('click','#detailPanelClose', function (e) {
......
})
解决方法:直接给自定义覆盖物绑定事件,给自定义覆盖物上的DOM元素设置id,通过e.target.id来判断点击的是自定义覆盖物上的哪个元素,然后阻止事件冒泡。(或者通过判断e.srcElement.innerText等)
cmpOverlay.addEventListener('click', function(e) {
if(e.target.id == 'detailPanelClose'){
......
}
e.cancelBubble = true;
e.stopPropagation();
})