问题
Now that I can actually create an SVG marker here is my vision: The user clicks on the map, the click fires an Ajax query which retrieves "length" and "angle" values from a remote server, and using those values, and SVG arrow of the given lenght and angle is drawn at the click.
The Ajax part is easy, and once I have a length and angle, I can figure out the SVG syntax for an arrow. For now, I am trying to create the "click and create a random arrow". The code below kinda works. An arrow gets created at the "previous" click. That is, when I click on point 1, nothing happens. Then, when I click on point 2, an arrow is created at point 1, and so on for point(n-1) where n is the nth click.
<head>
<style type="text/css">
.quiver {width: 50px; height: 50px;}
</style>
<script type="text/javascript">
var map;
function div() {
var m = document.createElement('DIV');
m.innerHTML = '<div class="quiver"></div>';
return m;
}
function init() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(43, -89),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addListener(map, "click", function (event) {
var marker = new RichMarker({
map: map,
position: event.latLng,
draggable: true,
flat: true,
anchor: RichMarkerPosition.MIDDLE,
content: div()
});
$('.quiver').svg({
onLoad: function(svg) {
svg.line(
Math.random()*49, Math.random()*49, Math.random()*49, Math.random()*49,
{stroke: 'black', strokeWidth: 2}
);
}
});
});
/*
google.maps.event.addListenerOnce(map, 'idle', function() {
$('.quiver').svg({onLoad: drawArrow});
});
*/
}
google.maps.event.addDomListener(window, 'load', init);
</script>
</head>
回答1:
The problem here is similar to your previous question. When you are calling
$('.quiver').svg({
onLoad: function(svg) {
...
}
});
in the click event listener, the marker that's being created hasn't been attached to the DOM node tree yet. Nice reading about synchronization and timing in JavaScript here.
The (n-1)-th arrow is rendered because the jQuery $('.quiver') command selects all elements with quiver class (that's n-1 elements, the n-th isn't present in the DOM node tree yet) and only the (n-1)-th is applicable for the svg code.
Unfortunately, the map's idle event (or any other event in Google Maps API v3) won't help it this case.
I guess there are 2 solutions to the problem:
One solution is to target the created HTML element with jQuery directly in the click event listener.
$(marker.content).find('.quiver').svg({
onLoad: function(svg) {
svg.line(
Math.random()*49, Math.random()*49,
Math.random()*49, Math.random()*49,
{stroke: 'black', strokeWidth: 2}
);
}
});
The second solution is not to use jQuery svg plugin, but rather create the svg directly in div() function.
function div() {
var m = document.createElement('DIV');
m.innerHTML = '<div class="quiver"><svg xmlns="http://www.w3.org/2000/svg" version="1.1">' +
'<line x1="' + Math.random()*49 + '" y1="' + Math.random()*49 + '" ' +
'x2="' + Math.random()*49 + '" y2="' + Math.random()*49 + '" style="stroke:rgb(0,0,0);stroke-width:2"/></svg></div>';
return m;
}
and delete the jQuery $('.quiver').svg(...); command in the click event listener.
来源:https://stackoverflow.com/questions/7465191/creating-an-svg-marker-on-click-event