2011-03-25 41 views
5

Estoy revolviendo con la v3 de la API de Google Maps y usando el complemento de InfoBox (parte de la suite http://google-maps-utility-library-v3.googlecode.com/) junto con algunas ventanas de información muy bien diseñadas que reaccionan a las interacciones de marcadores .Google Maps API v3 Evento mouseover con complemento de InfoBox

Para este experimento en particular, he intentado obtener la ventana emergente de InfoBox cuando el marcador se ha movido una y otra vez, sin embargo he tenido problemas para resolver el problema con el sistema de evento con respecto al mouseover/mouseout Ventana de InfoBox. Lo que ocurre es que puedo ubicar el DIV y usar un google.maps.event.addDomListener para adjuntar un evento mouseover y mouseout al InfoBox, excepto que es demasiado complicado: cuando muevo el mouse sobre un nodo secundario dentro del InfoBox, cuenta como un mouseout en el nodo padre y dispara el evento.

¿Está esto de alguna manera relacionado con la propagación? Sé que InfoBox tiene un interruptor enableEventPropagation cuando se crea un nuevo InfoBox, pero no estoy muy seguro de cómo y por qué se usaría.

El objetivo del experimento es crear una ventana de información con enlaces relacionados dentro que aparece al pasar el mouse sobre el marcador. Luego puede mover el mouse dentro de la ventana de información e interactuar y cuando salga del mouse cerrará la ventana de información. He intentado con otro método donde el mouseover en el marcador desencadena una función externa que crea un elemento de ventana de información externa que está posicionado y tiene su propio manejo de eventos. Eso funciona bien, pero la superposición de la ventana de información personalizada en la parte superior del mapa significa que cuando pasa el mouse sobre otro marcador muy cerca (debajo de la ventana de información personalizada) no puede registrar el mouseover para el marcador.

Este fue mi intento en el método de Caja de información:

<!DOCTYPE html> 
<html> 
<head> 
<style type="text/css"> 
<!-- 
    #map { 
     width:     800px; 
     height:     600px; 
     margin:     50px auto; 
    } 

    .map-popup { 
     overflow:    visible; 
     display:    block; 
    } 

    .map-popup .map-popup-window { 
     background:    #fff; 
     width:     300px; 
     height:     140px; 
     position:    absolute; 
     left:     -150px; 
     bottom:     20px; 
    } 

    .map-popup .map-popup-content { 
     padding:    20px; 
     text-align:    center; 
     color:     #000; 
     font-family:   'Georgia', 'Times New Roman', serif; 
    } 
--> 
</style> 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox_packed.js"></script> 
<script type="text/javascript"> 

    var gmap, gpoints = []; 

    function initialize() { 
     gmap = new google.maps.Map(document.getElementById('map'), { 
      zoom:    9, 
      streetViewControl: false, 
      scaleControl:  false, 
      center:    new google.maps.LatLng(-38.3000000,144.9629796), 
      mapTypeId:   google.maps.MapTypeId.ROADMAP 
     }); 

     for (var i=0; i<5; i++) { 
      gpoints.push(new point(gmap)); 
     } 
    } 

    function popup(_point) { 
     _point.popup = new InfoBox({ 
      content:   _point.content, 
      pane:    'floatPane', 
      closeBoxURL:  '', 
      alignBottom:  1 
     }); 

     _point.popup.open(_point.marker.map, _point.marker); 

     google.maps.event.addListener(_point.popup, 'domready', function() { 
      // Have to put this within the domready or else it can't find the div element (it's null until the InfoBox is opened) 
      google.maps.event.addDomListener(_point.popup.div_, 'mouseout', function() { 
       _point.popup.close(); 
      }); 
     }); 
    } 

    function point(_map) { 
     this.marker = new google.maps.Marker({ 
      position:   new google.maps.LatLng(-37.8131869 - (1 * Math.random()),144.9629796 + (1 * Math.random())), 
      map:    _map 
     }); 

     this.content = '<div class="map-popup"><div class="map-popup-window"><div class="map-popup-content"><a href="http://www.google.com/">Just try to click me!</a><br/>Hovering over this text will result in a <code>mouseout</code> event firing on the <code>map-popup</code> element and this will disappear.</div></div>'; 

     // Scope 
     var gpoint = this; 

     // Events 
     google.maps.event.addListener(gpoint.marker, 'mouseover', function() { 
      popup(gpoint); 
     }); 
    } 

</script> 
</head> 
<body onload="initialize()"> 
    <div id="map"></div> 
</body> 
</html> 

así que supongo que si alguien sabe cómo hacer este trabajo y responder adecuadamente (o proporcionar consejos/trucos pertinentes) entonces eso sería genial!

+0

¿Alguna vez encontró una buena solución para esto? El siguiente ejemplo de jQuery parece que se dirige a la ventana emergente y no al marcador.Tengo problemas para ver cómo implementarlo de esa manera usando InfoBox. Al actualizar a la última versión de desarrollo de InfoBox y activar la propagación de eventos, pude hacer que la ventana emergente no saltara a ningún marcador subyacente debajo de la ventana emergente. –

Respuesta

11

He tenido el mismo problema. Tal como usted dice, el problema es que mouseout se activa cuando se mueve a uno de los elementos secundarios. La solución es utilizar mouseenter y mouseleave (jQuery es necesario), consulte esta publicación para obtener más información: Hover, mouseover and mouse out

En este caso, no es posible utilizar el detector de eventos de google maps (no es compatible con mouseenter). En su lugar, puede adjuntar un evento jQuery normal o usar la función de desplazamiento como se muestra en el siguiente código:

google.maps.event.addListener(_point.popup, 'domready', function() { 
//Have to put this within the domready or else it can't find the div element (it's null until the InfoBox is opened) 

    $(_point.popup.div_).hover(
     function() { 
      //This is called when the mouse enters the element 
     }, 
     function() { 
      //This is called when the mouse leaves the element 
      _point.popup.close(); 
     } 
    ); 
});  
+0

¡Gracias, esto me ayudó mucho! –

+0

En las funciones de desplazamiento, configuro una variable para indicar si la ventana emergente está abierta. Luego, en la devolución de llamada "mouseover" para el marcador, solo muestro el cuadro de información si aún no está abierto. Por último, agregué un evento 'clickclose' para restablecer la variable que indica que la ventana emergente está cerrada. Infobox finalmente funciona correctamente cuando se superpone a un marcador. – yitwail

+0

la forma más reciente de usar esto con jquery: 'google.maps.event.addListener (_point, 'domready', function() {$ (_ point.div _). Mouseover (función (e) {...' – user151496

2

Lo que pasa es que puedo localizar el DIV y utilizar un google.maps.event.addDomListener para conectar un ratón encima y eventos mouseout a la Caja de información, a excepción de que sea demasiado incómoda - cuando mouseOver un nodo secundario dentro de la InfoBox, cuenta como un mouseout en el nodo padre y dispara el evento.

Un enfoque ingenuo para superar este podría ser para atravesar el árbol de elementos en el controlador de mouseout y para comprobar si se encuentra el DIV o terminan en la raíz del documento. Si encuentra el DIV, el mouse aún está dentro de la ventana emergente y no necesita cerrarlo.

jQuery resuelve este problema muy bien al introducir un segundo evento, mouseleave, que se comporta como es de esperar y se implementa de una manera similar a la explicada anteriormente. El jQuery sourcecode tiene un cierre especial withinElement para este caso que puede valer la pena mirar.

Cuestiones relacionadas