用户登录
个人主页 用户中心 我的订单 添加授权 管理授权
退出登录
用户登录 用户注册
欢迎来到 UC建站系统

网站里做一个点击展开的地图,四行CSS加一个百度地图API调用就能搞定,展开动画、懒加载、移动端适配都有现成方案

公司网站上要放一个地图展示位置,"联系我们"页面经常用,但地图一加载就是几百KB的JS,首页打开慢了2秒,客户还没看到地址就走了。这个问题其实用展开收起+懒加载两步就能解决——平时只显示一个"查看地图"按钮,客户点了才加载地图,展开过程还有平滑动画。下面把完整的实现方式拆开说,从纯CSS动画到地图API调用,每一步都有代码可以直接用。

地图展开组件的三个核心问题:①展开动画怎么做才丝滑(不用display:none) → max-height + transition;②地图什么时候加载(不让首页变慢) → 点击展开时才new Map(),懒初始化;③手机上看会不会变形 → 宽度100% + touchZoom + CSS媒体查询适配。

一、先搭HTML骨架,一个按钮一个容器

HTML结构只需要两样东西:一个触发按钮,一个装地图的div。地图容器初始是折叠隐藏状态。

<!-- 触发按钮 --><button id="mapToggle" onclick="toggleMap()">查看公司地图位置 ▼</button><!-- 地图容器,初始折叠 --><div id="mapWrapper" class="map-collapsed"><div id="baiduMap" style="width: 100%; height: 400px;"></div></div>

二、核心动画:四行CSS搞定平滑展开

这里有个容易踩的坑:如果直接用 display:nonedisplay:block 切换,浏览器不会做过渡动画,因为display属性不参与transition。正确的做法是用 max-height + overflow:hidden 组合。

/* ===== 核心四行CSS ===== */.map-collapsed {max-height: 0;              /* 折叠状态高度为0 */overflow: hidden;            /* 隐藏超出部分 */transition: max-height 0.5s ease-in-out;  /* 过渡动画 */}.map-expanded {max-height: 600px;            /* 展开后最大高度,要大于地图实际高度 */}

展开高度怎么设?你的地图如果高400px,就把max-height设成500~600px,留点余量给padding和margin。设太大(比如9999px)会导致动画前段看不到内容、后段突然结束,体验不好。

1 - 网站里做一个点击展开的地图,四行CSS加一个百度地图API调用就能搞定,展开动画、懒加载、移动端适配都有现成方案 - UC建站系统

三、JavaScript:点击展开、加载地图、收起还原

JS部分做三件事:切换CSS类名触发动画、地图只初始化一次、收起时隐藏。

let mapInstance = null;        // 地图实例,全局存一份let mapLoaded = false;        // 标记地图是否已加载过let isExpanded = false;       // 当前展开状态function toggleMap() {const wrapper = document.getElementById('mapWrapper');const btn = document.getElementById('mapToggle');if (!isExpanded) {// 展开wrapper.classList.remove('map-collapsed');wrapper.classList.add('map-expanded');btn.innerHTML = '收起地图 ▲';// 地图只加载一次if (!mapLoaded) {initBaiduMap();mapLoaded = true;}isExpanded = true;} else {// 收起wrapper.classList.remove('map-expanded');wrapper.classList.add('map-collapsed');btn.innerHTML = '查看公司地图位置 ▼';isExpanded = false;}}

为什么用mapLoaded标记?如果不加这个标记,每次展开都重新new一个地图,第二次展开就会报错——div里已经有一个地图实例了,再往里塞一个会冲突。所以地图初始化只做一次,后面展开收起只是CSS显隐。

四、加载百度地图API:动态插入script标签

地图的JS SDK文件有几百KB,不要在页面加载时就引入。点击展开时才动态创建script标签加载,这才是真正的按需加载。

function initBaiduMap() {// 动态加载百度地图JSconst script = document.createElement('script');script.src = 'https://api.map.baidu.com/api?v=3.0&ak=你的AK密钥&callback=onBaiduMapLoaded';document.body.appendChild(script);}// SDK加载完成后回调这个函数function onBaiduMapLoaded() {const map = new BMap.Map('baiduMap');// 设定中心点(换成你的地址坐标)const point = new BMap.Point(116.404, 39.915);map.centerAndZoom(point, 15);// 加个标记const marker = new BMap.Marker(point);map.addOverlay(marker);// 启用滚轮缩放map.enableScrollWheelZoom();mapInstance = map;}

AK密钥怎么获取?去百度地图开放平台(lbsyun.baidu.com)注册账号,创建应用选"浏览器端",就能拿到一个AK。免费额度每天有配额,企业站完全够用。

五、高德地图方案:代码结构几乎一样,换API就行

如果你更习惯用高德地图,代码结构完全相同,只是API调用方式换一下。

// 高德地图的初始化函数function initAmapMap() {const script = document.createElement('script');script.src = 'https://webapi.amap.com/maps?v=2.0&key=你的KEY&callback=onAmapLoaded';document.body.appendChild(script);}function onAmapLoaded() {const map = new AMap.Map('baiduMap', {center: [116.404, 39.915],   // 注意:高德是[经度,纬度]zoom: 15,resizeEnable: true       // 容器大小变化时自动适应});const marker = new AMap.Marker({ position: [116.404, 39.915] });map.add(marker);}
对比维度百度地图高德地图
免费额度JS API完全免费,无调用次数限制JS API 2.0免费,需注册开发者
坐标格式BMap.Point(经度, 纬度)[经度, 纬度] 数组格式
密钥要求AK密钥即可key + 安全密钥(2021年后新key)
适合场景偏PC端、企业站、SEO友好偏移动端、交互丰富、加载快

六、移动端适配:三件事让手机上看也正常

移动端屏幕窄,地图展开后如果高度还是400px会占大半个屏幕。需要做三处调整。

/* 1. 移动端地图高度缩小 */@media (max-width: 768px) {#baiduMap {height: 280px !important;}.map-expanded {max-height: 400px;}}/* 2. 按钮全宽,方便手指点击 */#mapToggle {padding: 14px 24px;font-size: 15px;cursor: pointer;background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);color: #fff;border: none;border-radius: 8px;width: 100%;max-width: 400px;display: block;margin: 0 auto;}

3. 初始化时设置手势适配:百度地图初始化时加一行 map.enableScrollWheelZoom() 让PC端滚轮缩放生效,移动端双指缩放默认是开启的。高德地图在构造函数里加 resizeEnable: true 可以让地图在容器大小变化时自动刷新尺寸。

2 - 网站里做一个点击展开的地图,四行CSS加一个百度地图API调用就能搞定,展开动画、懒加载、移动端适配都有现成方案 - UC建站系统

移动端最容易踩的坑:地图展开后只显示左上角一小块,其余部分是灰色。这是因为展开动画结束后地图容器尺寸变了,但地图实例没刷新。解决方案:展开动画的transition结束后,调一下地图的checkResize()方法。

七、加上过渡动画后的resize修复

transition动画0.5秒结束后,地图容器尺寸变了但地图实例不知道,所以需要监听transitionend事件,在动画结束后手动让地图重新计算尺寸。

// 展开后监听动画结束,手动刷新地图尺寸const wrapper = document.getElementById('mapWrapper');wrapper.addEventListener('transitionend', function() {if (isExpanded && mapInstance) {// 百度地图和高德地图都有 checkResize 方法mapInstance.checkResize();}});

八、进阶:地址坐标放HTML的data属性里,不用写死JS

实际建站时地址经常变——公司搬家了、新增分店了——每次改JS太麻烦。把经纬度和地址信息写在HTML的data属性里,JS读取就行。

<!-- HTML中存放地址数据 --><div id="baiduMap"data-lng="116.404"data-lat="39.915"data-zoom="15"data-title="XX科技有限公司"style="width: 100%; height: 400px;"></div>// JS中读取data属性const mapDiv = document.getElementById('baiduMap');const lng = parseFloat(mapDiv.dataset.lng);const lat = parseFloat(mapDiv.dataset.lat);const point = new BMap.Point(lng, lat);

九、常见问题排查

问题现象原因解决办法
地图展开后一片灰色,不显示内容容器尺寸变了,地图没刷新transitionend后调checkResize()
展开动画卡顿、一帧一帧的max-height值设太大(如9999px)max-height设成地图高度+100px即可
收起后按钮点第二次没反应mapLoaded=true了,但地图实例被销毁了不要销毁地图实例,收起只做CSS隐藏
手机上地图太小看不清没做移动端高度适配用@media设移动端高度280-300px
地图定位不准,偏差几百米用了GPS坐标没转换成地图坐标用地图API的坐标转换接口转换
AK密钥提示"浏览器端禁止"创建应用时选错了类型必须选"浏览器端",白名单填*或你的域名

十、多地点切换展开:多个门店怎么搞

如果公司有多个门店,可以做一个标签切换式的展开地图。点"北京店"展开显示北京地图,点"上海店"展开显示上海地图。

// 门店数据配置const stores = [{ name: '北京总部', lng: 116.404, lat: 39.915 },{ name: '上海分公司', lng: 121.473, lat: 31.230 },{ name: 深圳分公司', lng: 114.057, lat: 22.543 }];function switchStore(index) {const store = stores[index];const point = new BMap.Point(store.lng, store.lat);mapInstance.centerAndZoom(point, 15);// 清除旧标记,加新标记...}

多门店的关键点:地图实例只初始化一次,切换门店时只改变centerAndZoom中心点和标记,不重新new地图。这样切换丝滑,也不会有加载延迟。

最后说两句

网站里的地图展开图,技术拆开来看就三件事:CSS的max-height+transition做动画、JS的classList切换做展开收起、地图API的懒加载做性能。代码量加起来不到60行,但每个环节都有几个容易翻车的细节——max-height别设太大、展开后要调checkResize、地图只初始化一次别重复new。这些坑踩一次就知道,但提前知道就能少走弯路。三个地图平台里,百度适合PC企业站、高德移动端体验更好、腾讯地图如果你用的是腾讯生态可以无缝接入,选哪个取决于你的网站主力用户在哪里。代码本身不复杂,照着上面的示例改一下AK和坐标就能上线。

3 - 网站里做一个点击展开的地图,四行CSS加一个百度地图API调用就能搞定,展开动画、懒加载、移动端适配都有现成方案 - UC建站系统

十一、腾讯地图方案

如果网站用的是腾讯系域名或者微信小程序里用,腾讯地图JavaScript API GL也可以。代码结构跟前两个差不多,注意腾讯地图坐标格式是(纬度,经度),和百度高德反过来。

十二、完整HTML页面代码(可直接用)

把所有代码拼在一起,就是一个完整可运行的页面。替换掉AK和坐标就能直接上线。以下是核心代码结构:

<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><style>.map-collapsed { max-height: 0; overflow: hidden; transition: max-height 0.5s ease-in-out; }.map-expanded { max-height: 600px; }#mapToggle { padding: 14px 24px; font-size: 15px; cursor: pointer; background: linear-gradient(135deg, #667eea, #764ba2); color: #fff; border: none; border-radius: 8px; }@media (max-width: 768px) { #baiduMap { height: 280px !important; } .map-expanded { max-height: 400px; } }</style></head><body><button id="mapToggle" onclick="toggleMap()">查看公司地图位置 ▼</button><div id="mapWrapper" class="map-collapsed"><div id="baiduMap" data-lng="116.404" data-lat="39.915" style="width:100%;height:400px"></div></div><script>let mapInstance = null, mapLoaded = false, isExpanded = false;function toggleMap() {const w = document.getElementById('mapWrapper');const b = document.getElementById('mapToggle');if (!isExpanded) {w.classList.replace('map-collapsed', 'map-expanded');b.innerHTML = '收起地图 ▲';if (!mapLoaded) { initMap(); mapLoaded = true; }isExpanded = true;} else {w.classList.replace('map-expanded', 'map-collapsed');b.innerHTML = '查看公司地图位置 ▼';isExpanded = false;}}function initMap() {const s = document.createElement('script');s.src = 'https://api.map.baidu.com/api?v=3.0&ak=你的AK密钥&callback=onMapLoaded';document.body.appendChild(s);}function onMapLoaded() {const div = document.getElementById('baiduMap');const lng = parseFloat(div.dataset.lng);const lat = parseFloat(div.dataset.lat);const map = new BMap.Map('baiduMap');map.centerAndZoom(new BMap.Point(lng, lat), 15);map.addOverlay(new BMap.Marker(new BMap.Point(lng, lat)));map.enableScrollWheelZoom();mapInstance = map;}document.getElementById('mapWrapper').addEventListener('transitionend', function() {if (isExpanded && mapInstance) mapInstance.checkResize();});</script></body></html>

把"你的AK密钥"替换成百度地图开放平台申请的AK,把data-lng和data-lat换成你自己公司地址的经纬度,其他代码一个字都不用改。

十三、不想写代码的替代方案

如果只是想在网站里加个地图,不想写代码,也有几个现成的路子:

方案做法优缺点
百度地图生成器百度地图网页版搜地址 → 分享 → 嵌入代码 → 复制iframe零代码,但没法做展开收起动画
高德地图组件高德开放平台 → JS API示例 → 复制代码改坐标复制即用,展开收起还是得自己写CSS
WordPress插件WP Google Maps / MapPress 等插件拖拽式操作,但展开折叠功能未必有
第三方地图组件如jvectormap、Leaflet + OpenStreetMap完全免费开源,不需要任何API密钥

Leaflet的额外好处:如果你对地图精度要求不高(比如只是展示大概位置),Leaflet + OpenStreetMap完全免费、不需要申请任何密钥、国内也能正常加载。代码比百度高德更简单,而且移动端适配天然就很好。

最后说两句

网站里的地图展开图,技术拆开来看就三件事:CSS的max-height+transition做动画、JS的classList切换做展开收起、地图API的懒加载做性能。代码量加起来不到60行,但每个环节都有几个容易翻车的细节——max-height别设太大、展开后要调checkResize、地图只初始化一次别重复new。这些坑踩一次就知道,但提前知道就能少走弯路。三个地图平台里,百度适合PC企业站、高德移动端体验更好、腾讯地图如果你用的是腾讯生态可以无缝接入,选哪个取决于你的网站主力用户在哪里。代码本身不复杂,照着上面的示例改一下AK和坐标就能上线。

十四、怎么获取公司地址的经纬度坐标

写代码之前先得知道公司地址的经纬度。三个地图平台都有自己的坐标拾取工具,在网页上点一下就能拿到坐标。注意:不同地图平台使用的坐标系不一样——百度用的是BD09坐标系,高德和腾讯用的是GCJ02(火星坐标系),GPS原始坐标是WGS84。直接用GPS坐标放到百度地图上会偏几百米。

地图平台坐标系坐标拾取工具地址
百度地图BD09api.map.baidu.com/lbsapi/getpoint/
高德地图GCJ02lbs.amap.com/tools/picker
腾讯地图GCJ02lbs.qq.com/tool/getpoint/

省事的做法:直接用你要用的那个地图平台的坐标拾取工具去取坐标,保证坐标系对得上。不要用手机GPS定位的坐标直接填进去。

相关推荐
在线客服
👇找客服拿折扣
QQ咨询&售后
在线时间
11:00 ~ 5:30
QQ:3155555535
👇联系QQ
👇联系WX
首页 程序 帮助 登录