javascript - 滚动位置到达屏幕中的元素位置时如何显示和过渡?

标签 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 和 RowThree 在视口(viewport)中显示时,我想分别对其进行显示和动画处理。就像在 Laracasts website ,当滚动位置到达元素偏移量时,元素出现并动画。是否可以使用 Vue.js 和 javascript?

最佳答案

这里是如何使用指令来实现的。

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
  }  
})

当元素在视口(viewport)中可见时,您需要将 v-vpshow 指令添加到要设置动画的元素。

例如:

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

这个指令使用了两个类。

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

2) enter:这个应该包含当元素变得可见时你想要应用的过渡。

v-vpshow 将在元素在视口(viewport)中变得可见(触发动画后)后自动解除绑定(bind),删除在 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>

关于javascript - 滚动位置到达屏幕中的元素位置时如何显示和过渡?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45257308/

相关文章:

javascript - Facebook Canvas : Refused to display app in a frame because it set 'X-Frame-Options' to 'DENY'

javascript - Vue 2.6 在 Safari IOS 上无法正常工作

vue.js - 如何将带有 Jest 的 Vue Test Utils 添加到现有的 Vue-CLI 3 项目中?

Vue.js、Vuex、Vue-Router SPA 以及扩展应用程序客户端与服务器端

javascript - d3 js .append ("line") 没有出现

javascript - 如何在 KeystoneJS 中以编程方式从页面添加项目

webpack - 将 sass-resources-loader 与 vue-cli v3.x 一起使用

vue.js - "[Vue warn]: Unknown custom element: ..."错误,将 vuetify UI 组件与 vue-cli-plugin-vuetify 一起使用时

vue.js - 如何在 vuex Action 上使用 setTimeout?

javascript - 如何在 react 中返回单击元素的属性?