当滚动位置到达屏幕中的元素位置时如何显示和转换?

时间:2017-07-22 17:21:41

标签: javascript vue.js vuejs2

假设这是我的模板:

<template>
    <div id="Test">
        <transition name="fade">
            <div class="row" id="RowOne">
                <p>Lorem ipsum dolor odit qui sit?</p>
            </div>
        </transition>
        <transition name="fade">
            <div class="row" id="RowTwo">
                <p>Lorem ipsum dolor sit amet, consectetur.</p>
            </div>
        </transition>
        <transition name="fade">
            <div class="row" id="RowThree">
                <p>Lorem ipsum dolor sit amet, tenetur!</p>
            </div>
        </transition>
    </div>
</template>

我想分别在视口中显示的RowOne, RowTwo and RowThree显示和动画。就像在Laracasts website中一样,当滚动位置到达元素偏移时,元素会出现并生成动画。是否可以使用Vue.js和javascript?

2 个答案:

答案 0 :(得分:12)

以下是使用directive

执行此操作的方法
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
  }  
})

当您在视口中显示动画时,您需要将v-vpshow指令添加到要动画的元素。

例如:

<div class="row" id="RowOne" v-vpshow>...</div>

该指令使用两个类。

1)before-enter:它默认隐藏元素,并在指令绑定到元素时自动添加。

2)enter:此元素应包含元素变为可见时要应用的转换。

一旦元素在视口中变得可见(触发动画之后),

v-vpshow将自动解除绑定,从而删除bind上设置的任何数据和事件侦听器。

以下是一个有效的例子。

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>

答案 1 :(得分:0)

是的,它应该是。当您检测到用户已滚动一定距离时,您只需将display属性从none设置为可见的内容。

这是另一个问题,答案可以帮助您实现: Show div on scrollDown after 800px