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

多水平滚动区域图片懒加载异常:视口底/右侧触发逻辑失效

需求目标

实现图片懒加载:当图片靠近视口底部或右侧20%范围时加载,让用户滚动时感知图片“始终存在”——查看当前图片时,右侧及下方图片在屏幕外预加载。

问题现象

  • 方案1:视口底部触发逻辑正常,但右侧触发失效——图片刚接触视口右侧即加载,未按设置的20%提前触发;
  • 方案2:视口右侧触发逻辑正常,但底部触发失效——页面加载时所有图片已完成加载。

代码实现

JavaScript

import React, {useEffect} from 'react';
import './test.css';

// dummy test data
const coffeeShops = [
    {
        title: 'Coffee Shop 1',
        photos: [
            'picture 1 of Coffee Shop 1',
            'picture 2 of Coffee Shop 1',
            'picture 3 of Coffee Shop 1',
            'picture 4 of Coffee Shop 1'
        ]
    },
    {
        title: 'Coffee Shop 2',
        photos: [
            'picture 1 of Coffee Shop 2',
            'picture 2 of Coffee Shop 2',
            'picture 3 of Coffee Shop 2',
            'picture 4 of Coffee Shop 2'
        ]
    },
    {
        title: 'Coffee Shop 3',
        photos: [
            'picture 1 of Coffee Shop 3',
            'picture 2 of Coffee Shop 3',
            'picture 3 of Coffee Shop 3',
            'picture 4 of Coffee Shop 3'
        ]
    },
    {
        title: 'Coffee Shop 4',
        photos: [
            'picture 1 of Coffee Shop 4',
            'picture 2 of Coffee Shop 4',
            'picture 3 of Coffee Shop 4',
            'picture 4 of Coffee Shop 4'
        ]
    }
]

export const Test = () => {
    useEffect(() => {
        const svgs = document.querySelectorAll('.mySvg');
        // 设置图片在靠近视口右侧或底部20%时加载
        const rootMargin = '0% 20% 20% 0%';

        // 方案1:
        // 视口底部触发正常
        // 视口右侧触发失效:图片刚接触视口右侧即加载(未按20%设置触发)
        createObserver(svgs, rootMargin, null);

        // 方案2:(效果相反)
        // 视口底部触发失效:页面加载时所有图片已加载
        // 视口右侧触发正常
        // const scrollContainers = document.querySelectorAll('.scroll-container');
        // for (const scrollContainer of scrollContainers) {
        //     createObserver(svgs, rootMargin, scrollContainer);
        // }
    }, [])

    return (
        <>
            <div style={{marginBottom: '50px'}}>Awesome Coffee Shops:</div>

            {coffeeShops.map(shop => {
                return (
                    <>
                        <div className='scroll-container'>
                            {shop.photos.map(photo => {
                                return (
                                    <svg width='4032' height='3024' className='mySvg'>
                                        <rect x="0" y="0" width='4032' height="3024" stroke='black' fill='white' />
                                    </svg>

                                );
                            })}
                        </div>
                        <div>{shop.title}</div>
                    </>
                );
            })}
        </>
    );
};


export const createObserver = (svgs, rootMargin, root) => {
    const config = {
        root,
        rootMargin,
        threshold: 0
    };

    const lazyImageObserver = new IntersectionObserver(function (entries, observer) {
        entries.forEach(function (entry) {
            if (entry.isIntersecting) {
                const svg = entry.target;
                setTimeout(() => svg.childNodes[0].setAttribute('fill', 'purple'), 500); // 模拟图片下载延迟
                observer.unobserve(svg);
            }
        });
    }, config);

    svgs.forEach(function (svg) {
        lazyImageObserver.observe(svg);
    });
};

CSS

.scroll-container {
    overflow: auto;
    white-space: nowrap;
}

svg {
  width: 90%;
  height: 90%;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:55:15