解决MapboxGL的Popup不支持HTMLDiv元素的问题
官网给出的文档是不支持HTMLDivElement的,只支持HTML标签。
如果单纯的只显示字符串,那就没问题,如果想在Popup中使用更强大的功能,此时就不行了,下面是源码的一部分显示如下:
/**
* Sets the popup's content to the HTML provided as a string.
*
* This method does not perform HTML filtering or sanitization, and must be
* used only with trusted content. Consider {@link Popup#setText} if
* the content is an untrusted text string.
*
* @param {string} html A string representing HTML content for the popup.
* @returns {Popup} Returns itself to allow for method chaining.
* @example
* const popup = new mapboxgl.Popup()
* .setLngLat(e.lngLat)
* .setHTML("<h1>Hello World!</h1>")
* .addTo(map);
* @see [Example: Display a popup](https://docs.mapbox.com/mapbox-gl-js/example/popup/)
* @see [Example: Display a popup on hover](https://docs.mapbox.com/mapbox-gl-js/example/popup-on-hover/)
* @see [Example: Display a popup on click](https://docs.mapbox.com/mapbox-gl-js/example/popup-on-click/)
* @see [Example: Attach a popup to a marker instance](https://docs.mapbox.com/mapbox-gl-js/example/set-popup/)
*/
setHTML(html: string): this {
const frag = window.document.createDocumentFragment();
const temp = window.document.createElement('body');
let child;
temp.innerHTML = html;
while (true) {
child = temp.firstChild;
if (!child) break;
frag.appendChild(child);
}
return this.setDOMContent(frag);
}
可以看出,他接受的是一个html字符串,导致我们想在Popup中使用Vue组件就不支持了。
解决方法如下
通过继承Popup重写setHTML方法,代码如下:
class PopupExtend extends Popup {
setHTML(html: HTMLDivElement | string): this {
const frag = window.document.createDocumentFragment()
const temp = window.document.createElement("body")
let child
temp.appendChild(html as HTMLDivElement)
while (true) {
child = temp.firstChild
if (!child) {
break
}
frag.appendChild(child)
}
return this.setDOMContent(frag)
}
}
我们使用Popup的时候,直接使用PopupExtend类,就不再使用默认的Popup了,代码如下:
const element = componentToElement(LayerPopupComponent, {}) as HTMLDivElement
new PopupExtend().setLngLat(e.lngLat).setHTML(element).addTo(this.map)
componentToElement方法如下:
// 组件转原生dom
componentToElement(component, props) {
const app = createApp({
render() {
return h(component, props)
}
});
app.use(ElementPlus);
return app.mount(document.createElement("div")).$el;
}
年三十还在搬砖,天选打工人,祝大家2024新年快乐,明年再战,完结,撒花✿✿ヽ(°▽°)ノ✿