Инициировать событие с помощью infoWindow или InfoBox при щелчке Google Map API V3

Я хочу знать, как инициировать событие, когда я нажимаю на информационное окно с помощью Google Maps API v3. В этом примере, когда я нажимаю на маркер, появляется информационное окно с уникальным сообщением, в зависимости от того, какой маркер я нажал. Я также хочу иметь возможность щелкнуть информационное окно и получить предупреждение, в котором говорится

"Вы нажали на информационное окно для (__заполните пустое место_)

Я нашел несколько примеров с использованием Google Maps API v2 и jQuery, но не только с простым старым Google Maps API v3.

<!doctype html>
<html lang="en">
<head>
    <title>jQuery mobile with Google maps - Google maps jQuery plugin</title>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3&sensor=false&language=en"> </script>
    <script type="text/javascript">

    var cityList = [
    ['Chicago', 41.850033, -87.6500523, 1],
    ['Illinois', 40.797177,-89.406738, 2]
    ];

    var demoCenter = new google.maps.LatLng(41,-87);

    var map;
    function initialize()
    {
        map = new google.maps.Map(document.getElementById('map_canvas'), {
            zoom: 7,
            center: demoCenter,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        });
        addMarkers();
    }

    function addMarkers()
    {
        var marker, i;
        var infowindow = new google.maps.InfoWindow();
        for (i = 0; i < cityList.length; i++)
        {
            marker = new google.maps.Marker({
                position: new google.maps.LatLng(cityList[i][1], cityList[i][2]),
                map: map,
                title: cityList[i][0]
            });

            google.maps.event.addListener(marker, 'click', (function(marker, i) {
                var contentString = '<div id="infoWindow">'
                    +'<div id="bodyContent">'
                    +'<p>'
                    + "This location is:<br>"
                    + marker.title
                    +'</p>'
                    +'</div>'
                    + '</div>';
                return function() {
                    infowindow.setContent(contentString);
                    infowindow.open(map, marker);
                    google.maps.event.addListener(infowindow, 'click', (function(i){
                        alert("You clicked on the infowindow for" + cityList[i][0]);
                    }));
                }
                })(marker, i));
            }
        }

</script>
    </head>
    <body onload="initialize()">
        <div id="basic-map" data-role="page">
            <div data-role="header">
                <h1><a data-ajax="false" href="/">jQuery mobile with Google maps v3</a> examples</h1>
                <a data-rel="back">Back</a>
            </div>
            <div data-role="content">
                <div class="ui-bar-c ui-corner-all ui-shadow" style="padding:1em;">
                    <div id="map_canvas" style="height:350px;"></div>
                </div>
            </div>
        </div>
    </body>
</html>

Обновление В итоге я выяснил это и для InfoBox, который включен в мой ответ ниже.


person erin    schedule 24.08.2012    source источник
comment
Возможно, вас заинтересует использование snazzy-info-window в качестве альтернативы. github.com/atmist/snazzy- информационное окно/блоб/мастер/примеры/   -  person Zypps987    schedule 11.09.2017


Ответы (6)


Хорошо, я понял это для infoWindow, но затем я также понял это для InfoBox, так как он красивее и более настраиваемый. Я новичок в JavaScript, и эти замыкания могут быть очень сложными.

Для infoWindow

<!doctype html>
<html lang="en">
<head>
    <title>jQuery mobile with Google maps - Google maps jQuery plugin</title>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3&sensor=false&language=en"> </script>
    <script type="text/javascript">

    var cityList = [
    ['Chicago', 41.850033, -87.6500523, 1],
    ['Illinois', 40.797177,-89.406738, 2]
    ];

    var demoCenter = new google.maps.LatLng(41,-87);

    var map;
    function initialize()
    {
        map = new google.maps.Map(document.getElementById('map_canvas'), {
            zoom: 7,
            center: demoCenter,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        });
        addMarkers();
    }

    var boxText1 = document.createElement("div");
            boxText1.id = "boxText1";
            boxText1.className = "labelText1";
            boxText1.innerHTML = "title1";//this is created earlier 
    var boxList = [];

    function addMarkers()
    {
        var marker, i;
        var infowindow = new google.maps.InfoWindow({
            disableAutoPan: true
          ,isHidden:false
          ,pixelOffset: new google.maps.Size(-10, -10)
          ,closeBoxURL: ""
          ,pane: "mapPane"
          ,enableEventPropagation: true
        });
        for (var i = 0; i < cityList.length; i++)
        {
            marker = new google.maps.Marker({
                position: new google.maps.LatLng(cityList[i][1], cityList[i][2]),
                map: map,
                id: i,
                title: cityList[i][0]
            });

            var boxText = document.createElement("div");
            boxText.id = i;
            boxText.className = "labelText" + i;
            boxText.innerHTML = cityList[i][0];
            boxList.push(boxText);

            google.maps.event.addListener(marker, 'click', (function(marker, i) {
                var contentString = '<div id="infoWindow">'
                    +'<div id="bodyContent">'
                    +'<p>'
                    + "This location is:<br>"
                    + marker.title
                    +'</p>'
                    +'</div>'
                    + '</div>';

                return function() {
                    infowindow.setContent(boxList[this.id]);
                    infowindow.open(map, marker);
                }
                })(marker, i)); //end add marker listener

                google.maps.event.addDomListener(boxList[i],'click',(function(marker, i) {
                        return function() {
                          alert('clicked ' + cityList[i][0])
                        }
                      })(marker, i));
            } //endfor              
        }//end function

</script>
    </head>
    <body onload="initialize()">
        <div id="basic-map" data-role="page">
            <div data-role="header">
                <h1><a data-ajax="false" href="/">jQuery mobile with Google maps v3</a> examples</h1>
                <a data-rel="back">Back</a>
            </div>
            <div data-role="content">
                <div class="ui-bar-c ui-corner-all ui-shadow" style="padding:1em;">
                    <div id="map_canvas" style="height:350px;"></div>
                </div>
            </div>
        </div>
    </body>
</html>

Для InfoBox

<!doctype html>
<html lang="en">
<head>
    <title>jQuery mobile with Google maps - Google maps jQuery plugin</title>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3&sensor=false&language=en"> </script>
    <script type="text/javascript"
    src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox.js"> </script>
    <script type="text/javascript"
    src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox_packed.js"> </script>
    <script type="text/javascript">

    var cityList = [
    ['Chicago', 41.850033, -87.6500523, 1],
    ['Illinois', 40.797177,-89.406738, 2]
    ];

    var demoCenter = new google.maps.LatLng(41,-87);
    var boxList =[];

    function initialize() {
        map = new google.maps.Map(document.getElementById('map_canvas'), {
            zoom: 7,
            center: demoCenter,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        });
        addMarkers();
    }

    function addMarkers(){
        for (var i = 0; i < cityList.length; i++)
        {
            marker = new google.maps.Marker({
                position: new google.maps.LatLng(cityList[i][1], cityList[i][2]),
                map: map,
                id: i,
                title: cityList[i][0]
            });         

            var boxText = document.createElement("div");
            boxText.id = i;
            boxText.style.cssText = "border: 1px solid black; margin-top: 8px; background: yellow; padding: 5px;";
            boxText.innerHTML = "InfoBox for " + cityList[i][0];

            var myOptions = {
                content: boxText
                ,disableAutoPan: false
                ,maxWidth: 0
                ,pixelOffset: new google.maps.Size(-140, 0)
                ,zIndex: null
                ,boxStyle: {
                    background: "url('tipbox.gif') no-repeat"
                    ,opacity: 0.75
                    ,width: "280px"
                }
                ,closeBoxMargin: "10px 2px 2px 2px"
                ,closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif"
                ,infoBoxClearance: new google.maps.Size(1, 1)
                ,isHidden: false
                ,pane: "floatPane"
                ,enableEventPropagation: false
            };

            var ib = new InfoBox(myOptions);
            boxList.push(ib);

            google.maps.event.addListener(marker,'click',(function(marker, i) {
                return function() {
                    boxList[i].open(map, this);
                }
            })(marker, i));

            google.maps.event.addDomListener(boxList[i].content_,'click',(function(marker, i) {
                    return function() {
                      alert('clicked ' + cityList[i][0])
                    }
                  })(marker, i));
        } //endfor  
    } //end function

    </script>
</head>
<body onload="initialize()">
    <div id="basic-map" data-role="page">
        <div data-role="header">
            <h1><a data-ajax="false" href="/">jQuery mobile with Google maps v3</a> examples</h1>
            <a data-rel="back">Back</a>
        </div>
        <div data-role="content">
            <div class="ui-bar-c ui-corner-all ui-shadow" style="padding:1em;">
                <div id="map_canvas" style="height:350px;"></div>
            </div>
        </div>
    </div>
</body>
</html>
person erin    schedule 24.08.2012
comment
Если я выполняю функцию щелчка в Infobox, она вызывает функцию щелчка в маркере. Не могли бы вы помочь решить проблему. Пожалуйста, добавьте предупреждение в маркер, чтобы отладить проблему. - person rpelluru; 20.11.2012
comment
Код, который я написал, работает следующим образом: одним нажатием маркера открывается информационный ящик, затем, когда информационный ящик открыт, если вы щелкнете, вы получите предупреждение. Вы пытаетесь сделать что-то отличное от этого? - person erin; 22.11.2012
comment
Я делаю то же самое, что и вы, но ваш код отлично работает в Android, как вы упомянули. Но у меня проблемы только в iOS. В iOS для второго щелчка по Infobox открывается только предупреждение, потому что первый щелчок вызывает щелчок маркера. - person rpelluru; 22.11.2012
comment
Привет, я пытаюсь заставить твой пример работать в плункере, но он не работает. Ты знаешь почему? plnkr.co/edit/cRdiu6QkZsnDoZBRM1sJ?p=preview - person Rober; 11.01.2018

Объект InfoWindow не имеет события «щелчок», поэтому вы не можете

google.maps.event.addListener(infowindow, 'click',....

вместо этого вы можете прикрепить обработчик событий к объекту DOM, например

function addMarker(latLng, name){

var marker = new google.maps.Marker({
    map:map,
    position:latLng
});

G.event.addListener(marker,'click',function(mev){
        var div = document.createElement('div');
        div.innerHTML = name;
        div.onclick = function(){iwClick(name)};
        infoWindow.setContent(div);
        infoWindow.setPosition(mev.latLng);
        infoWindow.open(map);

    });
}

function iwClick(str){
    alert(str);
};

и вы называете это с

var chicago = new google.maps.LatLng(41.850033, -87.6500523);
addMarker(chicago,'chicago');
person Marcelo    schedule 24.08.2012
comment
Что означает G? - person katmanco; 13.11.2020

Спасибо! Эрин - это мужчина! Вы решили мою проблему! Я бил его 4 дня! Замыкания — это боль в *, если вы новичок в них.

Вот мой рабочий код (Sencha Touch 2 и API карт Google v3). Это позволит открыть только одно информационное окно.

var openedInfoWindow = null;
var boxList = [];
var marker, i;

//build info box object
var infoWindow = new google.maps.InfoWindow({
    enableEventPropagation: true,
});

//handle close
google.maps.event.addListener(infoWindow, 'closeclick', function() {
    openedInfoWindow = null;
});

//loop trough store data...
for(i in data) {
    //data
    var itemData = data[i].getData();

    //marker
    var geopos = new google.maps.LatLng(itemData['lat'], itemData['lng']);
    var marker = new google.maps.Marker({
        position: geopos,
        //icon: image,
        map: map,
        title: itemData['title'],
        id: i,
        animation: google.maps.Animation.DROP
    });

    //add info window content to DOM
    var boxText = document.createElement("div");
    boxText.id = i;
    boxText.className = "labelText" + i;
    boxText.data = itemData;
    boxText.innerHTML = '<b>' + itemData['title'] + '</b>' + (itemData['distance'] ? ' (' + itemData['distance'] + ')' : '') + '<br />' + (itemData['address'] != itemData['title'] ? itemData['address'] : '') + (itemData['price'] ? '<br />' + itemData['price'] : '') + '<br /><a class="button">Meer info</a>';
    boxList.push(boxText);

    //add marker click event
    google.maps.event.addListener(marker, 'click', (function(marker, i) {
        if (openedInfoWindow != null)
            openedInfoWindow.close();

        return function() {
            infoWindow.setContent(boxList[this.id]);
            infoWindow.open(map, marker);
            openedInfoWindow = infoWindow;
        }
    })(marker, i));

    //when infowindow is clicked, open view...
    google.maps.event.addDomListener(boxList[i],'click',(function(marker, i) {
        return function(){
            iStuddy.app.pushView('kames_detail',boxList[i].data);
        }
    })(marker, i));
}
person Daantje    schedule 09.09.2012
comment
Мне не удалось найти никакой документации по enableEventPropagation в спецификации объекта infoWindow ( версия 3.24) - person edigu; 15.07.2016

мое решение: попробуйте использовать onClick в xml

<InfoWindow  onCloseClick={props.onToggleOpen}>
     <div onClick={()=>{alert('hello')}} class="wow slideInLeft">
        <img src="https://i.imgur.com/7IgBxnH.jpg" width="150px" />
        <div>nhà trọ cho thuê</div>
         <div>1.500.000đ</div>
     </div>
 </InfoWindow>
person Nguyễn Phúc    schedule 13.03.2018


Спасибо за все ваши комментарии. Мне удалось создать (после прочтения ваших предложений) пример, который работает без изменения кода Infowindow.

Само infoWindow должно содержать только div-заполнитель с уникальным id:

    <InfoWindow
        marker={this.state.activeMarker}
        visible={this.state.showingInfoWindow}
        onOpen={e => {
          this.onInfoWindowOpen(this.props, e);
        }}
      >
        <div id="xyz" />
      </InfoWindow>

А внутри Mapcontainer вы определяете обратный вызов onInfoWindowOpen, который вставляет один компонент/контейнер с событием onClick и отображает его в заполнитель div:

    onInfoWindowOpen = () => {
        const button = (<button 
        onClick={
            () => {
            this.viewClinic(this.state.selectedPlace.slug)
            }
            }>
            View Details
        </button>);
        ReactDOM.render(React.Children.only(button),document.getElementById("xyz"));
        }


Вот рабочий пример:

https://codesandbox.io/s/k0xrxok983


Еще один полный пример MAP, Marker и InfoWindow:

https://codesandbox.io/s/24m1yrr4mj

person Farrukh Malik    schedule 03.04.2020

Чтобы сделать информационное окно интерактивным или вы хотите запускать функцию при нажатии любых тегов внутри информационного окна, dom должен быть готов. Итак, когда дом готов, вы можете вызвать функцию.

google.maps.event.addListener(infowindow, 'domready', function() {
            document.getElementById('yourId').addEventListener("click", yourFucntionToCall);
            function yourFucntionToCall() {
              Your fucntion code......
            }
          });

person Pramod Ukkali    schedule 19.06.2021