当Google地图上的标记超过1个时,删除功能将失败

时间:2018-09-15 09:26:11

标签: javascript google-maps google-maps-api-3 google-maps-markers

我正在使用Google Maps功能,该功能允许人们从侧边栏拖动标记并将其放置在地图上。当用户单击标记时,将弹出信息窗口,并提供一些数据以及删除按钮。 当地图上只有1个标记时,此删除按钮可以正常工作,但是如果有多个标记,则无法删除正确的标记(如下面的gif所示)。

这就是我拥有的JavaScript

https://graph.facebook.com/v3.1/me?fields=picture.width(value).height(2000)&access_token={}
var map, iw, drag_area, actual, mark;
var overview, zIndex = 0;
newMarkers = []; //declare empty markers array
id = 0; //marker id set at 0

function helper() {
    this.setMap(map);
    this.draw = function() {};
}
helper.prototype = new google.maps.OverlayView();

function fillMarker(icon) {
    var div = document.createElement("div");
    div.style.backgroundImage = "url(" + icon + ")";
    var left;
    if (mark.id == "m1") {
        left = "0px";
    } else if (mark.id == "m2") {
        left = "50px";
    } else if (mark.id == "m3") {
        left = "100px";
    }
    div.style.left = left;
    div.id = mark.id;
    div.className = "drag";
    div.onmousedown = div.ontouchstart = initDrag;
    drag_area.replaceChild(div, mark);
    mark = null;
}

function createDraggedMarker(latlng, icon) {
    var icon = {
        url: icon,
        size: new google.maps.Size(32, 32),
        anchor: new google.maps.Point(15, 32)
    };
    marker = new google.maps.Marker({
        position: latlng,
        map: map,
        clickable: true,
        draggable: true,
        crossOnDrag: false,
        optimized: false,
        icon: icon,
        zIndex: zIndex,
        id: id++ //increment the ID
    });
    newMarkers.push(marker);
    google.maps.event.addListener(marker, "click", function() {
        actual = marker;
        var lat = actual.getPosition().lat();
        var lng = actual.getPosition().lng();
        var contentStr = "<div class='infowindow'>" + lat.toFixed(6) + ", " + lng.toFixed(6) + "<\/div>";
        var delMe = "<br /><input type = 'button' value = 'Delete' onclick = 'DeleteMarker(" + marker.id + ")' value = 'Delete' />"
        iw.setContent(contentStr + delMe);
        iw.open(map, this);
    });
    google.maps.event.addListener(marker, "dragstart", function() {
        if (actual == marker) iw.close();
        zIndex += 1;
        marker.setZIndex(zIndex);
    });
}

function initDrag(evt) {
    function getPt(evt) {
        var pt = {};
        if (evt && evt.touches && evt.touches.length) {
            pt.x = evt.touches[0].clientX;
            pt.y = evt.touches[0].clientY;
        } else {
            if (!evt) var evt = window.event;
            pt.x = evt.clientX;
            pt.y = evt.clientY;
        }
        return pt;
    };
    var drag = function(mEvt) {
        if (mark && mark.className == "drag") {
            var pt = getPt(mEvt),
                x = pt.x - o.x,
                y = pt.y - o.y;
            mark.style.left = (mark.x + x) + "px";
            mark.style.top = (mark.y + y) + "px";
            mark.onmouseup = mark.ontouchend = function() {
                var mapDiv = map.getDiv(),
                    mapLeft = mapDiv.offsetLeft,
                    mapTop = mapDiv.offsetTop,
                    mapWidth = mapDiv.offsetWidth,
                    mapHeight = mapDiv.offsetHeight;
                var dragLeft = drag_area.offsetLeft,
                    dragTop = drag_area.offsetTop,
                    iconWidth = mark.offsetWidth,
                    iconHeight = mark.offsetHeight;
                var newLeft = mark.offsetLeft + dragLeft + iconWidth / 2;
                var newTop = mark.offsetTop + dragTop + iconHeight / 2;
                if (dragLeft > mapLeft && newLeft < (mapLeft + mapWidth) && newTop > mapTop && newTop < (mapTop + mapHeight)) {
                    var offset = 1;
                    var divPt = new google.maps.Point(newLeft - mapLeft - offset, newTop - mapTop + (iconHeight / 2));
                    var proj = overview.getProjection();
                    var latlng = proj.fromContainerPixelToLatLng(divPt);
                    var icon = mark.style.backgroundImage.slice(4, -1).replace(/"/g, "");
                    createDraggedMarker(latlng, icon);
                    fillMarker(icon);
                }
            };
        }
        return false;
    };
    if (!evt) var evt = window.event;
    mark = evt.target ? evt.target : evt.srcElement ? evt.srcElement : evt.touches ? evt.touches[0].target : null;
    if (mark.className != "drag") {
        if (d.cancelable) d.preventDefault();
        mark = null;
        return;
    } else {
        zIndex++;
        mark.style.zIndex = zIndex.toString();
        mark.x = mark.offsetLeft;
        mark.y = mark.offsetTop;
        var o = getPt(evt);
        if (evt.type === "touchstart") {
            mark.onmousedown = null;
            mark.ontouchmove = drag;
            mark.ontouchend = function() {
                mark.ontouchmove = null;
                mark.ontouchend = null;
                mark.ontouchstart = initDrag;
            };
        } else {
            document.onmousemove = drag;
            document.onmouseup = function() {
                document.onmousemove = null;
                document.onmouseup = null;
                if (mark) mark = null;
            };
        }
    }
    return false;
}

function initialize() {
    var mapOptions = {
        center: new google.maps.LatLng(52.052491, 9.84375),
        zoom: 4,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        streetViewControl: false,
        mapTypeControlOptions: {
            mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.SATELLITE, google.maps.MapTypeId.TERRAIN]
        },
        panControl: false,
        zoomControlOptions: {
            style: google.maps.ZoomControlStyle.SMALL
        }
    };
    map = new google.maps.Map(document.getElementById("map"), mapOptions);
    iw = new google.maps.InfoWindow();
    google.maps.event.addListener(map, "click", function() {
        if (iw) iw.close();
    });
    drag_area = document.getElementById("markers");
    var divArray = drag_area.getElementsByTagName("div");
    for (var i = 0; i < divArray.length; i++) {
        var div = divArray[i];
        div.onmousedown = div.ontouchstart = initDrag;
    }
    overview = new helper();
}

//Delete the marker by ID
function DeleteMarker(id) {
    for (var i = 0; i < newMarkers.length; i++) {
        if (newMarkers[i].id == marker.id) {
            console.log("This ID: " + this.marker.id);
            //markers[i].setMap(null);

            newMarkers[i].setMap(null);
            newMarkers.splice(i, -1);

            return;
        }

    }
}
google.maps.event.addDomListener(window, 'load', initialize);
body,
html {
  height: 100%;
  width: 100%;
}
#map {
  float: left;
  margin: 0 25px 10px 14px;
  width: 64%;
  height: 70%;
}
#desc {
  float: left;
  margin: 0 25px 10px 20px;
  width: 10em;
}
#markers {
  position: absolute;
  top: 140px;
  left: 70%;
  width: 200px;
  height: 110px;
}
.drag {
  position: absolute;
  width: 32px;
  height: 32px;
}
.infowindow {
  margin-top: 20px;
  width: 180px;
  height: 60px;
}
@media screen and (max-width: 890px) {
  body,
  html,
  #map {
    margin: 0;
  }
  #map {
    width: 100%;
    height: 50%;
  }
  #desc {
    margin: 100px 14px 0;
    width: 93%;
  }
  .include >b {
    float: right;
    margin-top: 17px;
  }
  #markers {
    /* center horizontal and do not overlap the map */
    position: absolute;
    top: 50%;
    left: 50%;
    width: 10em;
    height: 6em;
    margin-top: 5em;
    margin-left: -5em;
  }
  #markers > p {
    margin-top: 0;
    font-size: 80%;
  }
  .infowindow {
    margin-top: 10px;
    width: 150px;
    height: 25px;
  }
}

是的,仅当地图上只有1个标记时,删除按钮才起作用,除此之外,其他任何操作都将失败。

这是我的小提琴:http://jsfiddle.net/xpvt214o/797910/

1 个答案:

答案 0 :(得分:0)

我认为问题在于您在marker中将createDraggedMarker定义为全局变量,因此marker始终引用最后添加的标记,因此delete仅适用于最后添加的标记。

进行更改以使其起作用:

  1. 使marker在方法createDraggedMarker本地
  2. 修改DeleteMarker,以便它使用参数id在数组中搜索要删除的标记,而不是marker.id

其余的保持不变。

我用注释标记了代码的更改。

Working fiddle