If you want to achieve this using a directive
, here is how:
Vue.directive('vpshow', {
inViewport (el) {
var rect = el.getBoundingClientRect()
return !(rect.bottom < 0 || rect.right < 0 ||
rect.left > window.innerWidth ||
rect.top > window.innerHeight)
},
bind(el, binding) {
el.classList.add('before-enter')
el.$onScroll = function() {
if (binding.def.inViewport(el)) {
el.classList.add('enter')
el.classList.remove('before-enter')
binding.def.unbind(el, binding)
}
}
document.addEventListener('scroll', el.$onScroll)
},
inserted(el, binding) {
el.$onScroll()
},
unbind(el, binding) {
document.removeEventListener('scroll', el.$onScroll)
delete el.$onScroll
}
})
To make elements animate when they come into view, add the v-vpshow
directive to those elements.
For instance:
<div class="row" id="RowOne" v-vpshow>...</div>
This directive works with two classes:
1) before-enter
: hides the element by default and is added automatically upon binding.
2) enter
: should contain the transition for when the element becomes visible.
v-vpshow
will automatically unbind itself once the element is visible, removing any data or event listeners set during bind
.
Here's a live demo:
Vue.directive('vpshow', {
inViewport (el) {
var rect = el.getBoundingClientRect()
return !(rect.bottom < 0 || rect.right < 0 ||
rect.left > window.innerWidth ||
rect.top > window.innerHeight)
},
bind(el, binding) {
el.classList.add('before-enter')
el.$onScroll = function() {
if (binding.def.inViewport(el)) {
el.classList.add('enter')
el.classList.remove('before-enter')
binding.def.unbind(el, binding)
}
}
document.addEventListener('scroll', el.$onScroll)
},
inserted(el, binding) {
el.$onScroll()
},
unbind(el, binding) {
document.removeEventListener('scroll', el.$onScroll)
delete el.$onScroll
}
})
new Vue({
el: '#app',
})
/* v-vpshow classes */
.before-enter {
opacity: 0;
}
.enter {
transition: opacity 2s ease;
}
/* ---------------- */
.row {
display: flex;
min-height: 500px;
justify-content: center;
font-size: 20px;
font-family: tahoma;
}
#RowOne {
background-color: yellow;
}
#RowTwo {
background-color: #5D576B;
}
#RowThree {
background-color: #F7567C;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
<div id="Test">
<div class="row" id="RowOne" v-vpshow>
<p>Lorem ipsum dolor sit amet, consectetur.</p>
</div>
<div class="row" id="RowTwo" v-vpshow>
<p>Lorem ipsum dolor sit amet, consectetur.</p>
</div>
<div class="row" id="RowThree" v-vpshow>
<p>Lorem ipsum dolor sit amet, tenetur!</p>
</div>
</div>
</div>