jQuery Google Maps - open infowindow on click

时间秒杀一切 提交于 2019-12-24 14:35:13

问题


I am running a google map from HTML data and I really need to be able to click on rows (divs) to open the relevant marker. I was hoping to add an onclick within an .each() function but I cant get anything I have tried to work.

Basically if clicking on each row could open the relevant infowindow it would solve all my problems :)

Help would be much appreciated.

<script type="text/javascript" language="javascript">
        var infowindow = new google.maps.InfoWindow();
        var myOptions = {
           zoom: 4,
           center: new google.maps.LatLng(-40.900557, 174.885971),
           mapTypeId: google.maps.MapTypeId.ROADMAP,
           disableDefaultUI: true
        };
        var icon = "img/marker.png";
        $(function() {
            map = new google.maps.Map(document.getElementById("map"), myOptions);
            // grab data attributes from html
            $('.row').each(function( index ){
                var rLat = $(this).data("coordinates").lat;
                var rLong = $(this).data("coordinates").long;
                var rTitle = $(this).find('.itemtitle a').html();
                var rTel = $(this).find('.tel').html();
                var rAdd = $(this).find('.add').html();
                var contentString = '<div style="text-align:left"><h4 style="color:#0068a6;font-size:16px;margin:0px 0px 10px 0px;">' + rTitle + '</h4><strong>' + rTel + '</strong><br /><br />' + rAdd + '</div>';
                var myLatLng = new google.maps.LatLng( rLat, rLong );
                var otherMarkers = new google.maps.Marker({
                    position: myLatLng,
                    map: map,
                    icon: icon
                });
                // click actions
                google.maps.event.addListener(otherMarkers, 'click', (function(otherMarkers, index) {
                    return function() {
                        infowindow.setContent( contentString );
                        infowindow.open( map, otherMarkers );
                    }
                })(otherMarkers, index));               
            });
        });

        $(function() {
            $(".leftblock .ctrlholder:nth-child(2)").addClass("last");
            $(".leftblock .ctrlholder:nth-child(3)").addClass("last");
        });
    </script>

HTML

<div class="row" data-coordinates='{"lat" : -41.407493, "long" : 174.584122}'>
    <h4 class="itemtitle"><a href="">Title</a></h4>
    <p class="centralregion">Address</p>
    <ul>
        <li class="add">Post Address</li>
        <li class="tel">tel</li>
    </ul>
    <span class="filter3"></span>
</div>

Thanks in advance.


回答1:


Since you already loop over all the rows to create markers you can add a click handler to each row that will click on the marker

after adding marker event listener:

 google.maps.event.addListener(otherMarkers......);

Add a row click handler that triggers a marker click:

/* "this" is the row instance*/
$(this).click(function(){
 google.maps.trigger( otherMarkers ,'click')
})



回答2:


The following approach is slightly convoluted but has the advantage of being economical of memory.

$(function() {
    var myOptions = {
       zoom: 4,
       center: new google.maps.LatLng(-40.900557, 174.885971),
       mapTypeId: google.maps.MapTypeId.ROADMAP,
       disableDefaultUI: true
    };
    var map = new google.maps.Map(document.getElementById("map"), myOptions);
    var infowindow = new google.maps.InfoWindow();
    var icons = {
        'dflt': "../images/map_icons/beach-certified.png",
        'selected': "../images/map_icons/harbour-guest.png"
    };
    var infoTemplate = '<div style="text-align:left"><h4 style="color:#0068a6;font-size:16px;margin:0px 0px 10px 0px;">%Title</h4><strong>%Tel</strong><br /><br />%Add</div>';
    var seletedMarker = null;

    //Function for composing the info string on the fly.
    //This avoids needing to store fully composed info strings in a closure,
    //on the offchance that they will be viewed.
    function composeInfoString(row) {
        var $row = $(row);
        return infoTemplate
            .replace('%Title', $row.find('.itemtitle a').html())
            .replace('%Tel', $row.find('.tel').html())
            .replace('%Add', $row.find('.add').html());
    }

    //closure-forming function to trap row and marker
    function clickHandler(row, marker) {
        return function() {
            if(seletedMarker) {
                seletedMarker.setIcon(icons.dflt);//revert seletedMarker's icon to .dflt
            }
            infowindow.setContent( composeInfoString(row) );
            infowindow.open( map, marker );
            marker.setIcon(icons.selected);//Set marker's icon to .seleted
            seletedMarker = marker;//Remember the currently selected marker so it can be reverted to default next time round.
        };
    }

    $('.row').each(function( index, row ) {
        var $row = $(row);
        var coords = $row.data("coordinates");
        //console.log([coords.lat, coords.lng].join());
        var marker = new google.maps.Marker({
            position: new google.maps.LatLng( Number(coords.lat), Number(coords.lng) ),
            icon: icons.dflt,
            map: map
        });
        var fn = clickHandler(row, marker);
        google.maps.event.addListener(marker, 'click', fn);
        $row.data('clickFn', fn);//associate fn with row.
    });

    //Delegate handling of row clicks upward (to closest common row container).
    $(document).on('click', '.row', function() {
        var fn = $(this).data('clickFn');
        if(fn) fn();//this is the functionality you seek
    });
});

The economies are twofold :

  • By composing the info-string on the fly, you avoid the need to store fully composed info strings in closures (one per marker/row), on the off-chance that they will be viewed.
  • By attaching fn (pragmatically speaking, a "closure") to each row as a .data() item, and delegating click handling upwards, you can exploit the same closure used when clicking the marker directly without the need for an additional function wrapper per marker/row.

These kinds of economies can be significant when working with many markers, and otherwise do no harm.

Also, you might like to consider changing your coordinate longitude property from long to lng. In the code, this will avoid .long, which can give problems in some browsers. long is one of many underlying language keywords that should be avoided as js object property identifiers.

Edit

Now tested - See updated fiddle. Various fixes are reflected above.

Edit 2

Code modified to swap-out selected marker icon- See updated fiddle.



来源:https://stackoverflow.com/questions/15192164/jquery-google-maps-open-infowindow-on-click

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!