You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Ajax请求实现地图局部定时刷新(避免整页重载)

解决Ajax定时刷新地图而非整页的问题

看起来你已经找对了方向,但代码里几个小问题导致load()没生效,而且定时刷新的逻辑也没真正触发地图重绘。我帮你梳理下问题点,再给出修正后的代码:

现有代码的核心问题

  • setInterval的调用方式错误:用字符串"my_function();"会导致函数在全局作用域执行,而你的my_function定义在Ajax回调内部,全局访问不到
  • load()只更新了时间,没刷新司机数据:你当前的load()只是重新加载页面里的#time元素,但并没有重新获取最新的司机位置数据,也没重绘地图标记
  • 地图重绘逻辑只执行一次:你把地图初始化和标记绘制的代码放在了第一次Ajax成功的回调里,后续定时任务没有执行这些逻辑
  • 变量作用域问题:locationData、locationData2、gmarkers这些变量如果是局部变量,定时任务里会访问不到

修正后的完整实现方案

1. 保持HTML结构不变

<div class="row">
  <div class="col-md-12">
    <div id="map" style="height: 550px;">
      <div id="time">
        <?php echo date('H:i:s');?>
      </div>
    </div>
  </div>
</div>

2. 重构JavaScript逻辑

// 全局变量,确保定时任务能访问到
let map;
let gmarkers = [];
let infowindow;
let currentStatus = '';

// 初始化地图(只执行一次)
function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: {lat: 31.5204, lng: 74.3587},
    mapTypeId: 'roadmap'
  });
  infowindow = new google.maps.InfoWindow({});
}

// 获取司机数据并重绘地图
function refreshDrivers() {
  if (!currentStatus) return; // 如果没有选中状态,不执行

  $.ajax({
    url: '{{ URL::to('/get_drivers/')}}' + '/' + currentStatus,
    type: 'get',
    dataType: 'json',
    success: function (response) {
      // 先清除所有旧标记
      if (gmarkers.length > 0) {
        gmarkers.forEach(marker => marker.setMap(null));
        gmarkers = [];
      }

      // 更新时间显示
      $('#time').text(new Date().toLocaleTimeString());

      // 假设response返回的是司机位置数据数组,对应你原来的locationData2
      const locationData2 = response;
      for (let i = 0; i < locationData2.length; i++) {
        const driver = locationData2[i];
        // 根据状态设置图标(这里用你原来的逻辑,状态8用灰色车)
        const icon = currentStatus == 8 ? '{{asset('images/grey-car.png')}}' : '{{asset('images/red-car.png')}}';
        
        const marker = new google.maps.Marker({
          position: new google.maps.LatLng(driver.driver_lat, driver.driver_long),
          map: map,
          optimized: false,
          icon: icon
        });

        // 鼠标悬停事件
        google.maps.event.addListener(marker, 'mouseover', (function(marker, driver) {
          return function() {
            infowindow.setContent(`<h6><b>${driver.first_name}</b></h6>`);
            infowindow.open(map, marker);
          }
        })(marker, driver));

        // 点击地图关闭信息窗
        google.maps.event.addListener(map, 'click', function() {
          infowindow.close();
        });

        gmarkers.push(marker);
      }

      // 添加markerLayer用于CSS(如果需要的话)
      const myoverlay = new google.maps.OverlayView();
      myoverlay.draw = function () {
        this.getPanes().markerLayer.id = 'markerLayer';
      };
      myoverlay.setMap(map);
    }
  });
}

// 页面加载完成后初始化地图
$(document).ready(function() {
  initMap();

  // 状态切换事件
  $('#status').change(function () {
    currentStatus = $(this).val();
    
    // 先执行一次刷新
    refreshDrivers();
    
    // 清除之前的定时任务(避免重复创建)
    if (window.refreshInterval) {
      clearInterval(window.refreshInterval);
    }
    
    // 只有选中"可用"状态(假设状态值是你需要的,比如8?根据你的业务调整)时启动定时刷新
    if (currentStatus === '8') { // 这里替换成你实际的"可用"状态值
      window.refreshInterval = setInterval(refreshDrivers, 10000); // 每10秒执行一次
    }
  });
});

关键改动说明

  • 地图初始化分离:initMap()只在页面加载时执行一次,避免重复创建地图实例
  • 封装刷新逻辑:把获取数据、清除旧标记、绘制新标记的逻辑放在refreshDrivers()里,方便调用
  • 修正定时任务:用函数引用refreshDrivers代替字符串调用,避免作用域问题;同时切换状态时先清除旧的定时任务,防止多个定时器同时运行
  • 状态存储:用currentStatus全局变量存储当前选中的状态,定时任务可以直接使用
  • 直接更新时间:不需要用load()加载整个页面的#time,直接用text()更新当前时间更高效
  • 简化事件绑定:优化了信息窗的事件绑定逻辑,避免闭包问题

这样修改后,当你切换到"可用"状态时,会立即刷新一次地图,之后每10秒自动获取最新的司机数据并重绘地图,不会触发整页重载。

内容的提问来源于stack exchange,提问作者user10748394

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:10:43