NrW7MQcYO

23朵毒蘑菇

高德地图太坑了,关于使用new AMap.Marker创建点位后点位点击事件不准确的坑

说是坑呢又是自己造成的,但是这很难排查出来,花了我半天时间

高德地图

2023-09-08 18:00:07 已有版本 1 个 show:0.64kTYPE: blog

点击事件不准确

当我使用 new AMap.Marker创建点位,使用content属性自定义点位html,然后刷新页面,完全没毛病,当我跳转到其他地图页面时,注意,其他页面的地图都是 new AMap.Map重新初始化了的,然后就出现点击事件不灵了,反而点击其他会触发点位事件。

经过多方排查终于解决问题,原来是换行的问题

let marker = new AMap.Marker({
    position: new AMap.LngLat(...point),
    content:`
        <div style="position: absolute;transform: translate(-50%,-100%);pointer-events: none;">
            <div style="display: flex;flex-direction: column;justify-content: center;align-items: center;pointer-events: none;">
                <div style="
                    width: max-content;
                    height: fit-content;
                    padding:0.625rem 0.938rem;
                    text-align: center;
                    font-size: 1.125rem;
                    font-weight: bold;
                    box-sizing: border-box;color: #ffffff;
                    background: linear-gradient(180deg, #019178 0%, #177C6F 100%);
                    box-shadow: 0.000rem 0.438rem 0.688rem 0.000rem rgba(3,80,68,0.26);
                    border-radius: 0.313rem;
                    pointer-events: initial;
                ">${name}</div>
                <img
                    style="
                        margin-top:0.313rem;
                        width: 1.188rem;
                        height: 10.438rem;
                        object-fit: contain;
                        pointer-events: initial;
                    " 
                    src="${img_1}">
            </div>
        </div>
    `,
    // offset: ['50%','50%'],
});

可以看到,我在content属性使用了模板语法,并且模板语法第一行使用了换行,这就是问题所在,如果有换行,那么它会在第一个父级元素(类名 amap-marker-content)那儿加一个css white-space: pre;,我是不知道为啥第一次刷新的时候没有这个父级元素,然后后面调用 new AMap.Map的实例就不行了,还非得刷新一次页面才行,它是有什么数据给全局缓存了一下吗?

修改后的组件模板代码,方便其他地方复制粘贴

<script>
/** 
 * 盒子
 * 向外部暴露方法,由外部调用
 *  */
import { defineComponent,ref,getCurrentInstance,reactive,toRef, computed,onMounted,onActivated,watch,onUnmounted } from "vue";
import { useRouter,useRoute } from "vue-router";
import img_1 from "@/assets/big-screen-imgs/img-1/icon-3-2x.png";
import MapInfoDataDialog from "./MapInfoDataDialog.vue";

export default defineComponent({
    components: {
        MapInfoDataDialog,
    },
    setup(){
        const ContainerRef = ref(null);  //组件实例
        const MapRef = ref(null);  //组件实例
        const MapInfoDataDialogRef = ref(null);  //组件实例
        const dataContainer = reactive({
            loading:false,
            img:{
                img_1,
            },
        });
        const otherContainer = {
            map:'',
        };
        onUnmounted(()=>{
            destroyMap();
        });
        /** 销毁控件 */
        function destroyMap(){
            if(otherContainer.map){
                otherContainer.map.clearMap();
                otherContainer.map.destroy();
            }
        }
        /** 
         *  初始化地图
         *  可外部调用
         *  */
        function initMapContent() {
            if(!MapRef.value) return;
            destroyMap();
            otherContainer.map = new AMap.Map(MapRef.value, {
                resizeEnable: true,
                center: [116.397428, 39.90923],
                zoom: 13,
            });
            // 卫星图
            otherContainer.satellite = new AMap.TileLayer.Satellite({
                map: otherContainer.map,
            });
            // otherContainer.satellite.hide();
        }
        // onMounted(()=>{
        //     initMapContent();
        // });
        /** 
         * 创建一个标记点
         *  */
        function createMarker({point,instanceType=1,type=1,params={}}={}){
            /** 表示是点位 */
            if(instanceType == 1){
                let img,img_1,color,name;
                switch(true){
                    case type==1:
                        img = dataContainer.img.img_1;
                        img_1 = dataContainer.img.img_1;
                        color = "#2dd9dc";
                        name = params.name;
                        break;
                }
                let marker = new AMap.Marker({
                    position: new AMap.LngLat(...point),
                    content:`<div style="position: absolute;transform: translate(-50%,-100%);pointer-events: none;">
                            <div style="display: flex;flex-direction: column;justify-content: center;align-items: center;pointer-events: none;">
                                <div style="
                                    width: max-content;
                                    height: fit-content;
                                    padding:0.625rem 0.938rem;
                                    text-align: center;
                                    font-size: 1.125rem;
                                    font-weight: bold;
                                    box-sizing: border-box;color: #ffffff;
                                    background: linear-gradient(180deg, #019178 0%, #177C6F 100%);
                                    box-shadow: 0.000rem 0.438rem 0.688rem 0.000rem rgba(3,80,68,0.26);
                                    border-radius: 0.313rem;
                                    pointer-events: initial;
                                ">${name}</div>
                                <img
                                    style="
                                        margin-top:0.313rem;
                                        width: 1.188rem;
                                        height: 10.438rem;
                                        object-fit: contain;
                                        pointer-events: initial;
                                    " 
                                    src="${img_1}">
                            </div>
                        </div>`,
                    // offset: ['50%','50%'],
                });
                return marker;
            }
        }
        /** 
         * 初始化数据
         * 可外部调用
         *  */
        function initData(){
            if(!otherContainer.map) return;
            var markers = [
                [116.205467, 39.907761],
                [116.368904, 39.913423],
                [116.305467, 39.807761],
            ].map(item=>{
                return createMarker({
                    point:item,
                    type:1,
                    instanceType:1,
                    params:{
                        name:'边坡村地质灾害监测点',
                    },
                });
            });
            markers.forEach(item=>{
                item.on('click',(e)=>{
                    showInfo({
                        name:'啊是大多数',
                    });
                });
                // otherContainer.map.add(item);
                item.setMap(otherContainer.map);
            });
            otherContainer.map.setFitView(
                markers,
                false,  // 动画过渡到制定位置
                [400, 100, 300, 300],  // 周围边距,上、下、左、右
            );
        }
        /** 查看详情 */
        function showInfo(data){
            if(!MapInfoDataDialogRef.value) return;
            MapInfoDataDialogRef.value.initData(true,data);
        }
        return { 
            dataContainer,
            ContainerRef,
            initData,
            showInfo,
            MapInfoDataDialogRef,
            initMapContent,
            MapRef,
        };
    },
});
</script>

<template>
    <div
        ref="ContainerRef" 
        class="box-cp-container">
        <div 
            class="map-content"
            ref="MapRef"></div>
        <MapInfoDataDialog
            ref="MapInfoDataDialogRef">
        </MapInfoDataDialog>
    </div>
</template>

<style lang="scss" scoped>
.box-cp-container{
    width: 100%;
    height: 100%;
    >.map-content{
        width: 100%;
        height: 100%;
    }
}
</style>