Next.js SSR页面禁用JavaScript后Swiper滑块显示异常求助
解决禁用JavaScript后Swiper滑块显示异常的问题
正常情况下Swiper滑块功能完全正常,但当浏览器禁用JavaScript时,滑块的单个项目会占满整个宽度和高度,布局完全错乱。
问题相关代码
品牌滑块组件代码:
import React from "react"; import {BannerType} from "@/contracts/bannerContract"; import {Swiper, SwiperSlide} from "swiper/react"; import {Autoplay, Navigation} from "swiper"; import Link from "next/link"; import Image from "next/image"; const HomeBrands: React.FC<{ items: BannerType[] }> = ({items}) => { return ( <Swiper initialSlide={2} modules={[Autoplay, Navigation]} loop={true} slidesPerView={"auto"} autoplay={{disableOnInteraction: false, pauseOnMouseEnter: true, delay: 5000}} centeredSlides={true} spaceBetween={5} breakpoints={{ 320: { slidesPerView: 2, spaceBetween: 5, }, 640: { slidesPerView: 4, spaceBetween: 20, }, 768: { slidesPerView: 5, spaceBetween: 25, }, 1024: { slidesPerView: 6, spaceBetween: 25, }, 1280: { slidesPerView: 7, } }} > {items.map((brand, i) => <SwiperSlide key={i}> <Link href={brand.url || '/'} aria-label={brand.title} passHref> <a target="_blank"> <Image quality={100} src={brand.picture} alt={brand.title} layout={'responsive'} width={40} height={40}/> </a> </Link> </SwiperSlide> )} </Swiper> ) } export default HomeBrands
页面中加载组件的代码:
const HomeBrands = dynamic(() => import("@/components/HomeBrands"), { ssr: true, loading: () => <ImageLoading/> }) // ... {brand.length > 0 && <section className={'container mt-8 mx-auto'}> <HomeBrands items={brand}/> </section>}
解决方案
Swiper的布局完全依赖JavaScript动态生成样式,禁用JS后这些样式无法生效,导致原生HTML结构失去约束。可以通过以下步骤修复:
添加无JS fallback CSS
利用Swiper自动添加的swiper-container-no-js类,给无JS状态下的滑块写基础布局样式:/* 无JS时的容器布局 */ .swiper-container-no-js .swiper { display: flex; flex-wrap: wrap; gap: 5px; justify-content: center; padding: 1rem 0; } /* 固定滑块尺寸,和Image组件匹配 */ .swiper-container-no-js .swiper-slide { flex: 0 0 auto; width: 40px; height: 40px; } /* 适配断点,和Swiper的breakpoints对应 */ @media (min-width: 640px) { .swiper-container-no-js .swiper { gap: 20px; } } @media (min-width: 768px) { .swiper-container-no-js .swiper { gap: 25px; } } @media (min-width: 1024px) { .swiper-container-no-js .swiper { gap: 25px; } }调整Image组件的布局属性
将layout={'responsive'}改为layout={'fixed'},并添加objectFit确保图片不会拉伸:<Image quality={100} src={brand.picture} alt={brand.title} layout={'fixed'} width={40} height={40} objectFit="contain" />确保CSS提前加载
把上述fallback样式放在全局CSS文件里,或者组件的CSS模块中,确保SSR渲染的页面一开始就有正确的样式约束,避免布局闪烁。
内容的提问来源于stack exchange,提问作者Ramin eghbalian
相关产品推荐
相关产品推荐

