Merge branch 'dev2' into master
This commit is contained in:
commit
23fcb40471
@ -4,3 +4,4 @@ $pale-grey: #f0f7fd;
|
|||||||
$dark-slate-blue: #1f4163;
|
$dark-slate-blue: #1f4163;
|
||||||
$dark-sky-blue: #3d93e9;
|
$dark-sky-blue: #3d93e9;
|
||||||
$slate-blue: #5f7a95;
|
$slate-blue: #5f7a95;
|
||||||
|
$sky-blue: #9dc5ec;
|
@ -360,10 +360,17 @@ $fontFamily: Noto Sans TC, monospace;
|
|||||||
background: white;
|
background: white;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
&-item {
|
&-item {
|
||||||
margin: 5px 8px;
|
margin: 0 8px;
|
||||||
|
padding: 5px 1em;
|
||||||
color: $mid-blue;
|
color: $mid-blue;
|
||||||
font-family: $fontFamily;
|
font-family: $fontFamily;
|
||||||
cursor: point;
|
cursor: point;
|
||||||
|
border-right: 3px solid $sky-blue;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
font-weight: 900;
|
||||||
|
border-right: 3px solid $mid-blue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&-button {
|
&-button {
|
||||||
color: $mid-blue;
|
color: $mid-blue;
|
||||||
@ -375,6 +382,16 @@ $fontFamily: Noto Sans TC, monospace;
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&-contribute-button {
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: $mid-blue;
|
||||||
|
color: $white;
|
||||||
|
font-weight: 900;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
font-size: 1.2em;
|
||||||
|
margin: 1em auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-control-button {
|
.nav-control-button {
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<nav v-if="navVisible">
|
<nav v-if="navVisible">
|
||||||
<div class="news-nav">
|
<div class="news-nav" v-scrollspy="{ selectors: navbarItems }">
|
||||||
<a class="news-nav-item" href="#schedule">重要時程</a>
|
<a class="news-nav-item" href="#schedule">重要時程</a>
|
||||||
<a class="news-nav-item" href="#example">投稿主題範例</a>
|
<a class="news-nav-item" href="#example">投稿主題範例</a>
|
||||||
<a class="news-nav-item" href="#code-of-conduct">Code of Conduct</a>
|
<a class="news-nav-item" href="#code-of-conduct">Code of Conduct</a>
|
||||||
@ -56,7 +56,7 @@
|
|||||||
<a class="news-nav-item" href="#methods">投稿方式</a>
|
<a class="news-nav-item" href="#methods">投稿方式</a>
|
||||||
<a class="news-nav-item" href="#review">審稿方式</a>
|
<a class="news-nav-item" href="#review">審稿方式</a>
|
||||||
<a class="news-nav-item" href="#precautions">投稿注意事項</a>
|
<a class="news-nav-item" href="#precautions">投稿注意事項</a>
|
||||||
<a class="news-nav-item" href="https://forms.gle/XoXJSD2P8dL8X8s2A">我要投稿</a>
|
<a class="news-nav-contribute-button" target="_blank" rel="noopener" href="https://forms.gle/XoXJSD2P8dL8X8s2A">我要投稿</a>
|
||||||
<button class="news-nav-button" @click="(e)=>navVisible=!navVisible">▲</button>
|
<button class="news-nav-button" @click="(e)=>navVisible=!navVisible">▲</button>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@ -69,6 +69,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||||
|
import ScrollSpyDirective from './ScrollSpyDirective';
|
||||||
|
|
||||||
const DEAD_LINE = Math.floor(
|
const DEAD_LINE = Math.floor(
|
||||||
new Date('22 Feb 2021 06:24:00 GMT+8').getTime() / 1000
|
new Date('22 Feb 2021 06:24:00 GMT+8').getTime() / 1000
|
||||||
@ -81,9 +82,23 @@ interface Countdown {
|
|||||||
d: number;
|
d: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component
|
@Component({
|
||||||
|
directives: {
|
||||||
|
scrollspy: ScrollSpyDirective
|
||||||
|
}
|
||||||
|
})
|
||||||
export default class CfpHeader extends Vue {
|
export default class CfpHeader extends Vue {
|
||||||
private timerId!: number;
|
private timerId!: number;
|
||||||
|
private navbarItems = [
|
||||||
|
'#schedule',
|
||||||
|
'#example',
|
||||||
|
'#code-of-conduct',
|
||||||
|
'#info-section',
|
||||||
|
'#process',
|
||||||
|
'#methods',
|
||||||
|
'#review',
|
||||||
|
'#precautions'
|
||||||
|
];
|
||||||
private navVisible = false;
|
private navVisible = false;
|
||||||
private countdown: Countdown = {
|
private countdown: Countdown = {
|
||||||
s: 0,
|
s: 0,
|
||||||
|
37
src/components/news/ScrollSpyDirective.ts
Normal file
37
src/components/news/ScrollSpyDirective.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import Vue, { DirectiveOptions, VNode, VNodeDirective } from 'vue';
|
||||||
|
|
||||||
|
let selectors!: string[];
|
||||||
|
let observer!: IntersectionObserver;
|
||||||
|
|
||||||
|
const ScrollSpyDirective: DirectiveOptions = {
|
||||||
|
bind (el: Element, binding: VNodeDirective , vnode: VNode) {
|
||||||
|
selectors = binding.value.selectors;
|
||||||
|
|
||||||
|
// highlight first element
|
||||||
|
el.querySelector(`[href="${location.hash || selectors[0] || ''}"]`)?.classList.toggle('active', true);
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
rootMargin: '-10% 0px -80% 0px',
|
||||||
|
threshold: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
observer = new IntersectionObserver((entries, observer) => {
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
selectors.forEach((selector: string) => {
|
||||||
|
el.querySelector(`[href="${selector}"`)?.classList.toggle('active', selector === `#${entry.target.id}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, config);
|
||||||
|
|
||||||
|
selectors.forEach((selector: string) => {
|
||||||
|
observer.observe(document.querySelector(selector) as Element);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
unbind () {
|
||||||
|
observer.disconnect();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ScrollSpyDirective;
|
Loading…
x
Reference in New Issue
Block a user