封装isBroswer()

This commit is contained in:
tlyong1992
2022-05-24 17:01:42 +08:00
parent a324cc127c
commit 8c19d88630
29 changed files with 110 additions and 114 deletions

View File

@@ -2,6 +2,7 @@ import { NotionRenderer } from 'react-notion-x'
import dynamic from 'next/dynamic'
import mediumZoom from 'medium-zoom'
import React from 'react'
import { isBrowser } from '@/lib/utils'
const Code = dynamic(() =>
import('react-notion-x/build/third-party/code').then((m) => m.Code), { ssr: false }
@@ -27,7 +28,7 @@ const NotionPage = ({ post }) => {
return <>{post?.summary || ''}</>
}
const zoom = typeof window !== 'undefined' && mediumZoom({
const zoom = isBrowser() && mediumZoom({
container: '.notion-viewport',
background: 'rgba(0, 0, 0, 0.2)',
margin: getMediumZoomMargin()
@@ -39,7 +40,7 @@ const NotionPage = ({ post }) => {
addWatch4Dom()
}, [])
setTimeout(() => {
if (typeof document !== 'undefined') {
if (isBrowser()) {
// 将相册gallery下的图片加入放大功能
const imgList = document.querySelectorAll('.notion-collection-card-cover img')
if (imgList && zoomRef.current) {

View File

@@ -24,22 +24,20 @@ const SideBarDrawer = ({ children, isOpen, onOpen, onClose, className }) => {
// 点击按钮更改侧边抽屉状态
const switchSideDrawerVisible = (showStatus) => {
if (window) {
if (showStatus) {
onOpen()
} else {
onClose()
}
const sideBarDrawer = window.document.getElementById('sidebar-drawer')
const sideBarDrawerBackground = window.document.getElementById('sidebar-drawer-background')
if (showStatus) {
onOpen()
} else {
onClose()
}
const sideBarDrawer = window.document.getElementById('sidebar-drawer')
const sideBarDrawerBackground = window.document.getElementById('sidebar-drawer-background')
if (showStatus) {
sideBarDrawer.classList.replace('-ml-80', 'ml-0')
sideBarDrawerBackground.classList.replace('hidden', 'block')
} else {
sideBarDrawer.classList.replace('ml-0', '-ml-80')
sideBarDrawerBackground.classList.replace('block', 'hidden')
}
if (showStatus) {
sideBarDrawer.classList.replace('-ml-80', 'ml-0')
sideBarDrawerBackground.classList.replace('hidden', 'block')
} else {
sideBarDrawer.classList.replace('ml-0', '-ml-80')
sideBarDrawerBackground.classList.replace('block', 'hidden')
}
}

View File

@@ -2,7 +2,7 @@ import zhCN from './lang/zh-CN'
import enUS from './lang/en-US'
import zhHK from './lang/zh-HK'
import zhTW from './lang/zh-TW'
import { mergeDeep } from './utils'
import { isBrowser, mergeDeep } from './utils'
const lang = {
'en-US': enUS,
'zh-CN': zhCN,
@@ -45,7 +45,7 @@ export function generateLocaleDict (langString) {
* 根据用户当前浏览器语言进行切换
*/
export function initLocale (locale, changeLocale) {
if (typeof window !== 'undefined') {
if (isBrowser()) {
const targetLocale = generateLocaleDict(window.navigator.language)
if (JSON.stringify(locale) !== JSON.stringify(targetLocale)) {
changeLocale(targetLocale)

View File

@@ -38,6 +38,7 @@ async function getPageWithRetry(id, from, retryAttempts = 3) {
console.info('[响应成功]:', `from:${from}`, `id:${id}`)
return pageData
} catch (e) {
console.warn('[响应异常]:', e)
await delay(1000)
const cacheKey = 'page_block_' + id
const pageBlock = await getDataFromCache(cacheKey)

View File

@@ -32,7 +32,7 @@ export function loadExternalResource(url, type) {
* @returns
*/
export function getQueryVariable(variable) {
const query = typeof window !== 'undefined' ? window.location.search.substring(1) : ''
const query = isBrowser() ? window.location.search.substring(1) : ''
const vars = query.split('&')
for (let i = 0; i < vars.length; i++) {
const pair = vars[i].split('=')
@@ -99,3 +99,9 @@ export function deepClone(obj) {
* @returns
*/
export const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
/**
* 判断是否客户端
* @returns {boolean}
*/
export const isBrowser = () => typeof window !== 'undefined'

View File

@@ -5,6 +5,7 @@ import { useGlobal } from '@/lib/global'
import * as ThemeMap from '@/themes'
import React from 'react'
import { useRouter } from 'next/router'
import { isBrowser } from '@/lib/utils'
/**
* 根据notion的slug访问页面针对类型为Page的页面
@@ -20,7 +21,7 @@ const Slug = props => {
changeLoadingState(true)
const router = useRouter()
setTimeout(() => {
if (typeof document !== 'undefined') {
if (isBrowser()) {
const article = document.getElementById('container')
if (!article) {
router.push('/404').then(() => {

View File

@@ -6,6 +6,7 @@ import * as ThemeMap from '@/themes'
import React from 'react'
import { idToUuid } from 'notion-utils'
import { useRouter } from 'next/router'
import { isBrowser } from '@/lib/utils'
/**
* 根据notion的slug访问页面
@@ -21,7 +22,7 @@ const Slug = props => {
changeLoadingState(true)
const router = useRouter()
setTimeout(() => {
if (typeof document !== 'undefined') {
if (isBrowser()) {
const article = document.getElementById('container')
if (!article) {
router.push('/404').then(() => {

View File

@@ -27,7 +27,7 @@ export async function getStaticProps() {
if (BLOG.POST_LIST_STYLE !== 'page') {
postsToShow = Array.from(allPosts)
} else {
postsToShow = allPosts.slice(
postsToShow = allPosts?.slice(
BLOG.POSTS_PER_PAGE * (page - 1),
BLOG.POSTS_PER_PAGE * page
)

View File

@@ -5,6 +5,7 @@ import { useRouter } from 'next/router'
import { useEffect, useState } from 'react'
import SearchInput from './components/SearchInput'
import LayoutBase from './LayoutBase'
import { isBrowser } from '@/lib/utils'
export const LayoutSearch = props => {
const { keyword, posts } = props
@@ -12,7 +13,7 @@ export const LayoutSearch = props => {
useEffect(() => {
setTimeout(() => {
const container = typeof document !== 'undefined' && document.getElementById('container')
const container = isBrowser() && document.getElementById('container')
if (container && container.innerHTML) {
const re = new RegExp(`${keyword}`, 'gim')
container.innerHTML = container.innerHTML.replace(re, `<span class='text-red-500 border-b border-dashed'>${keyword}</span>`)

View File

@@ -25,16 +25,14 @@ export const LayoutArchive = (props) => {
})
useEffect(() => {
if (window) {
const anchor = window.location.hash
if (anchor) {
setTimeout(() => {
const anchorElement = document.getElementById(anchor.substring(1))
if (anchorElement) {
anchorElement.scrollIntoView({ block: 'start', behavior: 'smooth' })
}
}, 300)
}
const anchor = window.location.hash
if (anchor) {
setTimeout(() => {
const anchorElement = document.getElementById(anchor.substring(1))
if (anchorElement) {
anchorElement.scrollIntoView({ block: 'start', behavior: 'smooth' })
}
}, 300)
}
}, [])
return <LayoutBase {...props}>

View File

@@ -2,6 +2,7 @@ import LayoutBase from './LayoutBase'
import BlogListPage from './components/BlogListPage'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { isBrowser } from '@/lib/utils'
export const LayoutSearch = (props) => {
const { keyword } = props
@@ -9,7 +10,7 @@ export const LayoutSearch = (props) => {
const currentSearch = keyword || router?.query?.s
useEffect(() => {
setTimeout(() => {
const container = typeof document !== 'undefined' && document.getElementById('container')
const container = isBrowser() && document.getElementById('container')
if (container && container.innerHTML) {
const re = new RegExp(`${currentSearch}`, 'gim')
container.innerHTML = container.innerHTML.replace(re, `<span class='text-red-500 border-b border-dashed'>${currentSearch}</span>`)

View File

@@ -7,13 +7,11 @@ export const Layout404 = props => {
useEffect(() => {
// 延时3秒如果加载失败就返回首页
setTimeout(() => {
if (window) {
const article = typeof document !== 'undefined' && document.getElementById('container')
if (!article) {
router.push('/').then(() => {
// console.log('找不到页面', router.asPath)
})
}
const article = typeof document !== 'undefined' && document.getElementById('container')
if (!article) {
router.push('/').then(() => {
// console.log('找不到页面', router.asPath)
})
}
}, 3000)
})

View File

@@ -27,16 +27,14 @@ export const LayoutArchive = (props) => {
})
useEffect(() => {
if (window) {
const anchor = window.location.hash
if (anchor) {
setTimeout(() => {
const anchorElement = document.getElementById(anchor.substring(1))
if (anchorElement) {
anchorElement.scrollIntoView({ block: 'start', behavior: 'smooth' })
}
}, 300)
}
const anchor = window.location.hash
if (anchor) {
setTimeout(() => {
const anchorElement = document.getElementById(anchor.substring(1))
if (anchorElement) {
anchorElement.scrollIntoView({ block: 'start', behavior: 'smooth' })
}
}, 300)
}
}, [])
return <LayoutBase {...props} >

View File

@@ -4,9 +4,11 @@ import BlogPostListScroll from './components/BlogPostListScroll'
import Header from './components/Header'
import CONFIG_HEXO from './config_hexo'
import LayoutBase from './LayoutBase'
import React from 'react'
export const LayoutIndex = (props) => {
return <LayoutBase {...props} headerSlot={CONFIG_HEXO.HOME_BANNER_ENABLE && <Header {...props} />}>
{BLOG.POST_LIST_STYLE === 'page' ? <BlogPostListPage {...props} /> : <BlogPostListScroll {...props} />}
</LayoutBase>
}

View File

@@ -11,6 +11,7 @@ import NotionPage from '@/components/NotionPage'
import ArticleAdjacent from './components/ArticleAdjacent'
import ArticleCopyright from './components/ArticleCopyright'
import ArticleRecommend from './components/ArticleRecommend'
import { isBrowser } from '@/lib/utils'
export const LayoutSlug = props => {
const { post, lock, validPassword } = props
@@ -30,7 +31,7 @@ export const LayoutSlug = props => {
}
const drawerRight = useRef(null)
const targetRef = typeof window !== 'undefined' ? document.getElementById('container') : null
const targetRef = isBrowser() ? document.getElementById('container') : null
const floatSlot = <>
{post?.toc?.length > 1 && <div className="block lg:hidden">

View File

@@ -90,10 +90,8 @@ const Header = props => {
function updateHeaderHeight () {
setTimeout(() => {
if (window) {
const wrapperElement = document.getElementById('wrapper')
wrapperTop = wrapperElement?.offsetTop
}
const wrapperElement = document.getElementById('wrapper')
wrapperTop = wrapperElement?.offsetTop
}, 500)
}

View File

@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react'
import { isBrowser } from '@/lib/utils'
/**
* 顶部页面阅读进度条
@@ -9,7 +10,7 @@ const Progress = ({ targetRef, showPercent = true }) => {
const currentRef = targetRef?.current || targetRef
const [percent, changePercent] = useState(0)
const scrollListener = () => {
const target = currentRef || (typeof document !== 'undefined' && document.getElementById('container'))
const target = currentRef || (isBrowser() && document.getElementById('container'))
if (target) {
const clientHeight = target.clientHeight
const scrollY = window.pageYOffset

View File

@@ -5,13 +5,14 @@ import TagGroups from './components/TagGroups'
import CategoryGroup from './components/CategoryGroup'
import BlogPostListScroll from './components/BlogPostListScroll'
import { useEffect } from 'react'
import { isBrowser } from '@/lib/utils'
export const LayoutSearch = (props) => {
const { locale } = useGlobal()
const { keyword } = props
useEffect(() => {
setTimeout(() => {
const container = typeof document !== 'undefined' && document.getElementById('container')
const container = isBrowser() && document.getElementById('container')
if (container && container.innerHTML) {
const re = new RegExp(`${keyword}`, 'gim')
container.innerHTML = container.innerHTML.replace(re, `<span class='text-red-500 border-b border-dashed'>${keyword}</span>`)

View File

@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react'
import { isBrowser } from '@/lib/utils'
/**
* 顶部页面阅读进度条
@@ -9,7 +10,7 @@ const Progress = ({ targetRef, showPercent = true }) => {
const currentRef = targetRef?.current || targetRef
const [percent, changePercent] = useState(0)
const scrollListener = () => {
const target = currentRef || (typeof document !== 'undefined' && document.getElementById('container'))
const target = currentRef || (isBrowser() && document.getElementById('container'))
if (target) {
const clientHeight = target.clientHeight
const scrollY = window.pageYOffset

View File

@@ -1,19 +1,18 @@
import { useRouter } from 'next/router'
import LayoutBase from './LayoutBase'
import { useEffect } from 'react'
import { isBrowser } from '@/lib/utils'
export const Layout404 = props => {
const router = useRouter()
useEffect(() => {
// 延时3秒如果加载失败就返回首页
setTimeout(() => {
if (window) {
const article = typeof document !== 'undefined' && document.getElementById('container')
if (!article) {
router.push('/').then(() => {
// console.log('找不到页面', router.asPath)
})
}
const article = isBrowser() && document.getElementById('container')
if (!article) {
router.push('/').then(() => {
// console.log('找不到页面', router.asPath)
})
}
}, 3000)
}, [])

View File

@@ -26,16 +26,14 @@ export const LayoutArchive = (props) => {
})
useEffect(() => {
if (window) {
const anchor = window.location.hash
if (anchor) {
setTimeout(() => {
const anchorElement = document.getElementById(anchor.substring(1))
if (anchorElement) {
anchorElement.scrollIntoView({ block: 'start', behavior: 'smooth' })
}
}, 300)
}
const anchor = window.location.hash
if (anchor) {
setTimeout(() => {
const anchorElement = document.getElementById(anchor.substring(1))
if (anchorElement) {
anchorElement.scrollIntoView({ block: 'start', behavior: 'smooth' })
}
}, 300)
}
}, [])

View File

@@ -2,12 +2,13 @@ import LayoutBase from './LayoutBase'
import StickyBar from './components/StickyBar'
import BlogPostListScroll from './components/BlogPostListScroll'
import { useGlobal } from '@/lib/global'
import { isBrowser } from '@/lib/utils'
export const LayoutSearch = (props) => {
const { locale } = useGlobal()
const { posts, keyword } = props
setTimeout(() => {
const container = typeof document !== 'undefined' && document.getElementById('container')
const container = isBrowser() && document.getElementById('container')
if (container && container.innerHTML) {
const re = new RegExp(`${keyword}`, 'gim')
container.innerHTML = container.innerHTML.replace(re, `<span class='text-red-500 border-b border-dashed'>${keyword}</span>`)

View File

@@ -8,6 +8,7 @@ import TocDrawer from './components/TocDrawer'
import { useRef } from 'react'
import CONFIG_NEXT from './config_next'
import { ArticleLock } from './components/ArticleLock'
import { isBrowser } from '@/lib/utils'
export const LayoutSlug = (props) => {
const { post, latestPosts, lock, validPassword } = props
@@ -26,7 +27,7 @@ export const LayoutSlug = (props) => {
}
const drawerRight = useRef(null)
const targetRef = typeof window !== 'undefined' ? document.getElementById('container') : null
const targetRef = isBrowser() ? document.getElementById('container') : null
const floatSlot = post?.toc?.length > 1
? <div className='block lg:hidden'><TocDrawerButton onClick={() => {
drawerRight?.current?.handleSwitchVisible()

View File

@@ -74,10 +74,8 @@ export default function Header(props) {
function updateHeaderHeight() {
setTimeout(() => {
if (window) {
const wrapperElement = document.getElementById('wrapper')
wrapperTop = wrapperElement.offsetTop
}
const wrapperElement = document.getElementById('wrapper')
wrapperTop = wrapperElement.offsetTop
}, 500)
}

View File

@@ -4,9 +4,7 @@ import { loadExternalResource } from '@/lib/utils'
export default function Live2DWife() {
useEffect(() => {
if (window) {
initLive2DWife()
}
initLive2DWife()
}, [])
return <>
<Head><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome/css/font-awesome.min.css" /></Head>

View File

@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react'
import { isBrowser } from '@/lib/utils'
/**
* 顶部页面阅读进度条
@@ -9,7 +10,7 @@ const Progress = ({ targetRef, showPercent = true }) => {
const currentRef = targetRef?.current || targetRef
const [percent, changePercent] = useState(0)
const scrollListener = () => {
const target = currentRef || (typeof document !== 'undefined' && document.getElementById('container'))
const target = currentRef || (isBrowser() && document.getElementById('container'))
if (target) {
const clientHeight = target.clientHeight
const scrollY = window.pageYOffset

View File

@@ -8,14 +8,10 @@ import Image from 'next/image'
*/
const RewardButton = () => {
const openPopover = () => {
if (window) {
document.getElementById('reward-qrcode').classList.remove('hidden')
}
document.getElementById('reward-qrcode').classList.remove('hidden')
}
const closePopover = () => {
if (window) {
document.getElementById('reward-qrcode').classList.add('hidden')
}
document.getElementById('reward-qrcode').classList.add('hidden')
}
return (
<div className='justify-center'>

View File

@@ -33,17 +33,15 @@ const SideBarDrawer = ({ post, cRef, tags, slot, categories, currentCategory })
// 点击按钮更改侧边抽屉状态
const switchSideDrawerVisible = (showStatus) => {
if (window) {
const sideBarDrawer = window.document.getElementById('sidebar-drawer')
const sideBarDrawerBackground = window.document.getElementById('sidebar-drawer-background')
const sideBarDrawer = window.document.getElementById('sidebar-drawer')
const sideBarDrawerBackground = window.document.getElementById('sidebar-drawer-background')
if (showStatus) {
sideBarDrawer.classList.replace('-ml-80', 'ml-0')
sideBarDrawerBackground.classList.replace('hidden', 'block')
} else {
sideBarDrawer.classList.replace('ml-0', '-ml-80')
sideBarDrawerBackground.classList.replace('block', 'hidden')
}
if (showStatus) {
sideBarDrawer.classList.replace('-ml-80', 'ml-0')
sideBarDrawerBackground.classList.replace('hidden', 'block')
} else {
sideBarDrawer.classList.replace('ml-0', '-ml-80')
sideBarDrawerBackground.classList.replace('block', 'hidden')
}
}

View File

@@ -18,17 +18,15 @@ export default function WordCount() {
* 更新字数统计和阅读时间
*/
function countWords() {
if (window) {
const articleElement = document.getElementById('notion-article')
if (articleElement) {
const articleText = deleteHtmlTag(articleElement.innerHTML)
const wordCount = fnGetCpmisWords(articleText)
// 阅读速度 300-500每分钟
document.getElementById('wordCount').innerHTML = wordCount
document.getElementById('readTime').innerHTML = Math.floor(wordCount / 400) + 1
const wordCountWrapper = document.getElementById('wordCountWrapper')
wordCountWrapper.classList.remove('hidden')
}
const articleElement = document.getElementById('notion-article')
if (articleElement) {
const articleText = deleteHtmlTag(articleElement.innerHTML)
const wordCount = fnGetCpmisWords(articleText)
// 阅读速度 300-500每分钟
document.getElementById('wordCount').innerHTML = wordCount
document.getElementById('readTime').innerHTML = Math.floor(wordCount / 400) + 1
const wordCountWrapper = document.getElementById('wordCountWrapper')
wordCountWrapper.classList.remove('hidden')
}
}