如果在 mouseMove 事件中重绘矩形,GoogleMaps 会丢失 mouseUp 事件

发布于 2024-12-17 08:47:31 字数 3066 浏览 4 评论 0原文

下面的代码示例让我感到困惑。这是我可以用来演示我的问题的一段较大代码的最简单版本。基本上我希望用户能够通过按住鼠标键并拖动它来绘制边界框。

如果我在 mouseMove 函数中使用 setBounds 重绘矩形,我永远不会看到 mouseUp 事件!如果我在 mouseMove 函数中禁用矩形的重绘,我会收到 mouseUp 事件。我可以通过在 mouseUp 事件中绘制矩形来部分解决此问题,但用户在拖动框时看不到轮廓。

您可以在 http://www.geoffschultz.org/Test/bounding_box 中查看此代码示例的实际运行情况.html

这是代码:

<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
        <style type="text/css">
            html { height: 100% }
            body { height: 100%; margin: 0; padding: 0 }
            #mapdiv { height: 100% }
        </style>
        <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
        <script type="text/javascript">
            var map, mouseDownPos, gribBoundingBox = "", mouseIsDown = 0;

        function display_map()
        {       
            var latlng = new google.maps.LatLng(42, -71);
            var myOptions = {zoom: 8, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP};
            map = new google.maps.Map(document.getElementById("mapdiv"), myOptions);

            google.maps.event.addListener(map,'mousemove',function(event) {mouseMove(event);}); 
            google.maps.event.addListener(map,'mousedown',function(event) {mouseDown(event);});
            google.maps.event.addListener(map,'mouseup',function(event) {mouseUp(event);}); 
        }

        function mouseMove(event)
        {
            if (mouseIsDown)
            {
            if (gribBoundingBox) // box exists
                {
                var bounds = new google.maps.LatLngBounds(gribBoundingBox.getBounds().getSouthWest(), event.latLng);
                gribBoundingBox.setBounds(bounds); // If this statement is enabled, I lose mouseUp events
                }
            else // create bounding box
                {
                var bounds = new google.maps.LatLngBounds(mouseDownPos, event.latLng);
                gribBoundingBox = new google.maps.Rectangle({map: map, bounds: bounds, fillOpacity: 0.05, strokeWeight: 1});
                }
            }
        }

        function mouseDown(event)
        {
            mouseIsDown = 1;
            mouseDownPos = event.latLng;
            map.setOptions({draggable: false});
        }

        function mouseUp(event)
        {
            if (mouseIsDown)
            {
                mouseIsDown = 0;
                map.setOptions({draggable: true});
        //      var bounds = new google.maps.LatLngBounds(mouseDownPos, event.latLng);
        //      gribBoundingBox.setBounds(bounds); // If used instead of above, box drawn properly
                gribBoundingBox.setEditable(true);
            }
        }
    </script>
</head>

<body onload="display_map()">
    <div id="mapdiv" style="width:100%; height:100%"></div>
</body>
</html>

The following code sample has me baffled. It's the simplest version of a larger piece of code that I can use to demonstrate my problem. Basically I want the user to be able to draw a bounding box by holding down the mouse key and dragging it.

If I redraw the rectange using a setBounds in the mouseMove function, I never see the mouseUp event! If I disable the redrawing of the rectangle in the mouseMove function, I get the mouseUp event. I can partially work around this by drawing the rectangle in the mouseUp event, but then the user can't see the outline as they are dragging the box.

You can see this code sample in action at http://www.geoffschultz.org/Test/bounding_box.html

Here is the code:

<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
        <style type="text/css">
            html { height: 100% }
            body { height: 100%; margin: 0; padding: 0 }
            #mapdiv { height: 100% }
        </style>
        <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
        <script type="text/javascript">
            var map, mouseDownPos, gribBoundingBox = "", mouseIsDown = 0;

        function display_map()
        {       
            var latlng = new google.maps.LatLng(42, -71);
            var myOptions = {zoom: 8, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP};
            map = new google.maps.Map(document.getElementById("mapdiv"), myOptions);

            google.maps.event.addListener(map,'mousemove',function(event) {mouseMove(event);}); 
            google.maps.event.addListener(map,'mousedown',function(event) {mouseDown(event);});
            google.maps.event.addListener(map,'mouseup',function(event) {mouseUp(event);}); 
        }

        function mouseMove(event)
        {
            if (mouseIsDown)
            {
            if (gribBoundingBox) // box exists
                {
                var bounds = new google.maps.LatLngBounds(gribBoundingBox.getBounds().getSouthWest(), event.latLng);
                gribBoundingBox.setBounds(bounds); // If this statement is enabled, I lose mouseUp events
                }
            else // create bounding box
                {
                var bounds = new google.maps.LatLngBounds(mouseDownPos, event.latLng);
                gribBoundingBox = new google.maps.Rectangle({map: map, bounds: bounds, fillOpacity: 0.05, strokeWeight: 1});
                }
            }
        }

        function mouseDown(event)
        {
            mouseIsDown = 1;
            mouseDownPos = event.latLng;
            map.setOptions({draggable: false});
        }

        function mouseUp(event)
        {
            if (mouseIsDown)
            {
                mouseIsDown = 0;
                map.setOptions({draggable: true});
        //      var bounds = new google.maps.LatLngBounds(mouseDownPos, event.latLng);
        //      gribBoundingBox.setBounds(bounds); // If used instead of above, box drawn properly
                gribBoundingBox.setEditable(true);
            }
        }
    </script>
</head>

<body onload="display_map()">
    <div id="mapdiv" style="width:100%; height:100%"></div>
</body>
</html>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

如果更新矩形边界,则矩形会使用 mouseup 事件(这是因为鼠标光标现在位于矩形内)。有两种解决方案:

  1. 将矩形对象的clickable属性设置为false。那么矩形将不会消耗该事件。

    gribBoundingBox = new google.maps.Rectangle({map: map,bounds:bounds, fillOpacity: 0.05, strokeWeight: 1, clickable: false});

  2. 向矩形对象添加mouseup事件监听器。这样,事件就由矩形消耗和处理。在您的示例中,您可以使用相同的侦听器函数。

    google.maps.event.addListener(gribBoundingBox,'mouseup',function(event) {mouseUp(event);});

If you update the rectangle bounds, the mouseup event is consumed by the rectangle (it's because the mouse cursor is now positioned within the rectangle). There are two solutions to this:

  1. Set clickable property of the rectangle object to false. The rectangle won't consume the event then.

    gribBoundingBox = new google.maps.Rectangle({map: map, bounds: bounds, fillOpacity: 0.05, strokeWeight: 1, clickable: false});

  2. Add mouseup event listener to the rectangle object. This way the event is consumed and handled by the rectangle. In your example you can use the same listener function.

    google.maps.event.addListener(gribBoundingBox,'mouseup',function(event) {mouseUp(event);});

不即不离 2024-12-24 08:47:31

如果其他解决方案不起作用,还可以尝试在文档上注册 mouseup 事件。

document.addEventListener('mouseup', function(evt){
    stopDraw(evt);
});

One can also try to register a mouseup event on the document, if the other solution is not working.

document.addEventListener('mouseup', function(evt){
    stopDraw(evt);
});
萌能量女王 2024-12-24 08:47:31

如果 GoogleMaps 在使用 mouseMove 事件绘制(例如矩形)时间歇性丢失 mouseUp 事件,则可能是兴趣点 (POI) 拦截了 mouseUp 事件。

这可以通过使 POI 不可点击来解决(可以在 MapOptions 中设置)

const mapOptions: google.maps.MapOptions = {
        center: new google.maps.LatLng(0, 0),
        zoom: 1,
        minZoom: 1,
        clickableIcons: false
    };

这对我有用,但如果您需要/想要 POI,那么您可以考虑在 mouseDown 上禁用它们,或者考虑拦截它们的 mouseUp 事件并触发您想要的 mouseUp完成绘图。

If GoogleMaps intermittently loses mouseUp events when drawing (e.g. a rectangle) with a mouseMove event, it could be the Points Of Interest (POI) intercepting the mouseUp event.

This can be fixed by making POIs not clickable (can be set in the MapOptions)

const mapOptions: google.maps.MapOptions = {
        center: new google.maps.LatLng(0, 0),
        zoom: 1,
        minZoom: 1,
        clickableIcons: false
    };

This worked for me but if you need/want POIs then you could look into disabling them on mouseDown or look at intercepting their mouseUp events and firing your intended mouseUp for finishing drawing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文