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

React实现悬停文本切换对应图片透明度的方法咨询

实现方案

核心思路是用useState跟踪当前悬停的单词标识,再通过条件样式控制对应图片的透明度。具体步骤如下:

  • 定义状态变量,存储当前激活的单词ID(初始值设为null)
  • 给每个包裹单词的span绑定onMouseEnter和onMouseLeave事件,更新状态
  • 给每张图片添加条件样式,根据当前激活的ID判断是否切换透明度

完整代码示例

import { useState } from 'react';

function ImageGridPage() {
  // 存储当前悬停的单词ID,初始为null
  const [activeWordId, setActiveWordId] = useState(null);

  // 处理鼠标进入span事件
  const handleWordHover = (wordId) => {
    setActiveWordId(wordId);
  };

  // 处理鼠标离开span事件
  const handleWordLeave = () => {
    setActiveWordId(null);
  };

  return (
    <div style={{ 
      display: 'grid',
      gridTemplateAreas: `
        "img1 img2 img3"
        "img4 text img5"
        "img6 img7 img8"
      `,
      gap: '1rem',
      padding: '2rem'
    }}>
      {/* 中央文本区域 */}
      <div style={{ gridArea: 'text', fontSize: '1.5rem' }}>
        我正在学习React,制作一个包含<span 
          onMouseEnter={() => handleWordHover('mountain')}
          onMouseLeave={handleWordLeave}
          style={{ cursor: 'pointer', textDecoration: 'underline' }}
        >山脉</span>、<span 
          onMouseEnter={() => handleWordHover('lake')}
          onMouseLeave={handleWordLeave}
          style={{ cursor: 'pointer', textDecoration: 'underline' }}
        >湖泊</span>和<span 
          onMouseEnter={() => handleWordHover('forest')}
          onMouseLeave={handleWordLeave}
          style={{ cursor: 'pointer', textDecoration: 'underline' }}
        >森林</span>的练习网站。
      </div>

      {/* 周边图片 */}
      <img 
        src="/path/to/mountain.jpg" 
        alt="山脉"
        style={{ 
          gridArea: 'img1',
          opacity: activeWordId === 'mountain' ? 1 : 0,
          transition: 'opacity 0.3s ease',
          width: '100%',
          height: 'auto'
        }}
      />
      <img 
        src="/path/to/lake.jpg" 
        alt="湖泊"
        style={{ 
          gridArea: 'img2',
          opacity: activeWordId === 'lake' ? 1 : 0,
          transition: 'opacity 0.3s ease',
          width: '100%',
          height: 'auto'
        }}
      />
      <img 
        src="/path/to/forest.jpg" 
        alt="森林"
        style={{ 
          gridArea: 'img3',
          opacity: activeWordId === 'forest' ? 1 : 0,
          transition: 'opacity 0.3s ease',
          width: '100%',
          height: 'auto'
        }}
      />
      {/* 其他图片同理,对应各自的gridArea和wordId */}
    </div>
  );
}

export default ImageGridPage;

额外优化建议

  • 如果单词和图片数量较多,可以把数据抽成数组,用map循环渲染,避免重复代码:

    const wordImagePairs = [
      { id: 'mountain', text: '山脉', imgSrc: '/path/to/mountain.jpg', gridArea: 'img1' },
      { id: 'lake', text: '湖泊', imgSrc: '/path/to/lake.jpg', gridArea: 'img2' },
      // 更多数据...
    ];
    
    // 渲染span
    {wordImagePairs.map(pair => (
      <span
        key={pair.id}
        onMouseEnter={() => handleWordHover(pair.id)}
        onMouseLeave={handleWordLeave}
        style={{ cursor: 'pointer', textDecoration: 'underline' }}
      >
        {pair.text}
      </span>
    ))}
    
    // 渲染图片
    {wordImagePairs.map(pair => (
      <img
        key={pair.id}
        src={pair.imgSrc}
        alt={pair.text}
        style={{
          gridArea: pair.gridArea,
          opacity: activeWordId === pair.id ? 1 : 0,
          transition: 'opacity 0.3s ease',
          width: '100%',
          height: 'auto'
        }}
      />
    ))}
    
  • 可以把样式抽到CSS模块或者styled-components里,让JSX更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 15:05:30