整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

使用React和CSS淡入淡出加载图片:快速指南

eb开发人员和MVB展示了他如何在React中创建一个组件,使您可以使用CSS和React淡入缓存加载的图像。

假设你想在你的网站上加载一些图片。你不希望他们只是弹出存在,吓倒用户。效果很好,效果更好。

这是问题:没有好的预制React组件。或者我吮吸找到它。

有一个react-lazyload,它为你做了一个懒惰的加载部分。它使组件不会挂载到DOM中,直到用户真正看到它们。

这有助于加快您的网站加载速度。用户不需要加载大图像,直到用户可以看到它们。

但是,默认的体验可能会令人震惊。当图像最终加载时,他们只是弹出视图。

react-lazyload提供了一个淡入的例子,但它已经过时了,不适用于现代图书馆。而且使用起来很麻烦。

所以我建立了一个通用FadeIn组件。我会开放它,但它需要一些波兰首先,我希望你的意见,如何做得更好。

该组件只有40行代码。很简单。

class FadeIn extends React.Component {

state = {

loaded: false ,

} ;

onLoad = ( ) => this.setState ( { loaded: true } ) ;

render( ) {

const { height, children } = this.props ,

{ loaded } = this.state ;

return (

<LazyLoad height= {height} offset= { 150 } >

<Transition in = {loaded} timeout= {duration} >

{state =>

<div style= { { ...defaultStyle , ...transitionStyles [state] } } >

{children( this.onLoad ) }

</div> }

</Transition>

</LazyLoad>

) ;

}

}

FadeIn.propTypes = {

height: PropTypes.number ,

children: PropTypes.func ,

} ;

FadeIn保持本地loaded状态以跟踪显示内容。

false意思是“保持透明”,

true意思是“完全不透明”。

它使用react-lazyload的LazyLoad组件来处理延迟加载的部分,并且Transition从react-transition-group来驱动CSS渐变来淡入。这是自正式的淡入淡出的例子以来改变了很多的部分。

使用儿童渲染功能的方法,你可以要求FadeIn渲染任何你想要的。它被包装在处理淡入淡出效果的div中。

所有你需要做的就是触发onLoad回调,一旦你的内容准备就绪。当你的图像完成加载例如。

你渲染<FadeIn>,给它一个高度,所以事情不会跳来跳去,并通过一个onLoad回调的儿童功能。当您准备好触发转换时,您可以调用onLoad并FadeIn执行它的操作。

你知道onLoad所有的浏览器支持一个内置的DOM回调吗?我不知道。

onLoad是非常重要的,因为如果没有它,FadeIn过渡可能会在图像甚至落入管道之前结束。这是我面临的第一个问题,当我livecoded此。

建议?

我想开源这个。我知道这很简单,但是可以为他们节省一个小时的时间。这是值得的,对吧?

还有什么需要做的?我应该怎样命名呢?你会用它吗?

章节我们主要介绍 Vue.js 的过渡效果与动画效果。包括如何编写自定义 CSS 动画、如何配合第三方 CSS 动画库、过渡钩子函数的使用、如何使用第三方 JavaScript 动画库。本小节的内容相对之前有些难度,同学们在阅读一遍之后如果不能完全掌握,建议反复阅读,并把本小节的所有案例自己实现一遍,相信通过多次的练习一定可以掌握。

1. 过渡

Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。 包括以下工具: 1、在 CSS 过渡和动画中自动应用 class; 2、配合使用第三方 CSS 动画库,如 Animate.css; 3、在过渡钩子函数中使用 JavaScript 直接操作 DOM; 4、配合使用第三方 JavaScript 动画库,如 Velocity.js。

语法格式:

使用 transition 组件包裹需要使用过渡效果的 DOM 元素。例如:

    <transition name = "transition-name">
      <div>...</div>
    </transition>

1.1 基本使用

接下来让我们先看一个淡入淡出效果的实现代码:

实例演示

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .fade-enter-active, .fade-leave-active {
      transition: opacity 3s
    }
    .fade-enter, .fade-leave-to {
      opacity: 0
    }
  </style>
</head>
<body>
  <div id = "app">
    <button v-on:click = "show = !show">{{ show ? '隐藏' : '显示'}}</button>
    <transition name="fade">
      <p v-show = "show" >hello !</p>
    </transition>
  </div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type = "text/javascript">
  var vm = new Vue({
    el: '#app',
    data: {
        show:true
    },
    methods : {
    }
  });
</script>
</html>

12345678910111213141516171819202122232425262728293031323334353637

运行案例点击 "运行案例" 可查看在线运行效果

代码解释:

  1. HTML 代码第 3-5 行,我们使用 transition 组件包裹 <p> 标签,transition 组件指定 name 为 fade,通过 指令 v-show 控制 <p> 标签的显示和隐藏;
  2. HTML 代码第 2 行,定义按钮 button,点击修改 show 的值来控制标签 <p> 的显示隐藏;
  3. CSS 中我们定义了 4 个样式;
  4. JS 代码第 6 行,定义数据 show,默认值为 true。

那么,transition 组件是如何做到这样的过渡效果的呢?

我想,同学们肯定猜想到当元素切换状态的时候,我们定义的样式会作用于标签元素 <p>。那么,到底是不是这样呢?

打开控制台,检索到 <p> 标签上,我们可以清晰地看到:

  1. 当元素隐藏的时候,样式 fade-leave-active 和 fade-leave-to 会被添加到元素 <p> 上;
  2. 当元素显示的时候,样式 fade-enter-active 和 fade-enter-to 会被添加到元素 <p> 上。

实际上 Vue 在元素显示与隐藏的过渡中,提供了 6 个 class 来切换:

  • v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除;
  • v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡 / 动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数;
  • v-enter-to: 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡 / 动画完成之后移除。
  • v-leave: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除;
  • v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡 / 动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数;
  • v-leave-to: 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡 / 动画完成之后移除。

对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 <transition>,则 v- 是这些类名的默认前缀。如果你使用了 <transition name="test-transition">,那么 v 会替换为 test-transition。例如:test-transition-enter、test-transition-enter-active、test-transition-leave…

1.2 CSS 过渡

在日常开发中,我们经常会使用 CSS 过渡来实现一些简单的动画效果。接下来我们用一个示例来学习如何使用:

实例演示

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .fade-enter-active {
      transition: all .3s ease;
    }
    .fade-leave-active {
      transition: all .3s cubic-bezier(1.0, 0.5, 0.8, 1.0);
    }
    .fade-enter, .fade-leave-to {
      transform: translateY(10px);
      opacity: 0;
    }
  </style>
</head>
<body>
  <div id = "app">
    <button v-on:click = "show = !show">{{ show ? '显示' : '隐藏'}}</button>
    <transition name = "fade">
      <p v-show = "show" >Hello !</p>
    </transition>
  </div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type = "text/javascript">
  var vm = new Vue({
    el: '#app',
    data: {
      show:true
    }
  });
</script>
</html>

"运行案例" 可查看在线运行效果

代码解释:

  1. HTML 代码第 3-5 行,我们使用 transition 组件包裹 <p> 标签,transition 组件指定 name 为 fade,通过 指令 v-show 控制 <p> 标签的显示和隐藏;
  2. HTML 代码第 2 行,定义按钮 button,点击修改 show 的值来控制标签 <p> 的显示隐藏;
  3. CSS 中我们定义了 4 个样式,通过 transform 控制元素的垂直位移,通过 opacity 控制元素的 透明度,通过 transition 控制元素的过渡效果;
  4. JS 代码第 6 行,定义数据 show,默认值为 true。

1.3 CSS 动画

同样,我们可以使用 CSS 动画来实现元素的过渡效果。CSS 动画用法类似 CSS 过渡,在过渡的不同阶段对应的 Class 会作用于元素。但是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。 相信同学们在日常业务开发中一定使用过 Dialog,接下来我们就使用 CSS 动画来实现它的过渡效果:

实例演示

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    #app{
      text-align: center;
    }
    .dialog{
      width: 100px;
      height: 100px;
      border: 1px solid #333;
      margin: 60px auto;
      text-align: center;
      line-height: 100px;
    }
    .bounce-enter-active {
      animation: bounce-in 400ms;
    }
    .bounce-leave-active {
      animation: bounce-out 300ms;
    }
    @keyframes bounce-in {
      0% {
        transform: scale(0.7);
      }
      50% {
        transform: scale(1.3);
      }
      100% {
        transform: scale(1);
      }
    }
    @keyframes bounce-out {
      0% {
        transform: scale(1);
      }
      100% {
        transform: scale(0.4);
      }
    }
  </style>
</head>
<body>
  <div id = "app">
    <button v-on:click = "show = !show">{{ show ? '显示 Dialog' : '隐藏 Dialog'}}</button>
    <transition name = "bounce">
      <p v-show = "show" class="dialog">Dialog...</p>
    </transition>
  </div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type = "text/javascript">
  var vm = new Vue({
    el: '#app',
    data: {
      show:false
    }
  });
</script>
</html>

"运行案例" 可查看在线运行效果

代码解释:

  1. HTML 代码第 3-5 行,我们使用 transition 组件包裹 <p> 标签,transition 组件指定 name 为 bounce 指令 v-show 控制 <p> 标签的显示和隐藏;
  2. HTML 代码第 2 行,定义按钮 button,点击修改 show 的值来控制标签 <p> 的显示隐藏;
  3. CSS 中我们定义了样式两个样式:元素入场样式: bounce-enter-active,它执行动画 bounce-in。元素出场样式: bounce-leave-active,它执行动画 bounce-out。
  4. JS 代码第 6 行,定义数据 show,初始值为 true。

1.4 自定义过渡的类名

在之前的两个案例中,我们通过给 transition 设置 name 属性来指定元素在不同阶段的样式类名,但有时候希望使用自定义的过渡类名,我们可以通过给 transition 设置以下属性来达到需求:

  • enter-class
  • enter-active-class
  • enter-to-class
  • leave-class
  • leave-active-class
  • leave-to-class

自定义过渡的类名优先级高于普通的类名,这样就能很好地与第三方(如:animate.css)的动画库结合使用。

1.5 显性的过渡持续时间

在很多情况下,Vue 可以自动得出过渡效果的完成时机。默认情况下,Vue 会等待其在过渡效果的根元素的第一个 transitionend 或 animationend 事件。然而也可以不这样设定 —— 比如,我们可以拥有一个精心编排的一系列过渡效果,其中一些嵌套的内部元素相比于过渡效果的根元素有延迟的或更长的过渡效果。

在这种情况下你可以用 组件上的 duration 属性定制一个显性的过渡持续时间 (以毫秒计):

<transition :duration="1000">...</transition>

你也可以定制进入和移出的持续时间:

<transition :duration="{ enter: 400, leave: 600 }">...</transition>

2. JavaScript 钩子

transition 组件在过渡的不同阶段会触发相应的钩子函数:

<transition 
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"
  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
  <p>...</p>
</transition>

这些钩子函数可以结合 CSS transitions/animations 使用,也可以单独使用。

当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。

推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css="false",Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。

接下来我们来看一个使用钩子函数和 Velocity.js 实现过渡动画的例子:

实例演示

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .hello{
      width: 100px;
      height: 100px;
      border: 1px solid red;
      margin: auto;
    }
  </style>
</head>
<body>
  <div id = "app">
    <button @click="show = !show">
      切换显示状态
    </button>
    <transition
      v-on:before-enter="beforeEnter"
      v-on:enter="enter"
      v-on:leave="leave"
      v-bind:css="false"
    >
      <p v-if="show">
        Demo
      </p>
    </transition>
  </div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type = "text/javascript">
  var vm = new Vue({
    el: '#app',
    data: {
      show:false
    },
    methods: {
      beforeEnter: function (el) {
        el.style.opacity = 0
        el.style.transformOrigin = 'left'
      },
      enter: function (el, done) {
        Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
        Velocity(el, { fontSize: '1em' }, { complete: done})
      },
      leave: function (el, done) {
        Velocity(el, { translateX: '20px', rotateZ: '45deg' }, { duration: 600 })
        Velocity(el, { rotateZ: '90deg' }, { loop: 3 })
        Velocity(el, {
          rotateZ: '45deg',
          translateY: '30px',
          translateX: '30px',
          opacity: 0
        }, { complete: done })
      }
    }
  });
</script>
</html>

"运行案例" 可查看在线运行效果

代码解释:

  1. HTML 代码第 3-12 行,我们使用 transition 组件包裹 <p> 标签,并给 transition 组件绑定监听事件 before-enter、enter、leave;
  2. HTML 代码第 2 行,定义按钮 button,点击修改 show 的值来控制标签 <p> 的显示隐藏;
  3. JS 代码第 7 行,定义数据 show,默认值为 false;
  4. JS 代码第 10-13 行,定义元素的 beforeEnter 函数,并修改元素的样式 style;
  5. JS 代码第 14-17 行,定义元素的 enter 函数,并执行以下操作:
  6. 使用 Velocity 修改元素的 opacity 和 fontSize,过渡时间为 300。
  7. 使用 Velocity 修改元素的 fontSize,并在完成时间调用 done 回调函数。
  8. JS 代码第 18-27 行,定义元素的 leave 函数,并执行以下操作:
  9. 使用 Velocity 修改元素的 translateX 和 rotateZ,过渡时间为 600。
  10. 使用 Velocity 修改元素的 rotateZ,并且循环 3 次。
  11. 使用 Velocity 修改元素的 rotateZ 、translateY、translateX、opacity,并在完成时间调用 done 回调函数。

3. 初始渲染的过渡

有时候我们希望给元素设置初始渲染的过渡效果,可以通过给 transition 设置 appear 的 attribute

<transition appear>
  <!-- ... -->
</transition>

这里默认和进入 / 离开过渡一样,同样也可以自定义 CSS 类名:

<transition
  appear
  appear-class="v-appear-class"
  appear-to-class="v-appear-to-class"
  appear-active-class="v-appear-active-class"
>
  <!-- ... -->
</transition>

同样地,可以使用自定义 JavaScript 钩子:

<transition
  appear
  v-on:before-appear="beforeAppear"
  v-on:appear="appear"
  v-on:after-appear="afterAppear"
  v-on:appear-cancelled="appearCancelled"
>
  <!-- ... -->
</transition>

接下来我们看一个完整的示例:

实例演示

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .hello{
      width: 100px;
      height: 100px;
      border: 1px solid red;
      margin: auto;
    }
    .v-appear-class{
      opacity: 0;
    }
    .v-appear-to-class{
      opacity: 1;
    }
    .v-appear-active-class{
      transition: all 2s;
    }

  </style>
</head>
<body>
  <div id = "app">
    <button v-on:click = "show = !show">隐藏</button>
    <transition 
      appear
      appear-class="v-appear-class"
      appear-to-class="v-appear-to-class"
      appear-active-class="v-appear-active-class"
      v-on:before-appear="beforeAppear"
      v-on:appear="appear"
      v-on:after-appear="afterAppear"
      v-on:appear-cancelled="appearCancelled"
    >
      <p v-show = "show" class="hello">Hello !</p>
    </transition>
  </div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type = "text/javascript">
  var vm = new Vue({
    el: '#app',
    data: {
      show:true
    },
    methods: {
      beforeAppear() {
        console.log('beforeAppear')
      },
      appear() {
        console.log('appear')
      },
      afterAppear() {
        console.log('afterAppear')
      },
      appearCancelled() {
        console.log('appearCancelled')
      },
    }
  });
</script>
</html>

"运行案例" 可查看在线运行效果

代码解释:

  1. HTML 代码第 3-14 行,我们使用 transition 组件包裹 <p> 标签,指定 transition 为初次渲染的过渡,并给 transition 组件绑定监听事件: before-appear、appear、after-appear、appear-cancelled;
  2. HTML 代码第 2 行,定义按钮 button,点击修改 show 的值来控制标签 <p> 的显示隐藏;
  3. JS 代码第 6 行,定义数据 show,默认值为 false。

4. 小结

本小节我们介绍了如何使用 transition 实现过渡和动画效果,主要包括以下知识点:

  • 使用 CSS 过渡配合 transition 实现过渡效果;
  • 使用 CSS 动画配合 transition 实现动画效果;
  • 使用 transition 钩子函数操作元素 DOM 来实现动画;
  • 使用 transition 的 appear 属性实现初次渲染的动画效果。

体思路:

1.实现页面布局,设置css样式

2.用jQuery获取需要用到的变量

3.用jQuery为两个按钮绑定事件

一.页面布局:

<div class="d1">
 //随便在网上找一张图片放入img中//
 <img src="https://dummyimage.com/900x400/0000ff/ff" alt="" class="c1 c2">
 <div class="d2">
 <input type="button" value="<-" id="b1">
 <input type="button" value="->" id="b2">
 </div>
</div>
 <style>
 body{
 margin: 0 0 0 0;
 height: 1000px;
 width: 100%;
 }
 .d1{
 position: absolute;
 width: 100%;
 height: 500px;
 top: 50%;
 margin-top: -250px;
 }
 .d2{
 margin-left: 950px;
 }
 .d1 img{
 margin-left: 50px;
 position: relative;
 }
 .c1{
 display: block;
 padding-left: 500px;
 }
 </style>

我的css布局仅仅做了居中,各位可以做的更加美观性

二.jQuery获取需要用到的变量

 //imgList中放入你要加入的图片,记得要加入在div中定义的起始图片//
var imgList=['https://dummyimage.com/900x400/0000ff/ff','https://dummyimage.com/900x400/00/ff','https://dummyimage.com/900x400/ff0000/ff'];
 var $imgEle=$('img');//获取div中的img
 var nowSrc=imgList.indexOf($imgEle[0].src);//获取起始图片的索引值,后面函数要用到
//获取两个按钮
 var $b1Ele=$('#b1');
 var $b2Ele=$('#b2');

三.用jQuery为两个按钮绑定事件

首先写$b1El1的函数:

function f1(){
 //先让当前图片淡出,时间为0.5毫秒
 $imgEle.fadeOut(500);
 //进行判断,如果索引值为0,让索引变成列表的最大值
 if(nowSrc===0){
 nowSrc=imgList.length-1;
 }
 //索引值不为0,进行--
 else {
 nowSrc--;
 }
 //因为我淡出的时间设置为0.5毫秒,所以我设置计时器,让下面的代码0.5毫秒后启动
 t=setTimeout(function () {
 //更换图片的src
 $imgEle.attr('src',imgList[nowSrc]);
 //图片淡入,时间为0.5毫秒
 $imgEle.fadeIn(500);
 },500);
 }

为$b1El1绑定函数:

$b1Ele.on('click',f1);

同理可以写出按钮2的函数,并进行绑定

 function f2(){
 $imgEle.fadeOut(500);
 console.log(nowSrc);
 if(nowSrc===imgList.length-1){
 nowSrc=0;
 }
 else {
 nowSrc++;
 }
 t2=setTimeout(function () {
 $imgEle.attr('src',imgList[nowSrc]);
 $imgEle.fadeIn(500);
 },500);
 t2=null
 }
 $b2Ele.on('click',f2);

下面是整体代码: