When we use Google Maps, after we search something, Google will add a marker in the map. When we click on this marker, a detailed information window will show, just like this :
I search the "white house",then it create a marker "A".
This is not difficult. However I found something more interesting:
In the map view, even we do not search anything, when the map zoom to some specified level, there will be some anchors generated. If the mouse over it or click it, it will show something accordingly, see the image:
Here see the point "14H and F st NW". I did not search for it, but it show me an anchor. When I click it, it show me a information window accordingly.
But when I use Firebug to see what is downloading, I found that they are just images. I can not find any <a>
tag in the HTML.
Also, through Firebug, I found when the map level changed, the browser will send a request to the server to get the features inside the current map view. The response are JSON format. It contain the location and name of the features, then it add the anchors in the map.
But I wonder how do they implement it?
Possible manner to implement this:
1)when the map zoom or pan,request feature location data from server,suppose they get the following data(just take the white house for example):
data:{{name:'white house',Latitude:-77 longitude:38}}
2)bind mouse over event to the map div,something like this:
$("#map").mousemove(function(e){
for(var i=0;i<data.length;i++){
if(e.clientX=getImageX(data[i].x) && e.clientY=getImageY(data[i].y)){
//it mean that the mouse is overing this feature,now set the cousor and show the tip
//show tip,see the iamge:
}
}
});
3)bind the click event to the map div"
$("#map").mousemove(function(e){
for(var i=0;i<data.length;i++){
if(e.clientX=getImageX(data[i].x) && e.clientY=getImageY(data[i].y)){
//it mean that the mouse is clicking this feature,show the infomation window
//show tip,see the iamge:
}
}
});
The above is what I can thougth until now. But it seems that it is not enough, there are still some problems:
1) The tip can information window can show only if the user click or mouser over the very point which is the same as the Latitude and longitude of the feature,but in google Map,you will find that if the mouse over the marker(at any point of the marker),the tip will show. The area which will cause the tip show is the same as the the area of the marker.
It seems that google do someting like this:
$("#map").mousemove(function(e){
for(var i=0;i<data.length;i++){
if(e.clientX.insideTheMarker(data[i]) && e.clientY=insideTheMarker(data[i])){
//it mean that the mouse is clicking this feature,show the infomation window
}
}
});
But the marder size is not the same,how do they caculate the real area which will make the tip show?
2)in the eventhandle function,I haev to iterator all the features to see if the current mouse's location is match with any of the feat开发者_开发问答ure,if the featrues in current map view is so many,so it must cause performance problem.
It is likely an onclick event for the image or the map div. You can put an onclick handler on any DOM element. In this case they probably If they put the event on the map div since there is likely to be a lot of images that would have events and that could be a performance issue.
When you handle the click event for a child element in a parent element it is called event delegation. jQuery provides 2 functions for doing event delegation .live and .delegate. Other libraries also provide this functionality, but you can read about the basics this general javascript turorial or this jQuery specific tutorial.
They are probably doing something like (modified from here):
// Get the map canvas
var mapcanvas = document.getElementById('map_canvas');
// Quick and simple cross-browser event handler - to compensate for IE's attachEvent handler
function addEvent(obj, evt, fn, capture) {
if ( window.attachEvent ) {
obj.attachEvent("on" + evt, fn);
}
else {
if ( !capture ) capture = false; // capture
obj.addEventListener(evt, fn, capture)
}
}
// Check to see if the node that was clicked is an anchor tag. If so, proceed per usual.
addEvent(mapcanvas, "click", function(e) {
// Firefox and IE access the target element different. e.target, and event.srcElement, respectively.
var target = e ? e.target : window.event.srcElement;
if ( target.nodeName.toLowerCase() === 'img' ) {
alert("clicked");
return false;
}
});
As for making the the image look like an anchor (i.e. the pointer mouse icon), that can be set with css by setting the cursor property:
#map_canvas img { cursor: pointer }
精彩评论