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

屏幕宽度变化时切换对应图片数组的React实现方案

React 实现横竖屏自动切换对应图片数组渲染方案

实现思路

核心逻辑是实时判断当前屏幕方向,横屏状态下渲染landscape_images数组内容,竖屏状态下渲染portrait_images数组内容,监听事件做防抖优化,同时做好组件卸载时的内存清理,避免性能问题。

第一步:定义基础图片数组

先按照需求定义两个场景对应的图片数组,元素存储图片资源路径和必要的描述信息:

// 横屏场景适配的宽分辨率图片数组
const landscape_images = [
  { id: 1, src: '/imgs/landscape/home-banner.jpg', alt: '首页横屏主banner' },
  { id: 2, src: '/imgs/landscape/activity-banner.jpg', alt: '活动区横屏banner' },
  { id: 3, src: '/imgs/landscape/recommend-banner.jpg', alt: '推荐区横屏banner' }
]

// 竖屏场景适配的长尺寸图片数组
const portrait_images = [
  { id: 1, src: '/imgs/portrait/home-banner.jpg', alt: '首页竖屏主banner' },
  { id: 2, src: '/imgs/portrait/activity-banner.jpg', alt: '活动区竖屏banner' },
  { id: 3, src: '/imgs/portrait/recommend-banner.jpg', alt: '推荐区竖屏banner' }
]

第二步:React组件核心实现

用函数组件+Hooks实现,优先用性能更好的matchMedia监听屏幕方向变化,同时加resize事件做兼容兜底,加入防抖避免频繁触发重渲染:

import { useState, useEffect } from 'react'
import './AdaptiveImage.css'

export default function AdaptiveImageRender() {
  // 初始化时直接判断当前屏幕方向,避免首屏闪切
  const [isLandscape, setIsLandscape] = useState(() => window.innerWidth > window.innerHeight)

  useEffect(() => {
    let debounceTimer = null
    // 方向变化处理逻辑,加200ms防抖
    const updateOrientation = () => {
      clearTimeout(debounceTimer)
      debounceTimer = setTimeout(() => {
        setIsLandscape(window.innerWidth > window.innerHeight)
      }, 200)
    }

    // 优先使用matchMedia监听屏幕方向,性能优于resize监听
    const orientationMatcher = window.matchMedia('(orientation: landscape)')
    // 兼容新旧浏览器的事件绑定写法
    if (orientationMatcher.addEventListener) {
      orientationMatcher.addEventListener('change', updateOrientation)
    } else {
      orientationMatcher.addListener(updateOrientation)
    }

    // 兜底监听resize事件,覆盖PC端拖拽调整窗口、异形屏判断不准的场景
    window.addEventListener('resize', updateOrientation)

    // 组件卸载时清除所有监听和定时器,防止内存泄漏
    return () => {
      clearTimeout(debounceTimer)
      if (orientationMatcher.removeEventListener) {
        orientationMatcher.removeEventListener('change', updateOrientation)
      } else {
        orientationMatcher.removeListener(updateOrientation)
      }
      window.removeEventListener('resize', updateOrientation)
    }
  }, [])

  // 根据当前方向取对应要渲染的图片数组
  const renderImageList = isLandscape ? landscape_images : portrait_images

  return (
    <div className="img-container">
      {renderImageList.map(imgItem => (
        <img
          key={imgItem.id}
          src={imgItem.src}
          alt={imgItem.alt}
          className="adaptive-img"
        />
      ))}
    </div>
  )
}

第三步:配套CSS样式

写基础样式保证图片自适应容器,不会出现布局溢出:

/* 重置body默认边距,保证全屏适配 */
body {
  margin: 0;
  padding: 0;
}

.img-container {
  width: 100%;
}

.adaptive-img {
  width: 100%;
  display: block;
  /* 根据业务需求调整填充模式,cover为铺满容器裁剪多余部分,contain为完整显示图片 */
  object-fit: cover;
}

可选优化点

  • 如果需要固定断点判断(比如宽度大于768px就算横屏场景,适配平板设备),可以把判断逻辑里的window.innerWidth > window.innerHeight替换为window.innerWidth >= 768即可
  • 如果项目里用了React Router等路由库,注意这个自适应组件要放在路由外层,保证路由切换时方向监听不会重复绑定
  • 图片资源可以加懒加载属性,给<img>标签加上loading="lazy",减少首屏加载压力

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 09:57:29