简体   繁体   English

多个标记与独特的infowindows使用谷歌地图javascript api v3

[英]multiple markers with unique infowindows using google maps javascript api v3

I know this question is posted all over stack overflow. 我知道这个问题是遍布堆栈溢出的。 But I've been working at it for days, and none of the solutions have worked. 但是我已经在这里工作了好几天,但没有一个解决方案有效。 I'll post everything I'm doing and maybe someone will see my mistake. 我会发布我正在做的一切,也许有人会看到我的错误。 I'd much rather leave comments on the other existing questions but there is a requirement of 50 rep... I hope there are enough comments to help you read the code but let me summarize. 我更愿意对其他现有问题发表评论,但需要50个代表...我希望有足够的评论来帮助您阅读代码,但让我总结一下。 I have the initialize function for the map. 我有地图的初始化功能。 Since my maps is about directions there is a calcRoute() function. 由于我的地图是关于方向的,因此有一个calcRoute()函数。 This function gets a route from google, and puts in on the map. 此功能从谷歌获取路线,并放入地图。 I also place some markers along the route, that's the parksToPlaceArray. 我还在路线上放置了一些标记,那就是parksToPlaceArray。 so if the ajax returns successfully I parse through the data and add the markers. 所以如果ajax成功返回,我会解析数据并添加标记。 and just below creating the marker I have attempted to add an event listener for the infowindow, but it does not work. 在下面创建标记我试图为infowindow添加一个事件监听器,但它不起作用。 I'd like to get a concept going because I would like to have a title, small description, maybe a thumbnail, and have the title link to the details page. 我想得到一个概念,因为我想有一个标题,小描述,可能是一个缩略图,并有标题链接到详细信息页面。

    var directionsDisplay;
    var directionsService = new google.maps.DirectionsService();
    var map;
    var infowindow;
    var parksToPlaceArray = [];

    function initialize() {
        directionsDisplay = new google.maps.DirectionsRenderer();
        var desoto = new google.maps.LatLng(27.521692, -82.643475); // just a default start value to the map
        var mapOptions = {
            zoom: 15,
            center: desoto
        };


        map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
        directionsDisplay.setMap(map);

        // Resize stuff...
        // makes the map responsive by continuously centering the map on resize
        google.maps.event.addDomListener(window, "resize", function () {
            var center = map.getCenter();
            google.maps.event.trigger(map, "resize");
            map.setCenter(center);
        });

        infowindow = new google.map.InfoWindow();

        // marker click
        //google.maps.event.addListener(marker, 'click', function () {
        //    //map.setZoom(8);
        //    //map.setCenter(marker.getPosition());
        //});


    }

    function calcRoute() {
        var start = document.getElementById('start').value;
        var end = document.getElementById('end').value;
        var request = {
            origin: start,
            destination: end,
            travelMode: google.maps.TravelMode.DRIVING
        };

        directionsService.route(request, function (response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                directionsDisplay.setDirections(response);




                // This ajax call goes out to loadparksbyroute.cshtml with the bounds of the route, and returns a json array of possible parks
                $.ajax({
                    dataType: "json",
                    type: "POST",
                    url: "/getDataPage",
                    success: function (ajaxResponse) {

                        // SUCCESS FUNCTION - RETURNED FROM AJAX ==================================================================


                        var parksResponse = ajaxResponse;
                        // we now have a list of all locations in the zone

                        parksToPlaceArray = getParks();



                        for (i = 0; i < parksToPlaceArray.length; i++) {
                            var myLatlng = new google.maps.LatLng(parksToPlaceArray[i].addresses[0].latitude, parksToPlaceArray[i].addresses[0].longitude);

                            var marker = new google.maps.Marker({
                                position: myLatlng,
                                map: map,
                                title: parksToPlaceArray[i].recAreaName 
                            });

                            //google.maps.event.addListener(marker, 'click', (function (marker, i) {
                            //    return function () {
                            //        infowindow.setContent('<h3>' + this.title + '</h3>');
                            //        infowindow.open(map, marker);
                            //    }
                            //})(marker, i));

                            google.maps.event.addListener(marker, 'click', function () {
                                infowindow.setContent('<h3>' + this.title + '</h3>');
                                infowindow.open(map, this);
                            });

                        }


                    },
                    // END OF SUCCESS FUNCTION FROM AJAX CALL
                    error: function (response) {
                        console.log('error');
                    }
                });


            }
        });


    }

    // when the page loads initialize the map
    google.maps.event.addDomListener(window, 'load', initialize);

I've tried a few different places to put the event listener. 我已经尝试了几个不同的地方来放置事件监听器。 I can't really put it in the initialize since the actual markers are brought in using ajax. 我不能真正把它放在初始化中,因为实际的标记是使用ajax引入的。 I have a list of locations 'parksToPlaceArray' and I loop through it creating a marker and placing it. 我有一个位置'parksToPlaceArray'的列表,我循环通过它创建一个标记并放置它。 Everything works except for the ability to click on a marker. 一切都有效,除了点击标记的能力。

EDIT: So I made a change based on the comments, and now clicking any marker shows one infowindow over a single item. 编辑:所以我根据评论进行了更改,现在点击任何标记显示一个项目的一个信息。 Any marker click will show the same single info window over the same marker 任何标记点击都会在同一标记上显示相同的单个信息窗口

for (i = 0; i < parksToPlaceArray.length; i++) {
                            var myLatlng = new google.maps.LatLng(parksToPlaceArray[i].addresses[0].latitude, parksToPlaceArray[i].addresses[0].longitude);

                            var marker = new google.maps.Marker({
                                position: myLatlng,
                                map: map,
                                title: parksToPlaceArray[i].recAreaName 
                            });

                            //google.maps.event.addListener(marker, 'click', (function (marker, i) {
                            //    return function () {
                            //        infowindow.setContent('<h3>' + this.title + '</h3>');
                            //        infowindow.open(map, marker);
                            //    }
                            //})(marker, i));

                            var contentString = parksToPlaceArray[i].recAreaName;
                            marker.infowindow = new google.maps.InfoWindow({
                                content: contentString
                            });

                            google.maps.event.addListener(marker, 'click', function () {   
                                marker.infowindow.open(map, marker);          
                            });

                        } 

To clarify: you want to know how to close the other info windows when you click on a marker. 澄清一下:您想知道在单击标记时如何关闭其他信息窗口。

The answer is to use a single info window. 答案是使用单个信息窗口。 So you were closer with your original code. 所以你更接近原始代码。

To make the original code work you should write your for loop like this (because there is a function closure inside the loop) 要使原始代码工作,你应该像这样编写for循环(因为循环中有一个函数闭包)

for (i = 0; i < parksToPlaceArray.length; i++) (function(i) {
    // ...
})(i);

So you should write 所以你应该写

for (i = 0; i < parksToPlaceArray.length; i++) (function(i) {
    var myLatlng = new google.maps.LatLng(
        parksToPlaceArray[i].addresses[0].latitude,
        parksToPlaceArray[i].addresses[0].longitude);

    var marker = new google.maps.Marker({
        position: myLatlng,
        map: map,
        title: parksToPlaceArray[i].recAreaName 
    });

    marker.addListener('click', function() {
        infowindow.setContent('<h3>' + marker.title + '</h3>');
        infowindow.open(map, marker);
    });
})(i);

I believe your issue is in the way you are handling the infowindows. 我相信你的问题与你处理信息的方式有关。 You should be following a pattern along the lines of: 你应该按照以下方式遵循一种模式:

  1. Create a marker for each point (park) 为每个点(公园)创建标记
  2. Create an infowindow with the desired content for the marker 创建一个包含标记所需内容的信息窗口
  3. Add the infowindow to the marker 将infowindow添加到标记中
  4. Add an event handler for the marker that opens the infowindow you added to it. 为标记添加事件处理程序,以打开您添加到其中的信息窗口。

What you are doing is: 你在做什么是:

  1. Create a single infowindow 创建一个infowindow
  2. Create a marker for each point (park) 为每个点(公园)创建标记
  3. Add an event handler for each marker that opens the single infowindow that isn't attacked to anything. 为每个标记添加一个事件处理程序,打开不受任何攻击的单个infowindow。

Try Modifying: 尝试修改:

var marker = new google.maps.Marker({
                                position: myLatlng,
                                map: map,
                                title: parksToPlaceArray[i].recAreaName 
                            });


google.maps.event.addListener(marker, 'click', function () {
                                infowindow.setContent('<h3>' + this.title + '</h3>');
                                infowindow.open(map, this);
                            });

To something along the lines of: 对于以下内容:

var marker = new google.maps.Marker({
                                position: myLatlng,
                                map: map,
                                title: parksToPlaceArray[i].recAreaName 
                            });

marker.infowindow = new google.maps.InfoWindow({ content: '<h3>' + this.title + '</h3>' }); 

google.maps.event.addListener(marker, 'click', function () {   
                                this.infowindow.open(map, this);          
                            });

Ok I got it with help from the comment 好的,我在评论的帮助下得到了它

The problem was setting up an infowindow for the marker as a property, and the event listener used this instead of marker. 问题是为标记设置了一个infowindow作为属性,事件监听器使用它而不是标记。 Here are the changes I made, and I removed the global infowindow entirely 以下是我所做的更改,我完全删除了全局信息窗口

var contentString = '<h3>' + parksToPlaceArray[i].recAreaName + '</h3>';
var infowindow = new google.maps.InfoWindow({
    content: contentString
});

    var marker = new google.maps.Marker({
        position: myLatlng,
        map: map,
        title: parksToPlaceArray[i].recAreaName,
        infowindow: infowindow
    });

    google.maps.event.addListener(marker, 'click', function () {   
       this.infowindow.open(map, this);          
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Google Maps API v3-多个标记,多个信息窗口,3个图标 - Google maps api v3 - multiple markers, multiple infowindows, 3 icons Google Map API V3-2张地图上的infowindows @标记 - Google Map API V3 - infowindows @ markers on 2 maps 带有多个标记和方向的infoWindows问题在Google Maps API v3中显示变量 - Issue with infoWindows with multiple markers and directionsDisplay variables in Google Maps API v3 Google Maps API V3:多个标记和Ajax信息窗口? (最棒的表演) - Google Maps API V3 : multiple markers and ajax infowindows? (best performance) 谷歌地图 JS API V3,使用远程 json 源的信息窗口将多个标记添加到 map - Google maps JS API V3,add multiple markers to map with infowindows from remote json source Google Map API v3-带有信息窗口的多个标记未呈现 - Google map API v3 - Multiple markers with infowindows not rendering 在 Google 地图上显示具有独特信息窗口的多个标记 - Display multiple markers with unique infowindows on Google Maps Google地图-具有独特信息窗口的多个标记 - Google maps - multiple markers with unique infowindows 谷歌地图api v3:信息窗口失真 - google maps api v3: infowindows distorted 无法使用 Google map javascript api v3 在 Google 地图上设置多个标记 - Not able to set multiple markers on the Google maps using Google map javascript api v3
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM