Scroll to top button
This commit is contained in:
parent
4bd4d08f06
commit
4869352450
2 changed files with 84 additions and 0 deletions
82
src/components/ScrollToTop.astro
Normal file
82
src/components/ScrollToTop.astro
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
---
|
||||||
|
import Icon from "./Icon.astro";
|
||||||
|
---
|
||||||
|
|
||||||
|
<div id="scroll-to-top" data-show="0">
|
||||||
|
<a href="#">
|
||||||
|
<Icon code="" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
@size: 2.25rem;
|
||||||
|
@font: 1.50rem;
|
||||||
|
|
||||||
|
div {
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
&[data-show="0"] a {
|
||||||
|
height: 0;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease, height 0.2s step-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-show="1"] a {
|
||||||
|
height: @size;
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.2s ease, height 0.2s step-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0.5rem;
|
||||||
|
right: 0.625rem;
|
||||||
|
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.25rem;
|
||||||
|
|
||||||
|
width: @size;
|
||||||
|
height: @size;
|
||||||
|
border-radius: @size;
|
||||||
|
font-size: @font;
|
||||||
|
|
||||||
|
background: var(--accent-bg);
|
||||||
|
color: var(--fg);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--bg-sec);
|
||||||
|
color: var(--fg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const stt = document.getElementById('scroll-to-top')
|
||||||
|
const doc = document.documentElement
|
||||||
|
|
||||||
|
let scrollPos = 0
|
||||||
|
let ticking = false
|
||||||
|
|
||||||
|
const handler = (pos: number) => {
|
||||||
|
if (pos > doc.clientHeight / 2) {
|
||||||
|
stt.dataset.show = '1'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
stt.dataset.show = '0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener('scroll', () => {
|
||||||
|
scrollPos = window.scrollY
|
||||||
|
if (!ticking) {
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
handler(scrollPos)
|
||||||
|
ticking = false
|
||||||
|
})
|
||||||
|
ticking = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
|
@ -2,6 +2,7 @@
|
||||||
import Layout from "./Layout.astro";
|
import Layout from "./Layout.astro";
|
||||||
import NavMenu from "./NavMenu.astro";
|
import NavMenu from "./NavMenu.astro";
|
||||||
import MenuItem from "../components/MenuItem.astro";
|
import MenuItem from "../components/MenuItem.astro";
|
||||||
|
import ScrollToTop from "../components/ScrollToTop.astro";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -14,6 +15,7 @@ const { title, description, mainpage = false } = Astro.props;
|
||||||
|
|
||||||
<Layout title={"Blog | " + title} description={description}>
|
<Layout title={"Blog | " + title} description={description}>
|
||||||
<slot name="metadata" slot="metadata" />
|
<slot name="metadata" slot="metadata" />
|
||||||
|
<ScrollToTop />
|
||||||
<NavMenu>
|
<NavMenu>
|
||||||
{
|
{
|
||||||
mainpage ?
|
mainpage ?
|
||||||
|
|
Loading…
Add table
Reference in a new issue