mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-14 07:26:52 +00:00
hexo: topnav微调
This commit is contained in:
@@ -1,10 +1,5 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import formatDate from '@/lib/formatDate'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { getPageTableOfContents } from 'notion-utils'
|
||||
import { faFolderOpen } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import Link from 'next/link'
|
||||
import 'prismjs'
|
||||
import 'prismjs/components/prism-bash'
|
||||
import 'prismjs/components/prism-java'
|
||||
@@ -12,12 +7,12 @@ import 'prismjs/components/prism-javascript'
|
||||
import 'prismjs/components/prism-markup'
|
||||
import 'prismjs/components/prism-python'
|
||||
import 'prismjs/components/prism-typescript'
|
||||
import CONFIG_NEXT from '../NEXT/config_next'
|
||||
import ArticleDetail from './components/ArticleDetail'
|
||||
import LayoutBase from './LayoutBase'
|
||||
import TocDrawerButton from './components/TocDrawerButton'
|
||||
import { useRef } from 'react'
|
||||
import ArticleDetail from './components/ArticleDetail'
|
||||
import HeaderArticle from './components/HeaderArticle'
|
||||
import TocDrawer from './components/TocDrawer'
|
||||
import TocDrawerButton from './components/TocDrawerButton'
|
||||
import LayoutBase from './LayoutBase'
|
||||
|
||||
export const LayoutSlug = props => {
|
||||
const { post } = props
|
||||
@@ -28,64 +23,11 @@ export const LayoutSlug = props => {
|
||||
tags: post.tags
|
||||
}
|
||||
|
||||
const { locale } = useGlobal()
|
||||
const date = formatDate(
|
||||
post?.date?.start_date || post.createdTime,
|
||||
locale.LOCALE
|
||||
)
|
||||
|
||||
if (post?.blockMap?.block) {
|
||||
post.content = Object.keys(post.blockMap.block)
|
||||
post.toc = getPageTableOfContents(post, post.blockMap)
|
||||
}
|
||||
|
||||
const headerImage = post?.page_cover ? `url("${post.page_cover}")` : `url("/${CONFIG_NEXT.HOME_BANNER_IMAGE}")`
|
||||
const headerSlot = (
|
||||
<div
|
||||
className="w-full h-96 relative md:flex-shrink-0 overflow-hidden bg-cover bg-center bg-no-repeat"
|
||||
style={{ backgroundImage: headerImage }}
|
||||
>
|
||||
<header className="animate__slideInDown animate__animated bg-black bg-opacity-70 absolute top-0 w-full h-96 py-10 flex justify-center items-center font-sans">
|
||||
<div>
|
||||
{/* 文章Title */}
|
||||
<div className="font-bold text-3xl shadow-text flex justify-center text-white dark:text-white font-sans">
|
||||
{post.title}
|
||||
</div>
|
||||
|
||||
<section className="flex-wrap shadow-text flex justify-center mt-2 text-white dark:text-gray-400 font-light leading-8">
|
||||
<div>
|
||||
<Link href={`/category/${post.category}`} passHref>
|
||||
<a className="cursor-pointer text-md mr-2 dark:hover:text-white border-b dark:border-gray-500 border-dashed">
|
||||
<FontAwesomeIcon icon={faFolderOpen} className="mr-1" />
|
||||
{post.category}
|
||||
</a>
|
||||
</Link>
|
||||
<span className="mr-2">|</span>
|
||||
|
||||
{post.type[0] !== 'Page' && (
|
||||
<>
|
||||
<Link
|
||||
href={`/archive#${post?.date?.start_date?.substr(0, 7)}`}
|
||||
passHref
|
||||
>
|
||||
<a className="pl-1 mr-2 cursor-pointer hover:underline border-b dark:border-gray-500 border-dashed">
|
||||
{date}
|
||||
</a>
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="hidden busuanzi_container_page_pv font-light mr-2">
|
||||
<span className="mr-2">|</span>
|
||||
<span className="mr-2 busuanzi_value_page_pv" />
|
||||
次访问
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
)
|
||||
const drawerRight = useRef(null)
|
||||
const targetRef = typeof window !== 'undefined' ? document.getElementById('container') : null
|
||||
|
||||
@@ -104,7 +46,7 @@ export const LayoutSlug = props => {
|
||||
|
||||
return (
|
||||
<LayoutBase
|
||||
headerSlot={headerSlot}
|
||||
headerSlot={<HeaderArticle post={post}/>}
|
||||
{...props}
|
||||
meta={meta}
|
||||
showCategory={false}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { faAngleDown } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
@@ -15,7 +16,12 @@ let autoScroll = false
|
||||
*/
|
||||
export default function Header () {
|
||||
const [typed, changeType] = useState()
|
||||
const { theme } = useGlobal()
|
||||
|
||||
useEffect(() => {
|
||||
scrollTrigger()
|
||||
updateHeaderHeight()
|
||||
updateTopNav()
|
||||
if (!typed && window && document.getElementById('typed')) {
|
||||
changeType(
|
||||
new Typed('#typed', {
|
||||
@@ -28,8 +34,13 @@ export default function Header () {
|
||||
})
|
||||
)
|
||||
}
|
||||
window.addEventListener('scroll', scrollTrigger)
|
||||
window.addEventListener('resize', updateHeaderHeight)
|
||||
return () => {
|
||||
window.removeEventListener('scroll', scrollTrigger)
|
||||
window.removeEventListener('resize', updateHeaderHeight)
|
||||
}
|
||||
})
|
||||
const { theme } = useGlobal()
|
||||
|
||||
const autoScrollEnd = () => {
|
||||
if (autoScroll) {
|
||||
@@ -39,25 +50,29 @@ export default function Header () {
|
||||
}
|
||||
|
||||
const scrollTrigger = () => {
|
||||
if (
|
||||
(window.scrollY > windowTop) &
|
||||
(window.scrollY < window.innerHeight) &&
|
||||
!autoScroll
|
||||
const scrollS = window.scrollY
|
||||
const nav = document.querySelector('#sticky-nav')
|
||||
|
||||
if (scrollS < 300) {
|
||||
nav && nav.classList.replace('bg-white', 'bg-none')
|
||||
nav && nav.classList.replace('text-black', 'text-white')
|
||||
} else {
|
||||
nav && nav.classList.replace('bg-none', 'bg-white')
|
||||
nav && nav.classList.replace('text-white', 'text-black')
|
||||
}
|
||||
|
||||
if ((scrollS > windowTop) & (scrollS < window.innerHeight) && !autoScroll
|
||||
) {
|
||||
autoScroll = true
|
||||
window.scrollTo({ top: wrapperTop, behavior: 'smooth' })
|
||||
setTimeout(autoScrollEnd, 500)
|
||||
}
|
||||
if (
|
||||
(window.scrollY < windowTop) &
|
||||
(window.scrollY < window.innerHeight) &&
|
||||
!autoScroll
|
||||
) {
|
||||
if ((scrollS < windowTop) && (scrollS < window.innerHeight) && !autoScroll) {
|
||||
autoScroll = true
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||
setTimeout(autoScrollEnd, 500)
|
||||
}
|
||||
windowTop = window.scrollY
|
||||
windowTop = scrollS
|
||||
|
||||
updateTopNav()
|
||||
}
|
||||
@@ -82,17 +97,6 @@ export default function Header () {
|
||||
}, 500)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
updateHeaderHeight()
|
||||
updateTopNav()
|
||||
window.addEventListener('scroll', scrollTrigger)
|
||||
window.addEventListener('resize', updateHeaderHeight)
|
||||
return () => {
|
||||
window.removeEventListener('scroll', scrollTrigger)
|
||||
window.removeEventListener('resize', updateHeaderHeight)
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<header
|
||||
id="header"
|
||||
@@ -102,14 +106,15 @@ export default function Header () {
|
||||
`linear-gradient(rgba(0, 0, 0, 0.8), rgba(0,0,0,0.2), rgba(0, 0, 0, 0.8) ),url("${CONFIG_HEXO.HOME_BANNER_IMAGE}")`
|
||||
}}
|
||||
>
|
||||
<div className="absolute flex h-full items-center lg:-mt-14 justify-center w-full text-4xl md:text-7xl text-white">
|
||||
<div id='typed' className='flex text-center font-sans shadow-text'/>
|
||||
<div className="absolute flex flex-col h-full items-center justify-center w-full font-sans">
|
||||
<div className='text-4xl md:text-5xl text-white shadow-text'>{BLOG.TITLE}</div>
|
||||
<div id='typed' className='flex h-10 items-center text-center text-lg shadow-text text-white'/>
|
||||
</div>
|
||||
<div
|
||||
onClick={() => {
|
||||
window.scrollTo({ top: wrapperTop, behavior: 'smooth' })
|
||||
}}
|
||||
className="cursor-pointer w-full text-center py-4 text-5xl absolute bottom-10 text-white"
|
||||
className="cursor-pointer w-full text-center py-4 text-3xl absolute bottom-10 text-white"
|
||||
>
|
||||
<FontAwesomeIcon icon={faAngleDown} className='animate-bounce'/>
|
||||
</div>
|
||||
|
||||
83
themes/Hexo/components/HeaderArticle.js
Normal file
83
themes/Hexo/components/HeaderArticle.js
Normal file
@@ -0,0 +1,83 @@
|
||||
import { faFolderOpen } from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import Link from 'next/link'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import formatDate from '@/lib/formatDate'
|
||||
import CONFIG_HEXO from '../config_hexo'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
export default function HeaderArticle ({ post }) {
|
||||
const headerImage = post?.page_cover ? `url("${post.page_cover}")` : `url("/${CONFIG_HEXO.HOME_BANNER_IMAGE}")`
|
||||
|
||||
const { locale } = useGlobal()
|
||||
const date = formatDate(
|
||||
post?.date?.start_date || post.createdTime,
|
||||
locale.LOCALE
|
||||
)
|
||||
|
||||
const scrollTrigger = () => {
|
||||
const scrollS = window.scrollY
|
||||
const nav = document.querySelector('#sticky-nav')
|
||||
|
||||
if (scrollS < 300) {
|
||||
nav && nav.classList.replace('bg-white', 'bg-none')
|
||||
nav && nav.classList.replace('text-black', 'text-white')
|
||||
} else {
|
||||
nav && nav.classList.replace('bg-none', 'bg-white')
|
||||
nav && nav.classList.replace('text-white', 'text-black')
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
window.addEventListener('scroll', scrollTrigger)
|
||||
return () => {
|
||||
window.removeEventListener('scroll', scrollTrigger)
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<div
|
||||
className="w-full h-96 relative md:flex-shrink-0 overflow-hidden bg-cover bg-center bg-no-repeat"
|
||||
style={{ backgroundImage: headerImage }}
|
||||
>
|
||||
<header className="animate__slideInDown animate__animated bg-black bg-opacity-70 absolute top-0 w-full h-96 py-10 flex justify-center items-center font-sans">
|
||||
<div>
|
||||
{/* 文章Title */}
|
||||
<div className="font-bold text-3xl shadow-text flex justify-center text-white dark:text-white font-sans">
|
||||
{post.title}
|
||||
</div>
|
||||
|
||||
<section className="flex-wrap shadow-text flex justify-center mt-2 text-white dark:text-gray-400 font-light leading-8">
|
||||
<div>
|
||||
<Link href={`/category/${post.category}`} passHref>
|
||||
<a className="cursor-pointer text-md mr-2 dark:hover:text-white border-b dark:border-gray-500 border-dashed">
|
||||
<FontAwesomeIcon icon={faFolderOpen} className="mr-1" />
|
||||
{post.category}
|
||||
</a>
|
||||
</Link>
|
||||
<span className="mr-2">|</span>
|
||||
|
||||
{post.type[0] !== 'Page' && (
|
||||
<>
|
||||
<Link
|
||||
href={`/archive#${post?.date?.start_date?.substr(0, 7)}`}
|
||||
passHref
|
||||
>
|
||||
<a className="pl-1 mr-2 cursor-pointer hover:underline border-b dark:border-gray-500 border-dashed">
|
||||
{date}
|
||||
</a>
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="hidden busuanzi_container_page_pv font-light mr-2">
|
||||
<span className="mr-2">|</span>
|
||||
<span className="mr-2 busuanzi_value_page_pv" />
|
||||
次访问
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -4,8 +4,8 @@ import React from 'react'
|
||||
|
||||
const Logo = () => {
|
||||
return <Link href='/' passHref>
|
||||
<div className='flex flex-col justify-center items-center cursor-pointer space-y-3 font-bold'>
|
||||
<div className='font-serif text-xl text-white'> {BLOG.TITLE}</div>
|
||||
<div className='flex flex-col justify-center items-center cursor-pointer space-y-3'>
|
||||
<div className='font-sans text-xl'> {BLOG.TITLE}</div>
|
||||
</div>
|
||||
</Link>
|
||||
}
|
||||
|
||||
@@ -26,12 +26,11 @@ const TopNav = ({ tags, currentTag, categories, currentCategory, postCount }) =>
|
||||
|
||||
const scrollTrigger = throttle(() => {
|
||||
const scrollS = window.scrollY
|
||||
if (scrollS >= windowTop && scrollS > 10) {
|
||||
const nav = document.querySelector('#sticky-nav')
|
||||
const nav = document.querySelector('#sticky-nav')
|
||||
if (scrollS >= windowTop && scrollS > 20) {
|
||||
nav && nav.classList.replace('top-0', '-top-16')
|
||||
windowTop = scrollS
|
||||
} else {
|
||||
const nav = document.querySelector('#sticky-nav')
|
||||
nav && nav.classList.replace('-top-16', 'top-0')
|
||||
windowTop = scrollS
|
||||
}
|
||||
@@ -90,8 +89,8 @@ const TopNav = ({ tags, currentTag, categories, currentCategory, postCount }) =>
|
||||
<SearchDrawer cRef={searchDrawer} slot={searchDrawerSlot}/>
|
||||
|
||||
{/* 导航栏 */}
|
||||
<div id='sticky-nav' className={`${CONFIG_HEXO.NAV_TYPE !== 'normal' ? 'fixed' : ''} w-full top-0 z-20 transform duration-500`}>
|
||||
<div className='w-full flex justify-between items-center p-4 bg-black shadow-md bg-opacity-70 text-white'>
|
||||
<div id='sticky-nav' className={`${CONFIG_HEXO.NAV_TYPE !== 'normal' ? 'fixed' : ''} bg-white bg-opacity-70 text-black w-full top-0 z-20 transform duration-500 font-sans`}>
|
||||
<div className='w-full flex justify-between items-center p-4 shadow-md'>
|
||||
<div className='flex'>
|
||||
<Logo/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user