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

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

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

Я нашел несколько примеров использования API Карт Google v2 и jQuery, но не только с простым старым API Карт Google 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, что включено в мой ответ ниже.

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>

Объект InfoWindow не имеет события click, поэтому вы не можете сделать

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');

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

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

Вот мой рабочий код (Sencha Touch 2 и Google maps API 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));
}

Мое решение: попробуйте использовать 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>


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

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

    <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

Другие вопросы по тегам