v-observe-visibility
by Guillaume Chau
HTML
<!-- Polyfill -->
<script src="https://unpkg.com/[email protected]"></script>
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]"></script>
<div id="app">
<div class="toolbar">
<div class="wrapper">
<input id="is-visible" type="checkbox" v-model="isVisible" disabled>
<label for="is-visible">Is visible?</label>
<span class="separator"></span>
<button @click="show = !show">Toggle</button>
<span class="separator"></span>
<label for="throttle">Throttle</label>
<input id="throttle" type="number" v-model="throttle" min="0" step="100">
<span class="separator"></span>
<label for="threshold">Threshold</label>
<span class="number">{{ threshold }}</span>
<input type="range" v-model="threshold" min="0" max="1" step="0.01">
</div>
</div>
<div class="info">Scroll down</div>
<div class="test-wrapper">
<div
v-show="show"
ref="test"
class="test"
v-observe-visibility="{
callback: visibilityChanged,
throttle,
intersection: {
threshold,
},
}"
>Hello world!</div>
</div>
</div>
CSS
body {
font-family: sans-serif;
}
#app {
padding: 100px;
}
.toolbar {
position: fixed;
bottom: 12px;
left: 0;
width: 100%;
}
.toolbar .wrapper {
background: white;
padding: 12px;
border-radius: 3px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.07);
display: flex;
align-items: center;
border: #eee 1px solid;
}
.toolbar .wrapper > *:not(:last-child) {
margin-right: 6px;
}
.separator {
margin: 0 12px;
}
.info {
color: #eee;
}
.test {
background: #eee;
height: 100%;
border-radius: 3px;
}
.info,
.test {
font-size: 42px;
}
.test-wrapper {
margin: 3000px 0;
height: 400px;
}
.toolbar,
.info,
.test {
display: flex;
align-items: center;
justify-content: center;
}
input[type="number"] {
width: 90px;
}
.number {
display: inline-block;
width: 40px;
font-family: monospace;
text-align: center;
background: #eee;
border-radius: 3px;
padding: 4px 0;
}
JavaScript
// App
new Vue({
el: '#app',
data: {
show: true,
isVisible: true,
throttle: 0,
threshold: 0,
},
methods: {
visibilityChanged: function (isVisible, entry) {
this.isVisible = isVisible
console.log(Math.round(entry.intersectionRatio * 100) + '%')
}
}
})