【问题标题】:Add click eventlisteners to directionService endpoint markers将单击事件侦听器添加到目录服务端点标记
【发布时间】:2015-11-19 23:23:29
【问题描述】:

我希望能够从 window.google.maps.DirectionsService 调用中引用和/或附加点击事件侦听器到 A 和 B 端点标记。

我知道您可以隐藏这些标记并创建自己的标记(与此相关的所有 stackoverflow 都建议这样做。我不想要它),但是您失去了能够拖动标记并让它计算基于新路线的功能在您拖动端点的位置。

我想要做的主要事情是覆盖默认的 infoWindow 并显示我自己的自定义窗口。第一步是能够连接到标记中。仅仅能够触发点击事件是不够的,我需要访问事件处理程序来覆盖。

以下是可拖动标记的示例:http://jsbin.com/mekapadigo/1/edit?html,output

我不需要/想要右侧的面板,但我注意到有一个事件正在使用它在 A 和 B 标记上侦听,因此建议也许这是可能的。

【问题讨论】:

标签: javascript google-maps google-maps-api-3


【解决方案1】:

这是在端点上附加标记的版本,单击时会显示信息窗口。拖动标记时,标记位置和航点会反馈到方向服务中。请求受到限制,因此它不会超过每秒 10 次的查询限制。计算完路线后,应将标记移回路线上(留作练习)。

<!DOCTYPE html>
<html>
<head>
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
	<meta charset="utf-8">
	<title>Draggable directions</title>
	<style>
		html, body {
			height: 100%;
			margin: 0;
			padding: 0;
		}
		#map {
			height: 100%;
			width: 100%;
		}
	</style>
</head>
<body>
<div id="map"></div>
<script>
	function initMap() {

		var map = new google.maps.Map(document.getElementById('map'), {
			zoom: 10,
			center: {lat: 40.6, lng: -73.9}
		});

		var directionsService = new google.maps.DirectionsService;
		var directionsDisplay = new google.maps.DirectionsRenderer({
			draggable: true,
			map: map,
			suppressMarkers: true
		});

		var waypoints = [];
		var markerStart = new google.maps.Marker({
			position: {lat: 40.851246, lng: -73.875218},
			map: map,
			draggable:true
		});
		var infowindowStart = new google.maps.InfoWindow({
			content: "Marker Start Info Window"
		});
		markerStart.addListener('click', function() {
			infowindowStart.open(map, markerStart);
		});

		var markerEnd = new google.maps.Marker({
			position: {lat: 40.831916, lng: -73.888947},
			map: map,
			draggable:true
		});
		var infowindowEnd = new google.maps.InfoWindow({
			content: "Marker End Info Window"
		});
		markerEnd.addListener('click', function() {
			infowindowEnd.open(map, markerEnd);
		});


		var redisplay = _.throttle(function() {
			displayRoute(markerStart, markerEnd, directionsService, directionsDisplay, waypoints);
		}, 200);
		google.maps.event.addListener(markerStart, 'drag', redisplay);
		google.maps.event.addListener(markerEnd, 'drag', redisplay);

		directionsDisplay.addListener('directions_changed', function() {
			var directions = directionsDisplay.getDirections();
			waypoints = directions.request.waypoints;
		});

		displayRoute(markerStart, markerEnd, directionsService, directionsDisplay, waypoints);

	}

	function displayRoute(markerStart, markerEnd, service, display, waypoints) {
		service.route({
			origin: markerStart.getPosition(),
			destination: markerEnd.getPosition(),
			travelMode: google.maps.TravelMode.DRIVING,
			waypoints: waypoints,
			avoidTolls: true
		}, function(response, status) {
			if (status === google.maps.DirectionsStatus.OK) {
				waypoints = response.request.waypoints;
				display.setDirections(response);
			} else {
				console.log('Could not display directions due to: ' + status);
			}
		});
	}

</script>
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap" async defer></script>
<script	src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
</body>
</html>

【讨论】:

    【解决方案2】:

    当您创建自己的标记时,您不会失去在拖动端点时重新计算路线的能力。我认为https://developers.google.com/maps/documentation/javascript/examples/directions-draggable 的示例可以满足您的需求。

    这是该示例中的一些修改代码。您可以监听 'directions_changed' 事件,并在侧面板中显示您喜欢的任何内容:

    <!DOCTYPE html>
    <html>
    <head>
    	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    	<meta charset="utf-8">
    	<title>Draggable directions</title>
    	<style>
    		html, body {
    			height: 100%;
    			margin: 0;
    			padding: 0;
    		}
    		#map {
    			height: 100%;
    			float: left;
    			width: 63%;
    			height: 100%;
    		}
    		#right-panel {
    			float: right;
    			width: 34%;
    			height: 100%;
    		}
    		#right-panel {
    			font-family: 'Roboto','sans-serif';
    			line-height: 30px;
    			padding-left: 10px;
    		}
    
    		#right-panel select, #right-panel input {
    			font-size: 15px;
    		}
    
    		#right-panel select {
    			width: 100%;
    		}
    
    		#right-panel i {
    			font-size: 12px;
    		}
    
    		.panel {
    			height: 100%;
    			overflow: auto;
    		}
    	</style>
    </head>
    <body>
    <div id="map"></div>
    <div id="right-panel">
    	<p>Total Distance: <span id="total"></span></p>
    	<p>Your custom information would go here...</p>
    </div>
    <script>
    	// Modified from: https://developers.google.com/maps/documentation/javascript/examples/directions-draggable
    	// For so question: http://stackoverflow.com/questions/33816222/add-click-eventlisteners-to-directionservice-endpoint-markers
    	function initMap() {
    		var map = new google.maps.Map(document.getElementById('map'), {
    			zoom: 8,
    			center: {lat: 40.6, lng: -73.9}
    		});
    
    		var directionsService = new google.maps.DirectionsService;
    		var directionsDisplay = new google.maps.DirectionsRenderer({
    			draggable: true,
    			map: map,
    		});
    
    		directionsDisplay.addListener('directions_changed', function() {
    			// This is where you would do your custom processing
    			computeTotalDistance(directionsDisplay.getDirections());
    		});
    		displayRoute({lat: 40.763637, lng:-73.972238}, {lat: 40.849651, lng:-73.877270}, directionsService,
    			directionsDisplay);
    	}
    
    	function displayRoute(origin, destination, service, display) {
    		service.route({
    			origin: origin,
    			destination: destination,
    			travelMode: google.maps.TravelMode.DRIVING,
    			avoidTolls: true
    		}, function(response, status) {
    			if (status === google.maps.DirectionsStatus.OK) {
    				display.setDirections(response);
    			} else {
    				alert('Could not display directions due to: ' + status);
    			}
    		});
    	}
    
    	function computeTotalDistance(result) {
    		var total = 0;
    		var myroute = result.routes[0];
    		for (var i = 0; i < myroute.legs.length; i++) {
    			total += myroute.legs[i].distance.value;
    		}
    		total = total / 1000;
    		document.getElementById('total').innerHTML = total + ' km';
    	}
    </script>
    <script src="https://maps.googleapis.com/maps/api/js?callback=initMap"
            async defer></script>
    </body>
    </html>

    【讨论】:

    • directions_changed 仅在拖动其中一个标记时触发。如果 google 的标记被抑制并替换为自定义标记,directions_changed 事件将不会触发,因为没有事件可以附加到我的标记上说“拖动时,这些将改变方向”。当然,您可以在普通标记上进行拖动事件,然后在 drag_end 上重新运行 display.setDirections,但您会丢失在拖动时更新的实时路线。您发布的链接中的示例仍在使用谷歌标记作为端点(触发拖动)
    • @ParoX - 我认为,如果您在使用新端点重新计算时将路线更新中创建的任何航路点反馈回路线调用,则不会导致标记移动在你失去你的路线的任何东西。我会更新上面的代码以说明我是否有时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-27
    • 1970-01-01
    • 2019-07-05
    相关资源
    最近更新 更多