javascript 带有 InfoBox 插件的 Google Maps API v3 事件鼠标悬停

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5429444/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 17:10:32  来源:igfitidea点击:

Google Maps API v3 Event mouseover with InfoBox plugin

javascriptgoogle-maps

提问by Matt Scheurich

I'm mucking around with v3 of the Google Maps API and using the InfoBox plugin (part of the http://google-maps-utility-library-v3.googlecode.com/suite) in conjunction to make some nicely styled info windows that react to marker interactions.

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

For this particular experiment, I've attempted to get the InfoBox window pop-up when the marker has been hovered over and out, however I've struggled to resolve the issue with the event system regarding mouseover/mouseout on the InfoBox window. What happens is that I can locate the DIV and use a google.maps.event.addDomListenerto attach a mouseover and mouseout event to the InfoBox, except it's too fiddly -- when I mouseover a child node within the InfoBox, it counts as a mouseout on the parent node and fires the event.

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

Is this somehow related to propagation? I know InfoBox has a enableEventPropagationswitch when you create a new InfoBox, but I'm not quite sure how and why it would be used.

这在某种程度上与传播有关吗?我知道enableEventPropagation在创建新的 InfoBox 时InfoBox 有一个开关,但我不太确定如何以及为什么使用它。

The aim of the experiment is to create an info window with related links inside that appears on mouseover of the marker. You can then move the mouse inside the info window and interact and when you mouse out it will close the info window. I've tried another method where the mouseover on the marker triggers an external function that creates an external info window element that's positioned and has its own event handling. That works fine, but the layering of the custom info window on top of the map means that when you mouse over another marker in close proximity (under the custom info window) it can't register the mouseover for the marker.

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

This was my attempt at the InfoBox method:

这是我对 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>

So I guess if anyone knows how to make this work and respond properly (or provide relevant tips/tricks) then that would be great!

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

回答by anyman

I have had the same problem. Just as you say the issue is that mouseout is triggered when moving to one of the child elements. The solution is to instead use mouseenter and mouseleave (jQuery needed), see this post for more information: Hover, mouseover and mouse out

我曾经也有过一样的问题。正如您所说,问题在于移动到子元素之一时会触发鼠标移出。解决方案是改用 mouseenter 和 mouseleave(需要 jQuery),查看这篇文章了解更多信息:Hover, mouseover and mouse out

In this case it is not possible to use the google maps event listener (it does not support mouseenter). Instead you can attach a normal jQuery event, or use the hover function as shown in the following code:

在这种情况下,无法使用 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();
        }
    );
});    

回答by digitalbreed

What happens is that I can locate the DIV and use a google.maps.event.addDomListener to attach a mouseover and mouseout event to the InfoBox, except it's too fiddly -- when I mouseover a child node within the InfoBox, it counts as a mouseout on the parent node and fires the event.

发生的事情是我可以找到 DIV 并使用 google.maps.event.addDomListener 将鼠标悬停和鼠标移出事件附加到信息框,除非它太繁琐——当我将鼠标悬停在信息框内的子节点上时,它算作mouseout 在父节点上并触发事件。

A naive approach to overcome this could be to traverse the element tree up in your mouseouthandler and to check whether you find the DIV or end up at the document root. If you find the DIV, the mouse is still within the popup and you don't need to close it.

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

jQuery solves this problem nicely by introducing a second event, mouseleave, which behaves as you would expect it and is implemented in a similar manner as explained above. The jQuery sourcecodehas a special closure withinElementfor this case which may be worth looking at.

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