[O] Optimize bookmark rendering

This commit is contained in:
Hykilpikonna
2021-12-11 12:20:09 -05:00
parent 111419940a
commit fc4e9039e9
+27 -37
View File
@@ -1,16 +1,17 @@
<template> <template>
<div id="nav" class="fbox-v" <div id="nav" class="fbox-v"
:class="(this.currentLink ? this.currentLink.textContent.toLowerCase() : '') + ' ' + (menuOpen ? 'open' : '')"> :class="(currentRoute) + ' ' + (menuOpen ? 'open' : '')"
v-if="currentRoute !== 'colorpicker'">
<div id="menu" @click="showMenu"><i class="fas fa-bars"></i></div> <div id="menu" @click="showMenu"><i class="fas fa-bars"></i></div>
<div id="items" class="fbox-v"> <div id="items" class="fbox-v">
<router-link class="router-link" to="/projects">{{ $t('nav.projects') }}</router-link> <router-link class="router-link" ref="projects" to="/projects">{{ $t('nav.projects') }}</router-link>
<div class="dot">·</div> <div class="dot">·</div>
<router-link class="router-link" to="/blog">{{ $t('nav.blog') }}</router-link> <router-link class="router-link" ref="blog" to="/blog">{{ $t('nav.blog') }}</router-link>
<div class="dot">·</div> <div class="dot">·</div>
<router-link class="router-link" to="/about">{{ $t('nav.about') }}</router-link> <router-link class="router-link" ref="about" to="/about">{{ $t('nav.about') }}</router-link>
<div class="dot">·</div> <div class="dot">·</div>
<router-link class="router-link" to="/">{{ $t('nav.home') }}</router-link> <router-link class="router-link" ref="home" to="/">{{ $t('nav.home') }}</router-link>
<div class="dot">·</div> <div class="dot">·</div>
<router-link class="router-link" to="/new-home"> <router-link class="router-link" to="/new-home">
<svg focusable="false" data-prefix="fal" data-icon="house-night" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" class="svg-inline--fa fa-house-night fa-w-20"><path fill="currentColor" d="M112,224a111.5,111.5,0,0,0,87-41.45,20.51,20.51,0,0,0-19.75-33.08A59.2,59.2,0,0,1,138.84,39.85a20.3,20.3,0,0,0,10.07-21.27,20.26,20.26,0,0,0-16.47-16.7A136,136,0,0,0,112,0a112,112,0,0,0,0,224ZM97.78,33.27a91.21,91.21,0,0,0,54.47,147.9A80,80,0,1,1,97.78,33.27Zm97.15,35.51,39.72,16.56,16.56,39.72a5.33,5.33,0,0,0,9.55,0l16.56-39.72L317,68.78a5.33,5.33,0,0,0,0-9.54L277.32,42.68,260.76,3a5.33,5.33,0,0,0-9.55,0L234.65,42.68,194.93,59.24a5.34,5.34,0,0,0,0,9.54ZM157,379.24l-39.72-16.57L100.76,323a5.34,5.34,0,0,0-9.55,0L74.65,362.67,34.93,379.24a5.34,5.34,0,0,0,0,9.54l39.72,16.56,16.56,39.72a5.33,5.33,0,0,0,9.55,0l16.56-39.72L157,388.78a5.33,5.33,0,0,0,0-9.54Zm179-101.9v85.33A21.39,21.39,0,0,0,357.36,384h85.31A21.39,21.39,0,0,0,464,362.67V277.34A21.4,21.4,0,0,0,442.67,256H357.36A21.4,21.4,0,0,0,336,277.34ZM368,288H432v64H368Zm266.49,8L576,244.75V144a16,16,0,0,0-32,0v72.75L410.53,100a16,16,0,0,0-21.07,0l-224,196a16,16,0,0,0,21.07,24.09L224,287.28V464a48.05,48.05,0,0,0,48,48H528a48.06,48.06,0,0,0,48-48V287.28l37.46,32.78A16,16,0,0,0,634.53,296ZM544,464a16,16,0,0,1-16,16H272a16,16,0,0,1-16-16V264a15.94,15.94,0,0,0-.81-4L400,133.27l144,126Z" class=""></path></svg></router-link> <svg focusable="false" data-prefix="fal" data-icon="house-night" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" class="svg-inline--fa fa-house-night fa-w-20"><path fill="currentColor" d="M112,224a111.5,111.5,0,0,0,87-41.45,20.51,20.51,0,0,0-19.75-33.08A59.2,59.2,0,0,1,138.84,39.85a20.3,20.3,0,0,0,10.07-21.27,20.26,20.26,0,0,0-16.47-16.7A136,136,0,0,0,112,0a112,112,0,0,0,0,224ZM97.78,33.27a91.21,91.21,0,0,0,54.47,147.9A80,80,0,1,1,97.78,33.27Zm97.15,35.51,39.72,16.56,16.56,39.72a5.33,5.33,0,0,0,9.55,0l16.56-39.72L317,68.78a5.33,5.33,0,0,0,0-9.54L277.32,42.68,260.76,3a5.33,5.33,0,0,0-9.55,0L234.65,42.68,194.93,59.24a5.34,5.34,0,0,0,0,9.54ZM157,379.24l-39.72-16.57L100.76,323a5.34,5.34,0,0,0-9.55,0L74.65,362.67,34.93,379.24a5.34,5.34,0,0,0,0,9.54l39.72,16.56,16.56,39.72a5.33,5.33,0,0,0,9.55,0l16.56-39.72L157,388.78a5.33,5.33,0,0,0,0-9.54Zm179-101.9v85.33A21.39,21.39,0,0,0,357.36,384h85.31A21.39,21.39,0,0,0,464,362.67V277.34A21.4,21.4,0,0,0,442.67,256H357.36A21.4,21.4,0,0,0,336,277.34ZM368,288H432v64H368Zm266.49,8L576,244.75V144a16,16,0,0,0-32,0v72.75L410.53,100a16,16,0,0,0-21.07,0l-224,196a16,16,0,0,0,21.07,24.09L224,287.28V464a48.05,48.05,0,0,0,48,48H528a48.06,48.06,0,0,0,48-48V287.28l37.46,32.78A16,16,0,0,0,634.53,296ZM544,464a16,16,0,0,1-16,16H272a16,16,0,0,1-16-16V264a15.94,15.94,0,0,0-.81-4L400,133.27l144,126Z" class=""></path></svg></router-link>
@@ -29,25 +30,12 @@
<script lang="ts"> <script lang="ts">
import {Options, Vue} from "vue-class-component"; import {Options, Vue} from "vue-class-component";
import router from "@/router"; import router from "@/router";
import {RouteLocationNormalized} from "vue-router";
function runAfter(condition: () => boolean, callback: () => void, timeout=10): void
{
let times = 0
let id = setInterval(() => {
if (times <= timeout && !condition())
{
times ++
return
}
callback()
clearInterval(id)
}, 10)
}
@Options({components: {}}) @Options({components: {}})
export default class App extends Vue export default class App extends Vue
{ {
currentRoute = ''
currentLink: Element = null as never as Element currentLink: Element = null as never as Element
bookmarkCss = "" bookmarkCss = ""
bookmarkUpdateIntervalId!: number bookmarkUpdateIntervalId!: number
@@ -60,40 +48,42 @@ export default class App extends Vue
this.menuOpen = !this.menuOpen this.menuOpen = !this.menuOpen
// Auto close // Auto close
if (this.menuOpen) if (this.menuOpen) setTimeout(() => this.menuOpen = false, 2000)
{
setTimeout(() => this.menuOpen = false, 2000)
}
} }
updateBookmark(): void updateBookmark(to: RouteLocationNormalized): void
{ {
// On page change console.log('AfterEach called', to)
runAfter(() => document.querySelector('.router-link-active') != this.currentLink, () => this.currentRoute = (to.name as string).toLowerCase()
{
let el = document.querySelector('.router-link-active')
if (el != null) this.currentLink = el
this.calculateBookmarkCss()
// Close menu this.calculateBookmarkCss()
this.menuOpen = false this.menuOpen = false
})
} }
mounted(): void mounted(): void
{ {
router.afterEach(() => this.updateBookmark()) console.log('Mounted called', this.$route)
this.updateBookmark() router.afterEach(this.updateBookmark)
if (this.$route.name) this.currentRoute = (this.$route.name as string).toLowerCase()
// Resize listener // Resize listener
window.addEventListener('resize', () => this.calculateBookmarkCss(), true); window.addEventListener('resize', this.calculateBookmarkCss, true);
// Update every second // Update every second
this.bookmarkUpdateIntervalId = setInterval(this.calculateBookmarkCss, 1000) this.bookmarkUpdateIntervalId = setInterval(this.calculateBookmarkCss, 1000)
} }
unmounted(): void
{
window.removeEventListener('resize', this.calculateBookmarkCss)
clearInterval(this.bookmarkUpdateIntervalId)
}
calculateBookmarkCss(): void calculateBookmarkCss(): void
{ {
if (this.currentRoute in this.$refs)
this.currentLink = (this.$refs[this.currentRoute] as Vue).$el
// https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect // https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect
let box = this.currentLink.getBoundingClientRect() let box = this.currentLink.getBoundingClientRect()
if (box.top == this.lastTop) return if (box.top == this.lastTop) return