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
相关产品推荐
相关产品推荐

