Skip to content
目录

常见问题

InfoWindow点击图形后自动弹出

InfoWindow默认是和图形的点击事件绑定的,如果你不想自动弹窗可以把关联的事件写成null, 然后根据自己的需求自动打开

js
const marker = new maptalks.Marker([-0.113049, 51.49856]).addTo(layer);

marker.setInfoWindow({
    title: "Marker's InfoWindow",
    content: "Click on marker to open.",
    autoOpenOn: null,
    // 'autoPan': true,
    // 'width': 300,
    // 'minHeight': 120,
    // 'custom': false,
    //'autoOpenOn' : 'click',  //set to null if not to open when clicking on marker
    //'autoCloseOn' : 'click'
});

marker.on("click", (e) => {
    setTimeout(
        () => {
            //do some things
            e.target.openInfoWindow();
        },
        1000 * Math.random() + 500,
    );
});

怎样异步更新InfoWindow的内容

还是正常的绑定InfoWindow,在图形的点击事件里我们来动态请求图形的信息,然后把信息更新到InfoWindow即可

js
const marker = new maptalks.Marker([-0.113049, 51.49856]).addTo(layer);

marker.setInfoWindow({
    title: "Marker's InfoWindow",
    content: "Click on marker to open.",
    // 'autoPan': true,
    // 'width': 300,
    // 'minHeight': 120,
    // 'custom': false,
    //'autoOpenOn' : 'click',  //set to null if not to open when clicking on marker
    //'autoCloseOn' : 'click'
});

marker.on("click", (e) => {
    const infoWindow = e.target.getInfoWindow();
    infoWindow.setTitle("数据加载中....");
    infoWindow.setContent(defaultContent);
    //mock data fetch
    setTimeout(
        () => {
            infoWindow.setTitle("《滕王阁序》");
            infoWindow.setContent(
                document.getElementById("infowindow").outerHTML,
            );
        },
        500 + Math.random() * 1000,
    );
});

InfoWindow多例

InfoWindow 选项里有个single参数,默认是true,即单例,配置成false即可

js
point.setInfoWindow({
    // collision: true,
    single: false,
    content: `point${index + 1}`,
});

怎样批量管理UIMarker集合

maptalks里关于UI元素没有提供批量管理UIMarker的能力,why?

  • maptalks 里图层都是canvas/webgl渲染图层
  • UIMarker比较特殊,其是html渲染的,一般用来渲染一些特殊的东西,图表,表格,css动画等
  • 因为是html渲染所以无法和其他的图层位置三维深度关系

UI元素的操作一般是:

js
uiMarker.addTo(map);
uiMarker.remove();

如果你的业务里有这种批量和分类管理的需求,你可以自己抽象个UIMarker的图层管理工具, 下面是我写的一个简单的UIMarker管理图层类

WARNING

代码仅供参考,自己可以根据自己的需求做对应的修改,这里主要是模拟图层功能,以此来达到图形管理图层同样的API和使用习惯

js
class UIMarkerLayer {
    constructor() {
        this.markers = [];
        this.map = null;
        this.zIndex = null;
        this.maxZoom = null;
        this.minZoom = null;
        this.opacity = 1;
    }

    _checkMarkers() {
        if (!this.map) {
            return this;
        }
        this.markers.forEach((marker) => {
            if (!marker.getMap) {
                return;
            }
            if (!marker.getMap()) {
                marker.addTo(this.map);
            }
        });
        return this;
    }

    _removeMarkers(markers) {
        markers.forEach((marker) => {
            if (this.markers.indexOf(marker) > -1) {
                marker.remove();
            }
        });
        return this;
    }

    getMap() {
        return this.map;
    }

    addTo(map) {
        if (this.map) {
            console.warn("has add to map");
            return this;
        }
        this.map = map;
        this._checkMarkers();
        return this;
    }

    remove() {
        this._removeMarkers(this.markers);
        this.map = null;
        return this;
    }

    clear() {
        this._removeMarkers(this.markers);
        this.markers = [];
        return this;
    }

    show() {
        this.markers.forEach((marker) => {
            marker.options.visible = true;
        });
        return this;
    }

    hide() {
        this.markers.forEach((marker) => {
            marker.options.visible = false;
        });
        return this;
    }

    _markersArrayJudge(markers) {
        markers = Array.isArray(markers) ? markers : [markers];
        return markers.filter((marker) => {
            return !!(marker && marker.getMap);
        });
    }

    addMarker(markers) {
        markers = this._markersArrayJudge(markers);
        markers.forEach((marker) => {
            if (this.markers.indexOf(marker) === -1) {
                this.markers.push(marker);
            }
        });
        this._checkMarkers();
        return this;
    }

    removeMarker(markers) {
        markers = this._markersArrayJudge(markers);
        this._removeMarkers(markers);
        this.markers = this.markers.filter((marker) => {
            return markers.indexOf(marker) === -1;
        });
        return this;
    }

    getMarkers() {
        return this.markers.map((marker) => {
            return marker;
        });
    }

    setZIndex(zIndex) {
        if (!maptalks.Util.isNumber(zIndex)) {
            return this;
        }
        this.markers.forEach((marker) => {
            marker.setZIndex(zIndex);
        });
        this.zIndex = zIndex;
        return this;
    }

    getZIndex() {
        return this.zIndex;
    }

    setMinZoom(minZoom) {
        if (!maptalks.Util.isNumber(minZoom)) {
            return this;
        }
        this.markers.forEach((marker) => {
            marker.options.minZoom = minZoom;
        });
        this.minZoom = minZoom;
        return this;
    }

    getMinZoom() {
        return this.minZoom;
    }

    setMaxZoom(maxZoom) {
        if (!maptalks.Util.isNumber(maxZoom)) {
            return this;
        }
        this.markers.forEach((marker) => {
            marker.options.maxZoom = maxZoom;
        });
        this.maxZoom = maxZoom;
        return this;
    }

    getMaxZoom() {
        return this.maxZoom;
    }

    setOpacity(opacity) {
        if (!maptalks.Util.isNumber(opacity)) {
            return this;
        }
        opacity = Math.min(1, opacity);
        opacity = Math.max(0, opacity);
        this.markers.forEach((marker) => {
            const dom = marker.getDOM();
            if (dom) {
                dom.style.opacity = opacity;
            }
        });
        this.opacity = opacity;
        return this;
    }

    getOpacity() {
        return this.opacity;
    }
}
js
const layer = new UIMarkerLayer().addTo(map);

const coordinates = [
    [119.26945017383241, 30.376871910976178],
    [119.41899273004572, 30.377746042120833],
    [119.51608471650138, 30.37726503747328],
    [119.46354801648795, 30.31694687527127],
    [119.60562937352347, 30.37820924055947],
    [119.59045825643739, 30.430436461050107],
    [119.584406756833, 30.487931288984754],
    [119.51453485707066, 30.49039516064832],
    [119.45440953161744, 30.48646614394201],
    [119.69247157405653, 30.486815730590678],
    [119.80953084691987, 30.472457196921],
    [119.89535951684763, 30.47496435491533],
    [119.84708685095575, 30.36586547405281],
    [119.67054883716764, 30.303609976340255],
    [119.65234867735501, 30.363784873871822],
    [119.54423459602981, 30.480024325865287],
    [119.47395594040563, 30.56338903320065],
    [119.39707374359091, 30.53546677150925],
    [119.57396685725621, 30.574315977713553],
    [119.6401686202828, 30.569305689523247],
];

const markers = coordinates.map((c, index) => {
    return new maptalks.ui.UIMarker(c, {
        content: `<div class="marker">${index}</div>`,
    });
});

const markers1 = markers.slice(0, 5);
const markers2 = markers.slice(5, Infinity);

layer.addMarker(markers1);

UI Content 传参Dom报错

这种一般都是content的内容不和合法的HTMLElement导致的,比如可能是null,Array等

WARNING

注意在Vue里的v-forref拿到的dom节点是个数组,直接给content参数就会报这种错误

html
<div v-for="item in list">
    <div :ref="'infowindow_content'+item.name">
        <h2>{{name}}</h2>
        <input type="text" v-model="name" />
        <h4>count:{{count}}</h4>
        <button @click="add">count++</button><br /><br />
        <button v-for="item in btns">{{item}}</button>
    </div>
</div>
js
marker.setInfoWindow({
    // custom: true,
    content: this.$refs["infowindow_content1"],
});
marker.openInfoWindow();

所以业务里请做好对应的判断

UI内容元素不能滚动

UI元素比较特殊,其是随着地图的位置改变要改变其自己自身的位置的,所以要对其的事件 系统进行事件的冒泡的控制的,即缩放操作用于这个这个UI本身时也要冒泡到地图容器上,所以导致了 UI元素内容的滚动失效

maptalks里的UI元素有:

  • UIMarker
  • InfoWindow
  • Menu

InfoWindow和Menu都是默认禁用冒泡的,所以当其出现滚动时,其是可以滚动的, 但是UIMarker我们是当成Marker来看待和处理,默认是冒泡的,如果你想要其内容可以滚动, 你可以关闭冒泡

js
var uiMarker = new maptalks.ui.UIMarker(c, {
    content: profile.$el,
    verticalAlignment: "top",
    zIndex: 2,
    eventsPropagation: false,
});

WARNING

注意关闭冒泡后,UIMarker上的所有操作将不能作用到地图上了,所以业务里根据的需要配置合适的值

This document is generated by mdpress