【问题标题】:Google Maps API v3 Event mouseover with InfoBox plugin带有 InfoBox 插件的 Google Maps API v3 事件鼠标悬停
【发布时间】:2011-07-22 17:09:32
【问题描述】:

我正在使用 v3 的 Google Maps API 并结合使用 InfoBox 插件(http://google-maps-utility-library-v3.googlecode.com/ 套件的一部分)来制作一些样式精美的信息窗口,以响应标记交互。

对于这个特定的实验,我尝试在标记悬停时弹出 InfoBox 窗口,但是我一直在努力解决事件系统关于 InfoBox 上的 mouseover/mouseout 的问题窗户。发生的情况是我可以找到 DIV 并使用google.maps.event.addDomListener 将鼠标悬停和鼠标悬停事件附加到信息框,但它太繁琐了——当我将鼠标悬停在信息框中的子节点上时,它算作父节点上的鼠标悬停节点并触发事件。

这是否与传播有关?我知道当你创建一个新的 InfoBox 时 InfoBox 有一个 enableEventPropagation 开关,但我不太确定如何以及为什么会使用它。

实验的目的是创建一个包含相关链接的信息窗口,该窗口在鼠标悬停时出现。然后,您可以在信息窗口内移动鼠标并进行交互,当您将鼠标移出时,它将关闭信息窗口。我尝试了另一种方法,其中标记上的鼠标悬停触发一个外部函数,该函数创建一个外部信息窗口元素,该元素已定位并具有自己的事件处理。这很好用,但自定义信息窗口在地图顶部的分层意味着当您将鼠标悬停在附近的另一个标记上(在自定义信息窗口下)时,它无法为该标记注册鼠标悬停。

这是我对 InfoBox 方法的尝试:

 <!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>

所以我想如果有人知道如何使这项工作正常进行并正确响应(或提供相关提示/技巧),那就太好了!

【问题讨论】:

  • 你有没有找到一个好的解决方案?下面的 jQuery 示例看起来像是针对弹出窗口本身而不是标记。我无法看到如何使用 InfoBox 以这种方式实现它。通过升级到 InfoBox 的最新开发版本并打开事件传播,我能够让弹出窗口不跳转到弹出窗口下方的任何底层标记。

标签: javascript google-maps


【解决方案1】:

我可以找到 DIV 并使用 google.maps.event.addDomListener 将 mouseover 和 mouseout 事件附加到 InfoBox,但它太复杂了——当我将鼠标悬停在 InfoBox 中的子节点上时,它在父节点上算作 mouseout 并触发事件。

解决这个问题的一种简单方法是在您的mouseout 处理程序中向上遍历元素树,并检查您是否找到了 DIV 或最终到达文档根目录。如果找到 DIV,则鼠标仍在弹出窗口内,无需关闭。

jQuery 通过引入第二个事件mouseleave 很好地解决了这个问题,它的行为与您期望的一样,并且以与上述类似的方式实现。对于这种情况,jQuery sourcecode 有一个特殊的闭包 withinElement,可能值得一看。

【讨论】:

    【解决方案2】:

    我也遇到了同样的问题。正如您所说的那样,问题是在移动到其中一个子元素时会触发 mouseout。解决方案是改用 mouseenter 和 mouseleave(需要 jQuery),有关更多信息,请参阅此帖子:Hover, mouseover and mouse out

    在这种情况下,无法使用 google maps 事件监听器(它不支持 mouseenter)。相反,您可以附加一个普通的 jQuery 事件,或者使用悬停功能,如下面的代码所示:

    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();
            }
        );
    });    
    

    【讨论】:

    • 感谢这对我帮助很大!
    • 在悬停函数中,我设置了一个变量来指示弹出窗口是否打开。然后在标记的“鼠标悬停”回调中,如果信息框尚未打开,我只会显示信息框。最后,我添加了一个“clickclose”事件来重置指示弹出窗口已关闭的变量。当信息框覆盖标记时,它终于可以正常工作了。
    • 最近使用 jquery 的方法:google.maps.event.addListener(_point, 'domready', function() { $(_point.div_).mouseover(function(e){ ...
    猜你喜欢
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 2011-09-27
    • 2016-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多