Here you have an efficient approach to your problem. This code will give you a 0.1% precision over the total length of the path.
Have a look at the "timeline" in your inspector. If you feel your application is slow (it shouldn't be) you may want to decrease the 'path_increment' variable. If you want more precision, just increase it.
'path_increment = totaldist/1000' means I am dividing your path into 1000 pieces and looking for the closest one to your marker.
Working example: http://jsfiddle.net/fcoramos/tjm0kpby/1/
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="https://maps.googleapis.com/maps/api/js" ></script>
<script>
var map,
myCenter = new google.maps.LatLng(-32.7,-70.7)
function initialize() {
var mapProp = {
center:myCenter,
zoom:9,
mapTypeId:google.maps.MapTypeId.HYBRID,
scaleControl:true };
map=new google.maps.Map(document.getElementById('map'),mapProp);
var _path = new google.maps.Polyline({ //Here goes your _path
path: [{lat: -33.0, lng: -71.0},
{lat: -32.9, lng: -71.0},
{lat: -32.8, lng: -70.9},
{lat: -32.7, lng: -70.85},
{lat: -32.6, lng: -70.7},
{lat: -32.5, lng: -70.5}],
strokeColor: 'orange',
strokeWeight: 2,
map: map
});
map.addListener('click', addmarker);
function addmarker(event) {
var marker = new google.maps.Marker({
position: event.latLng,
map: map,
draggable: false,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 3,
strokeColor: 'red'
}});
var xmarker = marker.getPosition().lng();
var ymarker = marker.getPosition().lat();
var vertex = _path.getPath();
var totaldist = 0; // In pseudodegrees
// We calculate the total length of path in order to yield a relevant precision.
for (var i = 1; i < vertex.length; i++) {
x1 = vertex.getAt(i-1).lng();
y1 = vertex.getAt(i-1).lat();
x2 = vertex.getAt(i).lng();
y2 = vertex.getAt(i).lat();
totaldist = totaldist + Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));
}
var path_increment = totaldist / 1000; // This means precision on 0.1% of total path legth. Adjust accordingly.
var dist_to_marker = 1000;
var closest_x;
var closest_y;
var closest_percentage;
var partialdist = 0;
for (var i = 1; i < vertex.length; i++) {
x1 = vertex.getAt(i-1).lng();
y1 = vertex.getAt(i-1).lat();
x2 = vertex.getAt(i).lng();
y2 = vertex.getAt(i).lat();
var intervertex_dist = Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2)) ;
partialdist = partialdist + intervertex_dist;
var j=0;
var accumulated_dist = 0;
var azimut = Math.atan2((x2-x1),(y2-y1));
while ( accumulated_dist < intervertex_dist )
{
j++;
var delta_newx = path_increment * Math.sin(azimut);
var delta_newy = path_increment * Math.cos(azimut);
var newx = x1 + (delta_newx*j);
var newy = y1 + (delta_newy*j);
var new_dist_to_marker = Math.sqrt(Math.pow(xmarker-newx,2)+Math.pow(ymarker-newy,2));
if (new_dist_to_marker < dist_to_marker) {
closest_percentage = ((partialdist - intervertex_dist + ( path_increment * j)) / totaldist ) * 100;
closest_x = newx;
closest_y = newy;
dist_to_marker = new_dist_to_marker;
}
accumulated_dist = accumulated_dist + path_increment;
}
}
var marker = new google.maps.Marker({
position: {lat: closest_y, lng: closest_x},
map: map });
var infowindow = new google.maps.InfoWindow({ content:Math.round(closest_percentage)+'%' });
infowindow.open(map,marker);
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map" style="width:500px;height:500px;"></div>
</body>
</html>