在传单地图中,弹出窗口(创建为 L.Handler)在加载大 JavaScript 文件时不显示

In a leaflet map, popup (created as a L.Handler) not showing when loading a big JavaScript file

我有一些使用图层显示的数据。 我想在鼠标悬停时在弹出窗口中动态显示这些数据。

弹出窗口将显示在鼠标指针旁边。 弹出窗口将跟随光标并动态显示图层相对于鼠标指针位置的数据。

问题:

总的来说效果很好,但是当我加载大量af数据时,弹出窗口不会出现。但是,如果用户将鼠标指针移到视口之外,然后再次将鼠标指针移到视口内,则会显示弹出窗口。显然它不是用户友好的:-),所以我希望即使在加载大量数据时也能显示弹出窗口。

我尝试了不同的方法来创建弹出窗口,使用 jQuery $(document).ready 来确保数据已被加载,等等,但是 none 这些方法有效。我 运行 没主意了。但这似乎与浏览器加载数据所花费的时间有关。 有人可以帮我解决这个问题吗?

注意:根据数据量的不同,它有时在 Chrome 中有效,但在 Firefox 中无效。

这是一个可重现的示例和一个生成 data.js 文件的脚本。

HTML 页面:

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
    <style type="text/css">
    #map {
        position: absolute;
        height: 100%;
        width: 100%;
        background-color: #333;
    }
    </style>
</head>

<body>
    <div id="map"></div>
    <!-- Loading "big" data -->
    <script src="data.js"></script>
    <script type="text/javascript">
    $(document).ready(function() {

        // Create a cursor handler
        // In order to display informations in a popup next to cursor
        // (the popup will follow the mouse pointer) 
        L.CursorHandler = L.Handler.extend({
            addHooks: function() {
                this._popup = new L.Popup({ autoPan: false });
                this._map.on('mouseover', this._open, this);
                this._map.on('mousemove', this._update, this);
                this._map.on('mouseout', this._close, this);
            },

            removeHooks: function() {
                this._map.off('mouseover', this._open, this);
                this._map.off('mousemove', this._update, this);
                this._map.off('mouseout', this._close, this);
            },

            _open: function(e) {
                this._update(e);
                this._popup.openOn(this._map);
            },

            _close: function() {
                this._map.closePopup(this._popup);
            },

            _update: function(e) {
                var text_to_display = "Data";
                this._popup.setLatLng(e.latlng).setContent(text_to_display);
            }
        });

        L.Map.addInitHook('addHandler', 'cursor', L.CursorHandler);

        // Create map
        var map = L.map("map", { zoom: 6, center: [0, 0] });

        // To enable popup display next to cursor
        map.cursor.enable();

    });
    </script>
</body>
</html>

生成包含数据的js文件的脚本:

真正的数据是对象和数组的数组。 该脚本将生成一个 100 MB 的文件(因为它似乎与浏览器加载数据所花费的时间有关)。 这是一个 100 MB 的文件,以确保它可以重现。我的测试表明,对于 5MB 的文件,有时会显示弹出窗口,有时不会。对于 10 MB 的文件,90% 的时间都不会弹出。对于 100MB 的文件,100% 的时间都不会弹出。

在Python中:

# Create a 100 MB file
big_string = '1234567890' * 10000000
javascript_variable = 'var data = "' + big_string + '";'

with open("data.js", "w") as f:
    f.write(javascript_variable)

在 JS 中:

big_string = '1234567890'.repeat(10000000)
javascript_variable = 'var data = "' + big_string + '";'
// Then copy-paste the object in a "data.js" file

我认为如果在 _update 函数中添加一个检查弹出窗口是否打开的功能,就可以防止这种情况发生:

_update: function(e) {
        var text_to_display = "Data";
        this._popup.setLatLng(e.latlng).setContent(text_to_display);
        if(!this._popup.isOpen()){
          this._popup.openOn(this._map);
        }
      }

而且我建议将这个选项添加到弹出窗口中,这样当您点击地图时它就不会关闭。

this._popup = new L.Popup({ autoPan: false, autoClose: false, closeOnClick: false });