Skip to content

Instantly share code, notes, and snippets.

@mtancoigne
Created September 26, 2018 20:18
Show Gist options
  • Save mtancoigne/c817e4faf31efc6739444e1d219ff435 to your computer and use it in GitHub Desktop.
Save mtancoigne/c817e4faf31efc6739444e1d219ff435 to your computer and use it in GitHub Desktop.
Something that follows scrolling in VueJS (using $refs)
<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