如何在 Shadow DOM 中使用 div 作为 Leaflet 地图容器?

How to use a div inside a Shadow DOM as a Leaflet map container?

下面基于 JS 的自定义元素似乎可以工作,但找不到我添加到影子 DOM 根的 mapid div。在 Leaflet 或自定义元素中是否有一种方法允许库存 Leaflet(撰写本文时最新版本 1.4)查找和使用基于 DOM mapid div 的影子?

错误:

Uncaught Error: Map container not found.
    at NewClass._initContainer (Map.js:1102)
    at NewClass.initialize (Map.js:136)
    at new NewClass (Class.js:22)
    at Module.createMap (Map.js:1717)
    at new GDMap (gd-map.js:16)
    at gd-map.js:30
    at gd-map.js:31

我的方法是,这只是 Leaflet 在 dom 根目录中寻找 mapid div 而在影子 [=32] 中找不到的情况=].

Javascript

import * as L from './leaflet/leaflet-src.esm.js';

(function () {
    class GDMap extends HTMLElement {
        constructor() {
            super();

            this.attachShadow({ mode: 'open' });
            this.shadowRoot.innerHTML = `<div style="height:180px" id="mapid"></div>`;

           var map = L.map('mapid').setView([51.505, -0.09], 13);

            L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'

            }).addTo(map);


            L.marker([51.5, -0.09]).addTo(map)
                .bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
                .openPopup();

        }
    }
    window.customElements.define('geodex-map', GDMap);
})();

编辑 post 以对齐 div id 指出的..仍然是同样的问题。

我认为现在可以通过以下方式解决问题。

需要将地图 div 作为元素传递,而不是为 Leaflet 提供 id 字符串以供查找。还传递 CSS.

import * as L from './leaflet/leaflet-src.esm.js';

(function () {
    class GDMap extends HTMLElement {
        constructor() {
            super();

            let shadow = this.attachShadow({mode: 'open'});
            var mapdiv = document.createElement('div');
            mapdiv.setAttribute('id', 'mapid');
            // mapdiv.setAttribute('style', 'height:180px');
            mapdiv.style.height = "180px";
            mapdiv.innerHTML = ' <link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="crossorigin=""/>';
            shadow.appendChild(mapdiv);

            var map = L.map(mapdiv).setView([51.505, -0.09], 13);

            L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'

            }).addTo(map);

            L.marker([51.5, -0.09]).addTo(map)
                .bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
                .openPopup();

        }
    }
    window.customElements.define('geodex-map', GDMap);
})();

尝试在其容器位于 DOM 之前实例化 Leaflet 地图是 ,已知解决方案:

The <div id="leafletmap"> must be added to the dom before calling L.map('leafletmap').

但是你已经知道了,因为你提出了一个非常好的和具体的问题:

Is there a way in [Leaflet 1.4] to find and use a shadow DOM-based mapid div?

答案是"no, but"。

如果您仔细阅读 Leaflet API 参考资料,您会注意到 L.Map can be instantiated in two ways:要么通过提供 HTMLElementid地图的容器,或通过提供容器的HTMLElement实例

换句话说,类似于:

var mapdiv = document.createElement('div');
shadow.appendChild(mapdiv);
var map = L.map(mapdiv)