import { siteConfig } from '@/lib/config'
import Head from 'next/head'
import { useEffect, useRef, useState } from 'react'
/**
* 图片懒加载
* @param {*} param0
* @returns
*/
export default function LazyImage({
priority,
id,
src,
alt,
placeholderSrc,
className,
width,
height,
title,
onLoad,
onClick,
style
}) {
const maxWidth = siteConfig('IMAGE_COMPRESS_WIDTH')
const defaultPlaceholderSrc = siteConfig('IMG_LAZY_LOAD_PLACEHOLDER')
const imageRef = useRef(null)
const [currentSrc, setCurrentSrc] = useState(
placeholderSrc || defaultPlaceholderSrc
)
/**
* 占位图加载成功
*/
const handleThumbnailLoaded = () => {
if (typeof onLoad === 'function') {
// onLoad() // 触发传递的onLoad回调函数
}
}
// 原图加载完成
const handleImageLoaded = img => {
if (typeof onLoad === 'function') {
onLoad() // 触发传递的onLoad回调函数
}
}
/**
* 图片加载失败回调
*/
const handleImageError = () => {
if (imageRef.current) {
// 尝试加载 placeholderSrc,如果失败则加载 defaultPlaceholderSrc
if (imageRef.current.src !== placeholderSrc && placeholderSrc) {
imageRef.current.src = placeholderSrc
} else {
imageRef.current.src = defaultPlaceholderSrc
}
}
}
useEffect(() => {
const adjustedImageSrc =
adjustImgSize(src, maxWidth) || defaultPlaceholderSrc
// 加载原图
const img = new Image()
img.src = adjustedImageSrc
img.onload = () => {
setCurrentSrc(adjustedImageSrc)
handleImageLoaded(adjustedImageSrc)
}
img.onerror = handleImageError
const observer = new IntersectionObserver(
entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const lazyImage = entry.target
lazyImage.src = adjustedImageSrc
observer.unobserve(lazyImage)
}
})
},
{ rootMargin: '50px 0px' } // Adjust the rootMargin as needed to trigger the loading earlier or later
)
if (imageRef.current) {
observer.observe(imageRef.current)
}
return () => {
if (imageRef.current) {
observer.unobserve(imageRef.current)
}
}
}, [src, maxWidth])
// 动态添加width、height和className属性,仅在它们为有效值时添加
const imgProps = {
ref: imageRef,
src: currentSrc,
alt: alt,
onLoad: handleThumbnailLoaded, // 缩略图加载完成
onError: handleImageError // 添加onError处理函数
}
if (id) {
imgProps.id = id
}
if (title) {
imgProps.title = title
}
if (width && width !== 'auto') {
imgProps.width = width
}
if (height && height !== 'auto') {
imgProps.height = height
}
if (className) {
imgProps.className = className
}
if (style) {
imgProps.style = style
}
if (onClick) {
imgProps.onClick = onClick
}
return (
<>
{/* eslint-disable-next-line @next/next/no-img-element */}
{/* 预加载 */}
{priority && (