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

React Jvectormap:实现点击国家而非悬停时显示提示框

在React Jvectormap中实现点击触发提示框(非悬停)

React原生实现方案

核心思路是禁用默认悬停提示,通过监听地图的原生点击事件,用React状态管理提示框的显示状态、内容和位置,完全不需要依赖jQuery。

步骤1:安装依赖

确保已安装react-jvectormap和对应地图包(以世界地图为例):

npm install react-jvectormap jvectormap-world-mill

步骤2:完整组件示例

import React, { useState, useEffect } from 'react';
import { VectorMap } from 'react-jvectormap';
import 'jvectormap-world-mill';

const ClickTriggerMap = () => {
  // 维护提示框的核心状态
  const [tooltipState, setTooltipState] = useState({
    isVisible: false,
    content: '',
    position: { top: 0, left: 0 }
  });

  // 处理地图区域点击事件
  const handleRegionClick = (event, regionCode, regionData) => {
    // 获取鼠标点击位置,调整提示框偏移避免出界
    const { clientX, clientY } = event;
    setTooltipState({
      isVisible: true,
      content: `${regionData.name} (${regionCode})`,
      position: { top: clientY + 15, left: clientX + 15 }
    });
  };

  // 点击空白区域关闭提示框
  const handleOutsideClick = (e) => {
    const isTooltipOrMap = e.target.closest('.custom-tooltip') || e.target.closest('.jvectormap-container');
    if (!isTooltipOrMap) {
      setTooltipState(prev => ({ ...prev, isVisible: false }));
    }
  };

  // 绑定全局点击监听,组件卸载时清理
  useEffect(() => {
    window.addEventListener('click', handleOutsideClick);
    return () => window.removeEventListener('click', handleOutsideClick);
  }, []);

  return (
    <div style={{ position: 'relative', width: '100%', height: 550 }}>
      {/* 地图组件 */}
      <VectorMap
        map="world_mill"
        backgroundColor="#f5f7fa"
        onRegionClick={handleRegionClick}
        containerStyle={{ width: '100%', height: '100%' }}
        // 关闭默认悬停提示
        mapOptions={{
          tooltip: { enabled: false }
        }}
        regionStyle={{
          initial: { fill: '#4a90e2' },
          hover: { fill: '#357abd' },
          selected: { fill: '#e53e3e' }
        }}
      />

      {/* 自定义点击触发提示框 */}
      {tooltipState.isVisible && (
        <div
          className="custom-tooltip"
          style={{
            position: 'absolute',
            top: tooltipState.position.top,
            left: tooltipState.position.left,
            backgroundColor: '#2d3748',
            color: '#fff',
            padding: '8px 14px',
            borderRadius: '6px',
            fontSize: '14px',
            zIndex: 9999,
            pointerEvents: 'none'
          }}
        >
          {tooltipState.content}
        </div>
      )}
    </div>
  );
};

export default ClickTriggerMap;

代码说明

  • 状态管理:用useState统一控制提示框的显示/隐藏、内容和位置,点击区域时实时更新状态。
  • 原生事件回调:onRegionClick是react-jvectormap提供的原生回调,直接获取点击区域的名称、代码和鼠标位置。
  • 关闭逻辑:监听全局点击事件,点击地图和提示框外的区域时自动关闭提示。
  • 禁用默认提示:通过mapOptions.tooltip.enabled: false完全关闭原生悬停提示。

适配jQuery方案的思路(不推荐)

如果一定要沿用基于jQuery的现有方案,可以在React的useEffect中等待地图挂载完成后绑定事件,但这种方式容易导致DOM与React状态不同步,仅作参考:

import React, { useEffect } from 'react';
import { VectorMap } from 'react-jvectormap';
import 'jvectormap-world-mill';
import $ from 'jquery';

const JQueryAdaptedMap = () => {
  useEffect(() => {
    // 地图容器默认ID为react-jvectormap-container
    const mapContainer = $('#react-jvectormap-container');
    if (mapContainer.length) {
      const mapInstance = mapContainer.vectorMap('get', 'mapObject');
      
      // 绑定区域点击事件
      mapInstance.on('regionClick', (event, code, region) => {
        // 生成jQuery提示框
        $('<div class="jq-tooltip"/>')
          .text(`${region.name} (${code})`)
          .css({
            position: 'absolute',
            top: event.clientY + 15,
            left: event.clientX + 15,
            backgroundColor: '#2d3748',
            color: '#fff',
            padding: '8px 14px',
            borderRadius: '6px',
            zIndex: 9999
          })
          .appendTo('body');
        
        // 点击其他区域移除提示框
        $('body').one('click', () => $('.jq-tooltip').remove());
      });

      // 关闭默认悬停提示
      mapInstance.setTooltipEnabled(false);
    }

    // 组件卸载时清理事件和DOM元素
    return () => {
      const mapContainer = $('#react-jvectormap-container');
      if (mapContainer.length) {
        const mapInstance = mapContainer.vectorMap('get', 'mapObject');
        mapInstance.off('regionClick');
        $('.jq-tooltip').remove();
      }
    };
  }, []);

  return (
    <div style={{ width: '100%', height: 550 }}>
      <VectorMap
        map="world_mill"
        backgroundColor="#f5f7fa"
        containerStyle={{ width: '100%', height: '100%' }}
      />
    </div>
  );
};

export default JQueryAdaptedMap;

注意事项

  • 该方案需要额外引入jQuery,违背React的原生状态管理逻辑,容易出现内存泄漏或DOM与状态不一致的问题,不推荐在React项目中使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 06:18:27