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

React项目中CSS Hover悬停效果失效问题求助(基于Star Wars API)

修复React星舰卡片悬停效果失效问题

问题根源及修复步骤:

1. CSS选择器与定位错误

  • 原CSS中.ship-list .container:hover .overlay的多余空格导致选择器匹配失效,同时.ship-list未设置position: relative,使得绝对定位的.overlay脱离卡片范围,相对于页面全局定位。
  • 修复:给.ship-list添加position: relative,修正选择器格式,确保hover事件正确触发。

2. React状态更新方式错误

  • 原代码中直接修改this.state.data,不符合React状态更新规范,可能导致数据更新不及时或组件渲染异常。
  • 修复:使用setState方法正确合并新获取的星舰数据。

修复后的完整代码

JS部分(Films.js)

import React, { Component } from "react";
import "../styles/Films.css";

class Films extends Component {
  state = {
    data: [],
    movieDetailsOpen: false,
    movieSelected: "",
    index: 0,
    page: 1,
    isLoading: false,
  };

  posterImages = [
    "CR90-Corvette.png",
    "stardestroyer.png",
    "Sentinel-class-landing-craft.jpg",
    "Death-Star.png",
    "Millenium_Falcon.jpg",
    "Y-wing.png",
    "x-wing.png",
    "TIE-Advanced-x1.png",
    "executor.png",
    "rebel-transport.png",
    "https://picsum.photos/id/237/200/300",
    "https://picsum.photos/id/247/200/300",
    "https://picsum.photos/id/257/200/300",
    "https://picsum.photos/id/267/200/300",
    "https://picsum.photos/id/277/200/300",
    "https://picsum.photos/id/287/200/300",
    "https://picsum.photos/id/297/200/300",
    "https://picsum.photos/id/137/200/300",
    "https://picsum.photos/id/247/200/300",
    "https://picsum.photos/id/357/200/300",
    "https://picsum.photos/id/467/200/300",
    "https://picsum.photos/id/577/200/300",
    "https://picsum.photos/id/687/200/300",
    "https://picsum.photos/id/797/200/300",
  ];

  async getFilms() {
    const { page, data } = this.state;

    await fetch(`https://swapi.dev/api/starships/?page=${page}`)
      .then(async (res) => {
        let response = await res.json();
        const newShips = response.results.map((result, index) => ({
          name: result.name,
          image: this.posterImages[index + 10 * (page - 1)],
          model: result.model,
          hyperdrive_rating: result.hyperdrive_rating
        }));
        this.setState({
          data: [...data, ...newShips]
        });
      })
      .catch((err) => {
        console.log(err);
      });
  }

  closeDetails() {
    document.getElementById("movie-details-wrapper").style.animation = "close .5s ease forwards";
    document.getElementById("bottom").style.animation = "open .5s ease forwards";
    document.getElementById("top").style.animation = "open .5s ease forwards";
    this.props.closeDetails();
  }

  componentWillMount() {
    this.getFilms();
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevState.page !== this.state.page) {
      this.getFilms();
    }
  }

  loadMore = () => {
    this.setState((prevState) => ({
      page: prevState.page + 1,
      index: prevState.index + 1,
    }));
  };

  render() {
    const { isLoading, data } = this.state;

    return (
      <div className="starships-wrapper">
        <div className="top" id="top">
          <img src="./logo.png" alt="logo" />
        </div>
        <div className="bottom" id="bottom">
          <ul>
            {data.map((res, index) => (
              <li
                key={index}
                className="ship-list"
                style={{
                  backgroundImage: `url(${res.image})`,
                }}
              >
                <div className="name">{res.name}</div>
                <div className="container">
                  <div className="overlay">
                    <p className="text">型号:{res.model}</p>
                    <p className="text">超空间等级:{res.hyperdrive_rating}</p>
                  </div>
                </div>
              </li>
            ))}
          </ul>
        </div>
        <div className="load-more">
          <button onClick={this.loadMore} className="btn-grad" variant="dark">
            {isLoading ? "加载中..." : "加载更多"}
          </button>
        </div>
      </div>
    );
  }
}

export default Films;

CSS部分(Films.css)

.starships-wrapper {
    display: grid;
    grid-template-columns: 1fr;
}

.top {
    height: 400px;
    background-size: contain;
    background: rgb(0, 0, 0) url("https://starwars.fandom.com/tr/wiki/Star_Wars?file=Star-wars-logo-new-tall.jpg") no-repeat top;
}

.top > img {
    width: 400px;
    margin: 10px auto;
    display: block;
}

.bottom {
    background: #fff;
}

.bottom > ul {
    list-style: none;
    width: fit-content;
    margin: 0 auto auto;
    padding: 10px;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 15px;
    text-align: center;
    position: relative;
    top: 6rem;
    color:#ffffff;
    bottom: 0;
}

.bottom > ul:hover {
    cursor: pointer;
}

.ship-list {
    height: 510px;
    width: 400px;
    border-radius: 15px;
    box-shadow: 0 10px 15px -9px black;
    background-repeat: no-repeat;
    background-size: contain;
    background-position: bottom;
    position: relative;
    overflow: hidden;
}

.name {
    background-color: #070707;
    color: #ffffff;
    width: 100%;
    font-size: 48px;
    font-weight: 900;
    border-radius: 15px 15px 0 0;
    padding: 10px 0;
}

button {
    background-color: #000000;
    border: none;
    color: rgb(255, 251, 0);
    padding: 16px 32px;
    text-align: left;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
    margin: 4px 2px;
    transition-duration: 0.4s;
    cursor: pointer;
}

@media only Screen and (max-width: 900px) {
    .bottom > ul {
        grid-template-columns: 1fr;
        width: 95%;
    }

    .ship-list {
        height: 350px;
        background-size: cover;
    }
}

.ship-list .container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

.ship-list .overlay {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    height: 100%;
    width: 100%;
    opacity: 0;
    transition: .5s ease;
    background-color: rgba(0, 140, 186, 0.8);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.ship-list .container:hover .overlay {
    opacity: 1;
}

.ship-list .text {
    color: white;
    font-size: 20px;
    margin: 10px 0;
    text-align: center;
    padding: 0 20px;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:55:18