Something that follows scrolling in VueJS (using $refs)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div id="app"> | |
<ul class="trails"> | |
<li class="trail"> | |
<div class="caption" :class="sectionsClasses.section_1">El 1</div> | |
</li> | |
<li class="trail"> | |
<div class="caption" :class="sectionsClasses.section_2">El 2</div> | |
</li> | |
<li class="trail"> | |
<div class="caption" :class="sectionsClasses.section_3">El 3</div> | |
</li> | |
<li class="trail"> | |
<div class="caption" :class="sectionsClasses.section_4">El 4</div> | |
</li> | |
<li class="trail"> | |
<div class="caption" :class="sectionsClasses.section_5">El 5</div> | |
</li> | |
<li class="trail"> | |
<div class="caption" :class="sectionsClasses.section_6">El 6</div> | |
</li> | |
</ul> | |
<pre class="debug">{{sections}}{{sectionsClasses}}{{parentHeight}}</pre> | |
<div class="content"> | |
<div class="section" ref="section_1">Section 1</div> | |
<div class="section" ref="section_2">Section 2</div> | |
<div class="section section--small" ref="section_3">Section 3</div> | |
<div class="section" ref="section_4">Section 4</div> | |
<div class="section" ref="section_5">Section 5</div> | |
<div class="section" ref="section_6">{{img}}</div> | |
</div> | |
</div> | |
</template> | |
<script> | |
let img='' | |
export default { | |
name: 'app', | |
data () { | |
// Initialisation | |
let sections = {} | |
let sectionsClasses = {} | |
for (let i = 1; i < 7; i++) { | |
sections[`section_${i}`] = {} // section_x: {} | |
sectionsClasses[`section_${i}`] = 'hidden' // section_x: 'hidden' par défaut | |
} | |
return { | |
sections, | |
sectionsClasses, | |
parentHeight: 0, | |
} | |
}, | |
methods: { | |
// Définit les classes pour chaque section | |
setClasses () { | |
const page = document.body.getBoundingClientRect() | |
console.log(page) | |
const keys = Object.keys(this.sections) | |
for (let idx in keys) { | |
idx = parseInt(idx, 10) | |
let sizes = this.sections[keys[idx]] | |
let sectionClass = 'hidden' | |
let visible = { | |
top: sizes.top > 0 && sizes.top < this.parentHeight, | |
bottom: sizes.bottom > 0 && sizes.bottom < this.parentHeight, | |
} | |
if (visible.top && visible.bottom) { | |
sectionClass = 'visible' | |
} else if (visible.top || visible.bottom) { | |
sectionClass = 'partial' | |
} | |
this.sectionsClasses[keys[idx]] = sectionClass | |
} | |
}, | |
// Choppe les tailles dont on a besoin | |
getSizes () { | |
this.parentHeight = window.innerHeight | |
for (let idx in this.sections) { | |
this.sections[idx] = this.$refs[idx].getBoundingClientRect() | |
} | |
}, | |
// Choppe les tailles et définit les classes | |
setTrails () { | |
this.getSizes() | |
this.setClasses() | |
}, | |
}, | |
created () { | |
// On attend que le DOM soit bien créé | |
this.$nextTick(() => { | |
// On ajoute des event listeners | |
document.addEventListener('scroll', () => { this.setTrails() }) | |
window.addEventListener('resize', () => { this.setTrails() }) | |
// On calcule quand même une fois | |
this.setTrails() | |
}) | |
}, | |
} | |
</script> | |
<style lang="scss"> | |
$txt: #CCC; | |
$txt-visible: #8F8; | |
$txt-partial: #ff5a3b; | |
$bg: #333; | |
$bg2: transparentize($txt, .8); | |
* { | |
padding: 0; | |
margin: 0; | |
box-sizing: border-box; | |
} | |
body { | |
background-color: $bg; | |
color: $txt; | |
font-family: sans-serif; | |
padding: 15px; | |
} | |
#app { | |
.trails { | |
list-style-type: none; | |
width: 200px; | |
background-color: $bg2; | |
position: fixed; | |
.trail { | |
padding: 15px; | |
/*margin: 90px 0;*/ | |
.caption { | |
background-color: $bg2; | |
display: block; | |
&.visible { | |
font-weight: bold; | |
color: $txt-visible | |
} | |
&.partial { | |
font-weight: bold; | |
color: $txt-partial | |
} | |
} | |
} | |
} | |
.content { | |
margin-left: 215px; | |
margin-right: 215px; | |
.section { | |
margin: 30px 0; | |
background-color: $bg2; | |
min-height: 500px; | |
font-size: 3em; | |
&:first-child { | |
margin-top: 0 | |
} | |
&:last-child { | |
margin-bottom: 0 | |
} | |
&--small { | |
min-height: 200px; | |
} | |
} | |
} | |
.debug { | |
position: fixed; | |
right: 15px; | |
width: 200px; | |
background-color: $bg2; | |
font-size: .8em; | |
} | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment