【问题标题】:Google Maps v3 handle click on elements inside InfoWindowGoogle Maps v3 处理点击 InfoWindow 内的元素
【发布时间】:2013-03-14 07:12:24
【问题描述】:

简而言之,我试图完成的事情:

  • 地图上只有一个信息窗口,因为标记很多
  • 附加到标记的 InfoWindow 内容
  • InfoWindow 在标记单击时打开 => 附加属性中的内容
  • InfoWindow 包含 2 个按钮 => 设置 start,设置 target
  • 如果设置了starttarget,计算路线

我尝试了很多,但很难将处理程序附加到 InfoWindow 内的按钮。我发现的最好的提示是这个:Adding event to element inside Google Maps API InfoWindow

到目前为止我已经试过了:

<script>
function initialize() {
    var mapOptions = {
        center: new google.maps.LatLng(50.903033, 11.359863),
        zoom: 6,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        disableDefaultUI: true,
        zoomControl: true,
        scaleControl: true,
        overviewMapControl: true
    };
    var map = new google.maps.Map(document.getElementById('limousine-map'),
        mapOptions);
    var directionsService = new google.maps.DirectionsService();
    var directionDisplay = new google.maps.DirectionsRenderer();
    directionDisplay.setMap(map);
    directionDisplay.setPanel(document.getElementById('route-details'));
    var infoWindow = new google.maps.InfoWindow();
    var endPoint = false;
    var startPoint = false;


var marker = new google.maps.Marker({
    map: map,
    position: new google.maps.LatLng(50.903033, 11.359863),
    title: 'Test1'
});
marker.infoWindowContent = [
    '<div id="infoWindow"><strong>Test</strong>',
    '<button class="button" id="selectStart">Start</button>'+
    '<button class="button" id="selectTarget" style="float: right;">Target</button></div>'
].join('<br>');

google.maps.event.addListener(marker,'click',function(){
    infoWindow.close();
    infoWindow = new google.maps.InfoWindow({
        content: this.infoWindowContent
    });
    infoWindow.open(map,this);
    clickedLocation = this;
    google.maps.event.addListener(infoWindow, 'domready', function() {
        $('#infoWindow button').on('click',function(){
            console.log(clickedLocation);
            if($(this).attr('id') == 'selectStart'){
                startPoint = clickedLocation;
            }
            if($(this).attr('id') == 'selectTarget'){
                endPoint = clickedLocation;
            }
            recalcRoute();
        });
    });
});

var marker2 = new google.maps.Marker({
    map: map,
    position: new google.maps.LatLng(52.903033, 12.359863),
    title: 'Test2'
});
marker2.infoWindowContent = [
    '<div id="infoWindow"><strong>Test2</strong>',
    '<button class="button" id="selectStart">Start</button>'+
            '<button class="button" id="selectTarget" style="float: right;">Target</button></div>'
].join('<br>');

google.maps.event.addListener(marker2,'click',function(){
    infoWindow.close();
    infoWindow = new google.maps.InfoWindow({
        content: this.infoWindowContent
    });
    infoWindow.open(map,this);
    clickedLocation = this;
});



//Route painting
function recalcRoute(){
    if(startPoint != false && endPoint != false){
        var request = {
            origin: startPoint,
            destination: endPoint,
            travelMode: google.maps.TravelMode.DRIVING,
            unitSystem: google.maps.UnitSystem.METRIC
        };
        directionsService.route(request, function(response, status){
            if(status == google.maps.DirectionsStatus.OK){
                $('#route-details').parent().fadeIn();
                directionDisplay.setDirections(response);
            }
        });
    }else{
        directionDisplay.setDirections(null);
    }
}

}
google.maps.event.addDomListener(window, 'load', initialize);
</script>

我让处理程序正常工作,但路由计算不起作用。我收到类似

的错误
Uncaught Error: Invalid value for property <origin>: [object Object] 
thrown at line: directionsService.route(request, function(response, status){

如何将事件绑定到 InfoWindow 内的按钮并仍然调用 recalcRoute? 我也试过在按钮上设置onclick,但是recalcRoute的引用是未知的。

为什么$('#infoWindow button').on('click',function(){ console.log('test'); }); 不起作用?

【问题讨论】:

  • 您说“地图上的单个信息窗口”,但代码另有说明。每次点击 marker 时都会创建一个新的 infoWinow。

标签: jquery google-maps events google-maps-api-3


【解决方案1】:
  1. 要从 HTML 点击监听器访问变量,它们需要在全局上下文中。
  2. 路线服务的起点和终点必须是 google.maps.LatLng 对象或可作为地址进行地理编码的字符串,而不是 google.maps.Marker 对象。可以通过以下方式检索标记的 google.maps.LatLng:

    marker.getPosition().

working example

【讨论】:

    【解决方案2】:

    您应该能够建立 contentWindow 的 HTML 并单击一次操作,然后一遍又一遍地使用它们。

    contentWindow 中唯一需要更改的是标题,以反映点击标记的标题。

    应该这样做:

    function initialize() {
        var mapOptions = {
            center: new google.maps.LatLng(50.903033, 11.359863),
            zoom: 6,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            disableDefaultUI: true,
            zoomControl: true,
            scaleControl: true,
            overviewMapControl: true
        };
        var map = new google.maps.Map(document.getElementById('limousine-map'), mapOptions);
        var directionsService = new google.maps.DirectionsService();
        var directionDisplay = new google.maps.DirectionsRenderer();
        directionDisplay.setMap(map);
        directionDisplay.setPanel(document.getElementById('route-details'));
    
        var Route = {
            var request = {
                origin: null,
                destination: null,
                travelMode: google.maps.TravelMode.DRIVING,
                unitSystem: google.maps.UnitSystem.METRIC
            };
            this.setOrigin = function(m) { request.origin = m.getPosition(); };
            this.setDestination = function(m) { request.destination = m.getPosition(); };
            this.calc = function() {
                if(request.origin && request.destination) {
                    directionsService.route(request, function(response, status) {
                        if(status == google.maps.DirectionsStatus.OK) {
                            $('#route-details').parent().fadeIn();
                            directionDisplay.setDirections(response);
                        }
                    });
                } else {
                    directionDisplay.setDirections(null);
                }
            }
        };
    
        var route = new Route();
        var clickedLocation;
    
        var $infoWindowContent = $([
            '<div class="infoWindowContent">',
            '<h3></h3>',
            '<button class="setOrigin">Start</button>',
            '<button class="setDestination" style="float: right;">Target</button>',
            '</div>'
        ].join(''));
        $infoWindowContent.find(".setOrigin").on('click', function() {
            route.setOrigin(clickedLocation);
            route.calc();
        });
        $infoWindowContent.find(".setDestination").on('click', function() {
            route.setDestination(clickedLocation);
            route.calc();
        });
    
        var infoWindow = new google.maps.InfoWindow();
        infoWindow.setContent($infoWindowContent.get(0));
    
        //Assuming array markerData to contain the data necessary for bujilding markers ...
        $.each(markerData, function(i, m) {
            var marker = new google.maps.Marker({
                map: map,
                position: new google.maps.LatLng(m.lat, m.lng),
                title: m.title
            });
    
            google.maps.event.addListener(marker, 'click', function() {
                clickedLocation = this;
                infoWindow.close();//necessary?
                $infoWindowContent.find("h3").text(this.getTitle());
                infoWindow.open(map, this);
            });
        });
    
    }
    google.maps.event.addDomListener(window, 'load', initialize);
    

    未经测试

    注意事项:

    • 我在 Route() 构造函数中封装了与路由有关的所有内容,并使用单个实例 route
    • 我假设所有标记数据最初都包含在 markerData 数组中,该数组会循环以创建尽可能多的标记。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-11
      • 2015-09-08
      • 2021-03-19
      • 2011-01-09
      • 2012-01-06
      • 1970-01-01
      • 2015-05-20
      • 2013-11-08
      相关资源
      最近更新 更多