我的编程空间,编程开发者的网络收藏夹
学习永远不晚

React中怎么实现常见的动画

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

React中怎么实现常见的动画

这篇文章主要介绍React中怎么实现常见的动画,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

现在,用户对于前端页面的要求已经不能满足于实现功能,更要有颜值,有趣味。除了整体 UI 的美观,在合适的地方添加合适的动画效果往往比静态页面更具有表现力,达到更自然的效果。比如,一个简单的 loading 动画或者页面切换效果不仅能缓解用户的等待情绪,甚至通过使用品牌 logo 等形式,默默达到品牌宣传的效果。

React 作为最近几年比较流行的前端开发框架,提出了虚拟 DOM 概念,所有 DOM 的变化都先发生在虚拟 DOM 上,通过 DOM diff 来分析网页的实际变化,然后反映在真实 DOM 上,从而极大地提升网页性能。然而,在动画实现方面,React 作为框架并不会直接给组件提供动画效果,需要开发者自行实现,而传统 web 动画大多数都通过直接操作实际 DOM 元素来实现,这在 React 中显然是不被提倡的。那么,在 React 中动画都是如何实现的呢?

所有动画的本质都是连续修改 DOM 元素的一个或者多个属性,使其产生连贯的变化效果,从而形成动画。在 React 中实现动画本质上与传统 web 动画一样,仍然是两种方式: 通过 css3 动画实现和通过 js 修改元素属性。只不过在具体实现时,要更为符合 React 的框架特性,可以概括为几类:

  1. 基于定时器或 requestAnimationFrame(RAF) 的间隔动画;

  2. 基于 css3 的简单动画;

  3. React 动画插件 CssTransitionGroup;

  4. 结合 hook 实现复杂动画;

  5. 其他第三方动画库。

一、基于定时器或 RAF 的间隔动画

最早,动画的实现都是依靠定时器 setIntervalsetTimeout 或者 requestAnimationFrame (RAF) 直接修改 DOM 元素的属性。不熟悉 React 特性的开发者可能会习惯性地通过 ref 或者 findDOMNode() 获取真实的 DOM 节点,直接修改其样式。然而,通过 ref 直接获取真实 DOM 并对其操作是是不被提倡使用,应当尽量避免这种操作。

因此,我们需要将定时器或者 RAF 等方法与 DOM 节点属性通过 state 联系起来。首先,需要提取出与变化样式相关的属性,替换为 state ,然后在合适的生命周期函数中添加定时器或者 requestAnimationFrame 不断修改 state ,触发组件更新,从而实现动画效果。

示例

以一个进度条为例,代码如下所示:

// 使用requestAnimationFrame改变state
import React, { Component } from 'react';

export default class Progress extends Component { 
  constructor(props) {
    super(props);
    this.state = {
      percent: 10
    };
  }

  increase = () => {
    const percent = this.state.percent;
    const targetPercent = percent >= 90 ? 100 : percent + 10;
    const speed = (targetPercent - percent) / 400;
    let start = null;
    const animate = timestamp => {
      if (!start) start = timestamp;
      const progress = timestamp - start;
      const currentProgress = Math.min(parseInt(speed * progress + percent, 10), targetPercent);
      this.setState({
        percent: currentProgress
      });
      if (currentProgress < targetPercent) {
        window.requestAnimationFrame(animate);
      }
    };
    window.requestAnimationFrame(animate);
  }

  decrease = () => {
    const percent = this.state.percent;
    const targetPercent = percent < 10 ? 0 : percent - 10;
    const speed = (percent - targetPercent) / 400;
    let start = null;
    const animate = timestamp => {
      if (!start) start = timestamp;
      const progress = timestamp - start;
      const currentProgress = Math.max(parseInt(percent - speed * progress, 10), targetPercent);
      this.setState({
          percent: currentProgress
        });
      if (currentProgress > targetPercent) {
        window.requestAnimationFrame(animate);
      }
    };
    window.requestAnimationFrame(animate);
  }

  render() {
    const { percent } = this.state;

    return (
      <div>
        <div className="progress">
          <div className="progress-wrapper" >
            <div className="progress-inner" style = {{width: `${percent}%`}} ></div>
          </div>
          <div className="progress-info" >{percent}%</div>
        </div>
        <div className="btns">
          <button onClick={this.decrease}>-</button>
          <button onClick={this.increase}>+</button>
        </div>
      </div>
    );
  }
}

在示例中,我们在 increasedecrease 函数中构建线性过渡函数 animationrequestAnimationFrame 在浏览器每次重绘前执行会执行过渡函数,计算当前进度条 width 属性并更新该 state ,使得进度条重新渲染。该示例的效果如下所示:

React中怎么实现常见的动画

这种实现方式在使用 requestAnimationFrame 时性能不错,完全使用纯 js 实现,不依赖于 css,使用定时器时可能出现掉帧卡顿现象。此外,还需要开发者根据速度函数自己计算状态,比较复杂。

二、基于 css3 的简单动画

当 css3 中的 animationtransition 出现和普及后,我们可以轻松地利用 css 实现元素样式的变化,而不用通过人为计算实时样式。

示例

我们仍以上面的进度条为例,使用 css3 实现进度条动态效果,代码如下所示:

import React, { Component } from 'react';

export default class Progress extends Component { 
  constructor(props) {
    super(props);
    this.state = {
      percent: 10
    };
  }

  increase = () => {
    const percent = this.state.percent + 10;
    this.setState({
      percent: percent > 100 ? 100 : percent,
    })
  }

  decrease = () => {
    const percent = this.state.percent - 10;
    this.setState({
      percent: percent < 0 ? 0 : percent,
    })
  }

  render() {
    // 同上例, 省略
    ....
  }
}
.progress-inner {
 transition: width 400ms cubic-bezier(0.08, 0.82, 0.17, 1);
 // 其他样式同上,省略
 ...
}

在示例中, increasedecrease 函数中不再计算 width ,而是直接设置增减后的宽度。需要注意的是,在 css 样式中设置了 transition 属性,该属性在其指定的 transition-property 发生变化时自动实现样式的动态变化效果,并且可以设置不同的速度效果的速度曲线。该示例的效果如下图所示,可以发现,与上一个例子不同的是,右侧的进度数据是直接变化为目标数字,没有具体的变化过程,而进度条的动态效果因为不再是线性变化,效果更为生动。

React中怎么实现常见的动画

基于 css3 的实现方式具有较高的性能,代码量少,但是只能依赖于 css 效果,对于复杂动画也很难实现。此外,通过修改 state 实现动画效果,只能作用于已经存在于 DOM 树中的节点。如果想用这种方式为组件添加入场和离场动画,需要维持至少两个 state 来实现入场和离场动画,其中一个 state 用于控制元素是否显示,另一个 state 用于控制元素在动画中的变化属性。在这种情况下,开发者需要花费大量精力来维护组件的动画逻辑,十分复杂繁琐。

三、React 动画插件 CssTransitionGroup

React 曾为开发者提供过动画插件 react-addons-css-transition-group ,后交由社区维护,形成现在的 react-transition-group ,该插件可以方便地实现组件的入场和离场动画,使用时需要开发者额外安装。 react-transition-group 包含 CSSTransitionGroupTransitionGroup 两个动画插件,其中,后者是底层 api,前者是后者的进一步封装,可以较为便捷地实现 css 动画。

示例

以一个动态增加tab的为例,代码如下:

import React, { Component } from 'react'; 
import { CSSTransitionGroup } from 'react-transition-group';

let uid = 2; 
export default class Tabs extends Component { 
  constructor(props) {
    super(props);
    this.state = {
      activeId: 1,
      tabData: [{
        id: 1,
        panel: '选项1'
      }, {
        id: 2,
        panel: '选项2'
      }]
    };
  }

  addTab = () => {
    // 添加tab代码
    ...
  }

  deleteTab = (id) => {
    // 删除tab代码
    ...
  }

  render() {
    const { tabData, activeId } = this.state;

    const renderTabs = () => {
      return tabData.map((item, index) => {
        return (
          <div
            className={`tab-item${item.id === activeId ? ' tab-item-active' : ''}`}
            key={`tab${item.id}`}
          >
            {item.panel}
            <span className="btns btn-delete" onClick={() => this.deleteTab(item.id)}>✕</span>
          </div>
        );
      })
    }

    return (
      <div>
        <div className="tabs" >
          <CSSTransitionGroup
           transitionName="tabs-wrap"
           transitionEnterTimeout={500}
           transitionLeaveTimeout={500}
          >
           {renderTabs()}
          </CSSTransitionGroup>
          <span className="btns btn-add" onClick={this.addTab}>+</span>
        </div>
        <div className="tab-cont">
          cont
        </div>
      </div>
    );
  }
}

.tabs-wrap-enter {
 opacity: 0.01;
}

.tabs-wrap-enter.tabs-wrap-enter-active {
 opacity: 1;
 transition: all 500ms ease-in;
}

.tabs-wrap-leave {
 opacity: 1;
}

.tabs-wrap-leave.tabs-wrap-leave-active {
 opacity: 0.01;
 transition: all 500ms ease-in;
}

CSSTransitionGroup 可以为其子节点添加额外的 css 类,然后通过 css 动画达到入场和离场动画效果。为了给每个 tab 节点添加动画效果,需要先将它们包裹在 CSSTransitionGroup 组件中。 当设定 transitionName 属性为 'tabs-wrapper'transitionEnterTimeout 为400毫秒后,一旦 CSSTransitionGroup 中新增节点,该新增节点会在出现时被添加上 css 类 'tabs-wrapper-enter' ,然后在下一帧时被添加上 css 类 'tabs-wrapper-enter-active' 。由于这两个 css 类中设定了不同的透明度和 css3 transition 属性,所以节点实现了透明度由小到大的入场效果。400毫秒后 css 类 'tabs-wrapper-enter''tabs-wrapper-enter-active' 将会同时被移除,节点完成整个入场动画过程。离场动画的实现类似于入场动画,只不过被添加的 css 类名为 'tabs-wrapper-leave''tabs-wrapper-leave-active' 。该示例效果如下图所示:

React中怎么实现常见的动画

CSSTransitionGroup 支持以下7个属性:

React中怎么实现常见的动画

其中,入场和离场动画是默认开启的,使用时需要设置 transitionEnterTimeouttransitionLeaveTimeout 。值得注意的是, CSSTransitionGroup 还提供出现动画(appear),使用时需要设置 transitionAppearTimeout 。那么,出现动画和入场动画有什么区别呢?当设定 transitionAppeartrue 时, CSSTransitionGroup初次渲染 时,会添加一个出现阶段。在该阶段中, CSSTransitionGroup 的已有子节点都会被相继添加 css 类 'tabs-wrapper-appear''tabs-wrapper-appear-active' ,实现出现动画效果。因此, 出现动画仅适用于 CSSTransitionGroup 在初次渲染时就存在的子节点 ,一旦 CSSTransitionGroup 完成渲染,其子节点就只可能有入场动画(enter),不可能有出现动画(appear)。

此外,使用 CSSTransitionGroup 需要注意以下几点:

  1. CSSTransitionGroup 默认在 DOM 树中生成一个 span 标签包裹其子节点,如果想要使用其他 html 标签,可设定 CSSTransitionGroupcomponent 属性;

  2. CSSTransitionGroup 的子元素必须添加 key 值才会在节点发生变化时,准确地计算出哪些节点需要添加入场动画,哪些节点需要添加离场动画;

  3. CSSTransitionGroup 的动画效果只作用于直接子节点,不作用于其孙子节点;

  4. 动画的结束时间不以 css 中 transition-duration 为准,而是以 transitionEnterTimeouttransitionLeaveTimeoutTransitionAppearTimeout 为准,因为某些情况下 transitionend 事件不会被触发,详见 MDN transitionend 。

CSSTransitionGroup 实现动画的优点是:

  1. 简单易用,可以方便快捷地实现元素的入场和离场动画;

  2. 与 React 结合,性能比较好。

CSSTransitionGroup 缺点也十分明显:

  1. 局限于出现动画,入场动画和离场动画;

  2. 由于需要制定 transitionName ,灵活性不够;

  3. 只能依靠 css 实现简单的动画。

四、结合 hook 实现复杂动画

在实际项目中,可能需要一些更炫酷的动画效果,这些效果仅依赖于 css3 往往较难实现。此时,我们不妨借助一些成熟的第三方库,如 jQuery 或 GASP,结合 React 组件中的生命周期钩子方法 hook 函数,实现复杂动画效果。除了 React 组件正常的生命周期外, CSSTransitionGroup 的底层 api TransitonGroup 还为其子元素额外提供了一系列特殊的生命周期 hook 函数,在这些 hook 函数中结合第三方动画库可以实现丰富的入场、离场动画效果。

TransisitonGroup 分别提供一下六个生命周期 hook 函数:

  1. componentWillAppear(callback)

  2. componentDidAppear()

  3. componentWillEnter(callback)

  4. componentDidEnter()

  5. componentWillLeave(callback)

  6. componentDidLeave()

它们的触发时机如图所示:

React中怎么实现常见的动画

示例

GASP 是一个 flash 时代发展至今的动画库,借鉴视频帧的概念,特别适合做长时间的序列动画效果。本文中,我们用 TransitonGroupreact-gsap-enhancer (一个可以将 GSAP 应用于 React 的增强库)完成一个图片画廊,代码如下:

import React, { Component } from 'react'; 
import { TransitionGroup } from 'react-transition-group'; 
import GSAP from 'react-gsap-enhancer' 
import { TimelineMax, Back, Sine } from 'gsap';

class Photo extends Component { 
  constructor(props) {
    super(props);
  }

  componentWillEnter(callback) {
    this.addAnimation(this.enterAnim, {callback: callback})
  }

  componentWillLeave(callback) {
    this.addAnimation(this.leaveAnim, {callback: callback})
  }

  enterAnim = (utils) => {
    const { id } = this.props;
    return new TimelineMax()
      .from(utils.target, 1, {
        x: `+=${( 4 - id ) * 60}px`,
        autoAlpha: 0,
        onComplete: utils.options.callback,
      }, id * 0.7);
  }

  leaveAnim = (utils) => {
    const { id } = this.props;
    return new TimelineMax()
      .to(utils.target, 0.5, {
        scale: 0,
        ease: Sine.easeOut,
        onComplete: utils.options.callback,
      }, (4 - id) * 0.7);
  }

  render() {
    const { url } = this.props;
    return (
      <div className="photo">
        <img class="lazy" data-src={url} />
      </div>
    )
  }
}

const WrappedPhoto = GSAP()(Photo);

export default class Gallery extends Component { 
  constructor(props) {
    super(props);
    this.state = {
      show: false,
      photos: [{
        id: 1,
        url: 'http://img4.imgtn.bdimg.com/it/u=1032683424,3204785822&fm=214&gp=0.jpg'
      }, {
        id: 2,
        url: 'http://imgtu.5011.net/uploads/content/20170323/7488001490262119.jpg'
      }, {
        id: 3,
        url: 'http://tupian.enterdesk.com/2014/lxy/2014/12/03/18/10.jpg'
      }, {
        id: 4,
        url: 'http://img4.imgtn.bdimg.com/it/u=360498760,1598118672&fm=27&gp=0.jpg'
      }]
    };
  }

  toggle = () => {
    this.setState({
      show: !this.state.show
    })
  }

  render() {
    const { show, photos } = this.state;

    const renderPhotos = () => {
      return photos.map((item, index) => {
        return <WrappedPhoto id={item.id} url={item.url} key={`photo${item.id}`} />;
      })
    }

    return (
      <div>
        <button onClick={this.toggle}>toggle</button>
        <TransitionGroup component="div">
          {show && renderPhotos()}
        </TransitionGroup>
      </div>
    );
  }
}

在该示例中,我们在子组件 PhotocomponentWillEntercomponentWillLeave 两个 hook 函数中为每个子组件添加了入场动画 enterAnim 和 离场动画 LeaveAnim 。在入场动画中,使用 TimeLineMax.from(target, duration, vars, delay) 方式建立时间轴动画,指定了每个子组件的动画移动距离随 id 增大而减小,延期时间随着 id 增大而增大,离场动画中每个子组件的延期时间随着 id 增大而减小,从而实现根据组件 id 不同具有不同的动画效果。实际使用时,你可以根据需求对任一子组件添加不同的效果。该示例的效果如下图所示:

React中怎么实现常见的动画

在使用 TransitionGroup 时,在 componentnWillAppear(callback)componentnWillEntercallback)componentnWillLeave(callback) 函数中一定要 在函数逻辑结束后调用 callback ,以保证 TransitionGroup 能正确维护子节点的状态序列 。

结合 hook 实现动画可以支持各种复杂动画,如时间序列动画等,由于依赖第三方库,往往动画效果比较流畅,用户体验较好。但是第三方库的引入,需要开发者额外学习对应的 api,也提升了代码复杂度。

五、其他第三方动画库

此外,还有很多优秀的第三方动画库,如 react-motion ,Animated, velocity-react 等,这些动画库在使用时也各有千秋。

Animated

Animated 是一个跨平台的动画库,兼容 React 和 React Native。由于在动画过程中,我们只关心动画的初始状态、结束状态和变化函数,并不关心每个时刻元素属性的具体值,所以 Animatied 采用声明式的动画,通过它提供的特定方法计算 css 对象,并传入 Animated.div 实现动画效果。

示例

我们使用 Animated 实现一个图片翻转的效果,代码如下。

import React, { Component } from 'react'; 
import Animated from 'animated/lib/targets/react-dom';

export default class PhotoPreview extends Component { 
  constructor(props) {
    super(props);
    this.state = {
      anim: new Animated.Value(0)
    };
  }

  handleClick = () => {
    const { anim } = this.state;
    anim.stopAnimation(value => {
      Animated.spring(anim, {
        toValue: Math.round(value) + 1
      }).start();
    });
  }

  render() {
    const { anim } = this.state;

    const rotateDegree = anim.interpolate({
      inputRange: [0, 4],
      outputRange: ['0deg', '360deg']
    });

    return (
      <div>
        <button onClick={this.handleClick}>向右翻转</button>
        <Animated.div
          style={{
            transform: [{
              rotate: rotateDegree
            }]
          }}
          className="preivew-wrapper"
        >
          <img
            alt="img"
            class="lazy" data-src="http://img4.imgtn.bdimg.com/it/u=1032683424,3204785822&fm=214&gp=0.jpg"
          />
        </Animated.div>
      </div>
    );
  }
}

在该示例中,我们希望实现每点击一次按钮,图片向右旋转90°。在组件初始化时新建了一个初始值为 0 的 Animated 对象 this.state.anim ,在 render 函数中通过插值函数 interpolate 根据 Animated 对象的当前值计算得到对应的旋转角度 rotateDegree 。我们假设每点击一次按钮, Animated 对象的值加 1,相应地图像转动90°,所以,设置 interpolate 函数的输入区间为[0, 4],输出区间为['0deg', '360deg']进行线性插值。如果 Animated 对象当前值为 2,对应的旋转角度就是 180deg。在组件渲染结构中,需要使用 Animated.div 包裹动画节点,并将变化的元素属性封装为 css 对象作为 stlye 传入 Animated.div 中。在点击事件中,考虑到按钮可以多次连续点击,我们首先使用 stopAnimation 停止当前动画,并获取 Animated 对象的当前值 value ,随后使用 Animated.spring 函数开启一次弹簧动画过程,从而实现一个流畅的动画效果。由于每次转动停止时,我们希望图片的翻转角度都是90°的整数倍,所以需要对 Animated.spring 的终止值进行取整。最终我们实现了如下效果:

React中怎么实现常见的动画

使用时需要注意一下几点:

  1. Animated 对象的值和其插值结果只能作用于 Animated.div 节点;

  2. interpolate 默认会根据输入区间和输出区间进行线性插值,如果输入值超出输入区间不受影响,插值结果默认会根据输出区间向外延展插值,可以通过设置 extrapolate 属性限制插值结果区间。

Animated 在动画过程中不直接修改组件 state ,而是通过其新建对象的组件和方法直接修改元素的属性,不会重复触发 render 函数,是 React Native 中非常稳定的动画库。但是在 React 中存在低版本浏览器兼容问题,且具有一定学习成本。

结语

当我们在 React 中实现动画时,首先要考量动画的难易程度和使用场景,对于简单动画,优先使用 css3 实现,其次是基于 js 的时间间隔动画。如果是元素入场动画和离场动画,则建议结合 CSSTransitionGroup 或者 TransitionGroup 实现。当要实现的动画效果较为复杂时,不妨尝试一些优秀的第三方库,打开精彩的动效大门。

以上是“React中怎么实现常见的动画”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网行业资讯频道!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

React中怎么实现常见的动画

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

jQuery常见动画效果实现介绍

这篇文章主要为大家介绍了jQuery编程动画基本实现方法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

怎么使用react native reanimated实现动画

这篇“怎么使用react native reanimated实现动画”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么使用r
2023-07-05

怎么使用Framer Motion实现React动画

这篇文章主要介绍“怎么使用Framer Motion实现React动画”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用Framer Motion实现React动画”文章能帮助大家解决问题。在我
2023-07-04

Vue中CSS动画怎么实现

本篇内容主要讲解“Vue中CSS动画怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue中CSS动画怎么实现”吧!显示的过程:在动画即将被执行的瞬间,会往div上增加两个class名:f
2023-07-04

react怎么实现滑动

react实现滑动的方法:1、在onTouchStart事件找到touches,根据identifier中记录新的touch出现;2、在onTouchMove事件中根据identifier来记录每个touch经过的点的坐标;3、在onTouchEnd事件中,找到结束的touch事件,然后通过结束的touch事件划过的点来计算要执行的手势即可。
2023-05-14

React中常见的TypeScript定义实战教程

这篇文章主要介绍了React中常见的TypeScript定义实战,本文介绍了Fiber结构,Fiber的生成过程,调和过程,以及render和commit两大阶段,需要的朋友可以参考下
2022-11-13

css3怎么实现动画

本篇内容主要讲解“css3怎么实现动画”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“css3怎么实现动画”吧!具体使用示例:1.通过transition设置过渡,添加transform设置形状,
2022-12-15

jQuery中怎么实现操作动画

本篇内容主要讲解“jQuery中怎么实现操作动画”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“jQuery中怎么实现操作动画”吧!具体代码如下: jQue</div></div><div class="articleBottom"><span class="date" style="float: right;">2023-06-17</span></div><div class="clearboth"></div></div><div class="articleList clearfix"><div class="intro"><a title="css怎么实现动画" href="/article/42176ec0b7.html"><h4>css怎么实现动画</h4></a><div class="des"></div></div><div class="articleBottom"><span class="date" style="float: right;">2024-04-02</span></div><div class="clearboth"></div></div><div class="articleList clearfix"><div class="intro"><a title="css3中怎么实现动画效果" href="/article/b8e9cc5eca.html"><h4>css3中怎么实现动画效果</h4></a><div class="des"></div></div><div class="articleBottom"><span class="date" style="float: right;">2024-04-02</span></div><div class="clearboth"></div></div><div class="articleList clearfix"><div class="intro"><a title="CSS3动画是怎么实现的" href="/article/6cddd37456.html"><h4>CSS3动画是怎么实现的</h4></a><div class="des">这篇文章主要讲解了“CSS3动画是怎么实现的”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“CSS3动画是怎么实现的”吧!  动画  CSS3属性中有关于制作动画的三个属性:  transfo</div></div><div class="articleBottom"><span class="date" style="float: right;">2023-06-05</span></div><div class="clearboth"></div></div><div class="articleList clearfix"><div class="intro"><a title="react常见的ts类型怎么定义" href="/article/499016e173.html"><h4>react常见的ts类型怎么定义</h4></a><div class="des">本篇内容主要讲解“react常见的ts类型怎么定义”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“react常见的ts类型怎么定义”吧!一个函数组件import React from "react</div></div><div class="articleBottom"><span class="date" style="float: right;">2023-07-06</span></div><div class="clearboth"></div></div><div class="articleList clearfix"><div class="intro"><a title="怎么用React加CSS3实现微信拆红包动画效果" href="/article/7f8d09797d.html"><h4>怎么用React加CSS3实现微信拆红包动画效果</h4></a><div class="des"></div></div><div class="articleBottom"><span class="date" style="float: right;">2024-04-02</span></div><div class="clearboth"></div></div><div class="articleList clearfix"><div class="intro"><a title="react怎么实现滚动条" href="/article/b15230a6c0.html"><h4>react怎么实现滚动条</h4></a><div class="des">react实现滚动条的方法:1、使用“render() {const translateDistancePercentage...}”方式设置滚动条滚动百分比;2、通过“.scrollBar {width: 362px;...}”设置滚动条宽度;3、设置样式为“left: -362px;top: 0px;position: absolute;”即可。</div></div><div class="articleBottom"><span class="date" style="float: right;">2023-05-14</span></div><div class="clearboth"></div></div><div class="articleList clearfix"><div class="intro"><a title="React Native中怎么实现动态导入" href="/article/b1db7ac534.html"><h4>React Native中怎么实现动态导入</h4></a><div class="des">这篇文章主要介绍“React Native中怎么实现动态导入”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“React Native中怎么实现动态导入”文章能帮助大家解决问题。背景随着业务的发展,每一</div></div><div class="articleBottom"><span class="date" style="float: right;">2023-07-02</span></div><div class="clearboth"></div></div><div class="articleList clearfix"><div class="intro"><a title="CSS3中怎么实现滚动条动画效果" href="/article/a189419662.html"><h4>CSS3中怎么实现滚动条动画效果</h4></a><div class="des"></div></div><div class="articleBottom"><span class="date" style="float: right;">2024-04-02</span></div><div class="clearboth"></div></div></div></div><div class="hotFlag"><h4>热门标签</h4><div class="flagBox"><a title="Linux" href="/tag/Linux/">Linux(148)</a><a title="PHP" href="/tag/PHP/">PHP(127)</a><a title="Java" href="/tag/Java/">Java(102)</a><a title="正则表达式" href="/tag/正则表达式/">正则表达式(101)</a><a title="JavaScript" href="/tag/JavaScript/">JavaScript(69)</a><a title="最佳实践" href="/tag/最佳实践/">最佳实践(67)</a><a title="jQuery" href="/tag/jQuery/">jQuery(44)</a><a title="MySQL" href="/tag/MySQL/">MySQL(39)</a><a title="Docker" href="/tag/Docker/">Docker(37)</a><a title="C语言" href="/tag/C语言/">C语言(36)</a><a title="性能优化" href="/tag/性能优化/">性能优化(34)</a><a title="Python" href="/tag/Python/">Python(34)</a><a title="XML" href="/tag/XML/">XML(28)</a><a title="string" href="/tag/string/">string(27)</a><a title="第三方库" href="/tag/第三方库/">第三方库(23)</a><a title="回调函数" href="/tag/回调函数/">回调函数(23)</a><a title="ZIP" href="/tag/ZIP/">ZIP(22)</a><a title="数组" href="/tag/数组/">数组(22)</a><a title="可扩展性" href="/tag/可扩展性/">可扩展性(22)</a><a title="字符串比较" href="/tag/字符串比较/">字符串比较(21)</a><a title="find" href="/tag/find/">find(20)</a><a title="RPM" href="/tag/RPM/">RPM(20)</a><a title="Go" href="/tag/Go/">Go(20)</a><a title="grep" href="/tag/grep/">grep(19)</a><a title="ASP.NETCore" href="/tag/ASP.NETCore/">ASP.NETCore(19)</a><a title="XML解析器" href="/tag/XML解析器/">XML解析器(19)</a><a title="事件" href="/tag/事件/">事件(19)</a><a title="事件处理程序" href="/tag/事件处理程序/">事件处理程序(19)</a><a title="StringBuilder" href="/tag/StringBuilder/">StringBuilder(18)</a><a title="Nginx" href="/tag/Nginx/">Nginx(18)</a></div></div></div><div class="main_right fr"><div class="artHotSearch"><h4 class="title"><div class="fl"><span class="icon bg_content bg_icon_rs"></span><span class="name">编程热搜</span></div><a href="" class="fr bg_content bg_txt_rsb"></a><div class="clearboth"></div></h4><ul><li class="rslist clearfix"><div class="rslist_left fl"><h5><span class="fl name"><a title="怎么安装配置nodejs" href="https://www.528045.com/article/2f3ea96eab.html">怎么安装配置nodejs</a></span></h5><div class="clearboth"></div><div class="des"></div></div><img class="lazy" data-type="0" data-src="/file/upload/202210/19/tixkirpxiqo.jpg" alt="怎么安装配置nodejs" /><div class="clearboth"></div></li><li class="rslist clearfix"><div class="rslist_left fl"><h5><span class="fl name"><a title="Vue中Vue.extend()的使用及解析" href="https://www.528045.com/article/a5db73cb2f.html">Vue中Vue.extend()的使用及解析</a></span></h5><div class="clearboth"></div><div class="des">这篇文章主要介绍了Vue中Vue.extend()的使用及解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教</div></div><img class="lazy" data-type="0" data-src="https://static.528045.com/imgs/10.jpg?imageMogr2/format/webp/blur/1x0/quality/35" alt="Vue中Vue.extend()的使用及解析" /><div class="clearboth"></div></li><li class="rslist clearfix"><div class="rslist_left fl"><h5><span class="fl name"><a title="NodeJs模拟登陆正方教务" href="https://www.528045.com/article/2ecc5d16d4.html">NodeJs模拟登陆正方教务</a></span></h5><div class="clearboth"></div><div class="des">网上已经有很多关于模拟登陆正方教务的作品了,基于 PHP,Python,Java,.Net 加上我自己尝试的NodeJs,这几门语言都可以实现模拟登陆,模拟登陆的技术点不是特别难,这里记录一下利用 Node 碰到的一些坑,以及一些我自己的解</div></div><img class="lazy" data-type="0" data-src="http://files.jb51.net/file_images/article/201704/2017428104219999.jpg" alt="NodeJs模拟登陆正方教务" /><div class="clearboth"></div></li><li class="rslist clearfix"><div class="rslist_left fl"><h5><span class="fl name"><a title="如何让DIV水平垂直居中" href="https://www.528045.com/article/ca8452210f.html">如何让DIV水平垂直居中</a></span></h5><div class="clearboth"></div><div class="des"></div></div><img class="lazy" data-type="0" data-src="/file/upload/202210/19/pki1d2gq0ly.jpg" alt="如何让DIV水平垂直居中" /><div class="clearboth"></div></li><li class="rslist clearfix"><div class="rslist_left fl"><h5><span class="fl name"><a title="css中怎么设置div背景颜色" href="https://www.528045.com/article/8b624fb379.html">css中怎么设置div背景颜色</a></span></h5><div class="clearboth"></div><div class="des"></div></div><img class="lazy" data-type="0" data-src="/file/upload/202210/19/byqxxwbwqk1.png" alt="css中怎么设置div背景颜色" /><div class="clearboth"></div></li><li class="rslist clearfix"><div class="rslist_left fl"><h5><span class="fl name"><a title="nodejs怎么查看版本" href="https://www.528045.com/article/db3a645928.html">nodejs怎么查看版本</a></span></h5><div class="clearboth"></div><div class="des"></div></div><img class="lazy" data-type="0" data-src="/file/upload/202210/19/m05vf0vjqbr.jpg" alt="nodejs怎么查看版本" /><div class="clearboth"></div></li><li class="rslist clearfix"><div class="rslist_left fl"><h5><span class="fl name"><a title="html如何设置按钮文字" href="https://www.528045.com/article/2134eea2b3.html">html如何设置按钮文字</a></span></h5><div class="clearboth"></div><div class="des"></div></div><img class="lazy" data-type="0" data-src="/file/upload/202210/19/4cmxmmrqn2p.jpg" alt="html如何设置按钮文字" /><div class="clearboth"></div></li><li class="rslist clearfix"><div class="rslist_left fl"><h5><span class="fl name"><a title="html如何设置div的透明度" href="https://www.528045.com/article/69630be7a7.html">html如何设置div的透明度</a></span></h5><div class="clearboth"></div><div class="des"></div></div><img class="lazy" data-type="0" data-src="/file/upload/202210/19/owhfomqa2hr.jpg" alt="html如何设置div的透明度" /><div class="clearboth"></div></li><li class="rslist clearfix"><div class="rslist_left fl"><h5><span class="fl name"><a title="JavaScript对象(详细)" href="https://www.528045.com/article/aa5647b26d.html">JavaScript对象(详细)</a></span></h5><div class="clearboth"></div><div class="des"></div></div><img class="lazy" data-type="0" data-src="https://static.528045.com/imgs/25.jpg?imageMogr2/format/webp/blur/1x0/quality/35" alt="JavaScript对象(详细)" /><div class="clearboth"></div></li><li class="rslist clearfix"><div class="rslist_left fl"><h5><span class="fl name"><a title="html5 mui怎么使用" href="https://www.528045.com/article/537e020a72.html">html5 mui怎么使用</a></span></h5><div class="clearboth"></div><div class="des"></div></div><img class="lazy" data-type="0" data-src="/file/upload/202210/19/jvzk30x24yu.jpg" alt="html5 mui怎么使用" /><div class="clearboth"></div></li></ul><div class="seeMore"><a href="https://www.528045.com/article/web-c5-1.html">查看更多</a></div></div><div class="artSubmit"><h4 class="title"><div class="fl"><span class="icon bg_content bg_icon_yktg"></span><span class="name">编程资源站</span></div><div class="clearboth"></div></h4><ul class="submitNav clearfix"><li class="active first">资料下载</li><li>历年试题</li></ul><div class="submitBox active"><div class="submitItem"><span class="turn"></span><h5 class="title"><a title="2021年下半年软考高级信息系统项目管理师高频考点" href="https://www.528045.com/down/89bb6.html">2021年下半年软考高级信息系统项目管理师高频考点</a><span class="hot"><a href="https://www.528045.com/down/ziliao-c69-1.html">精选资料</a></span></h5></div><div class="submitItem"><span class="turn"></span><h5 class="title"><a title="2021下半年软考高级信息系统技术知识点记忆口诀" href="https://www.528045.com/down/7d690.html">2021下半年软考高级信息系统技术知识点记忆口诀</a><span class="hot"><a href="https://www.528045.com/down/ziliao-c69-1.html">精选资料</a></span></h5></div><div class="submitItem"><span class="turn"></span><h5 class="title"><a title="2021下半年软考《信息系统项目管理师》考试真题及答案" href="https://www.528045.com/down/4277a.html">2021下半年软考《信息系统项目管理师》考试真题及答案</a><span class="hot"><a href="https://www.528045.com/down/ziliao-c69-1.html">精选资料</a></span></h5></div><div class="submitItem"><span class="turn"></span><h5 class="title"><a title="2021下半年软考高级考试备考攻略" href="https://www.528045.com/down/9248a.html">2021下半年软考高级考试备考攻略</a><span class="hot"><a href="https://www.528045.com/down/ziliao-c69-1.html">精选资料</a></span></h5></div><div class="submitItem"><span class="turn"></span><h5 class="title"><a title="2021年软考高级《信息系统项目管理师》巩固练习题汇总" href="https://www.528045.com/down/fcca0.html">2021年软考高级《信息系统项目管理师》巩固练习题汇总</a><span class="hot"><a href="https://www.528045.com/down/ziliao-c69-1.html">精选资料</a></span></h5></div><div class="submitItem"><span class="turn"></span><h5 class="title"><a title="2021下半年软考高级信息系统项目管理师30个易考知识点汇总" href="https://www.528045.com/down/7636b.html">2021下半年软考高级信息系统项目管理师30个易考知识点汇总</a><span class="hot"><a href="https://www.528045.com/down/ziliao-c69-1.html">精选资料</a></span></h5></div><div class="submitItem"><span class="turn"></span><h5 class="title"><a title="2021下半年软考高级知识点这样记,还担心记不住吗" href="https://www.528045.com/down/76382.html">2021下半年软考高级知识点这样记,还担心记不住吗</a><span class="hot"><a href="https://www.528045.com/down/ziliao-c69-1.html">精选资料</a></span></h5></div><div class="submitItem"><span class="turn"></span><h5 class="title"><a title="2021年下半年软考高级考试重点汇总" href="https://www.528045.com/down/15f44.html">2021年下半年软考高级考试重点汇总</a><span class="hot"><a href="https://www.528045.com/down/ziliao-c69-1.html">精选资料</a></span></h5></div><div class="submitItem"><span class="turn"></span><h5 class="title"><a title="2021下半年软考高级信息系统项目管理师计算公式汇总" href="https://www.528045.com/down/2d560.html">2021下半年软考高级信息系统项目管理师计算公式汇总</a><span class="hot"><a href="https://www.528045.com/down/ziliao-c69-1.html">精选资料</a></span></h5></div><div class="submitItem"><span class="turn"></span><h5 class="title"><a title="2021年下半年软考高级《信息系统项目管理师》模拟试题" href="https://www.528045.com/down/c0085.html">2021年下半年软考高级《信息系统项目管理师》模拟试题</a><span class="hot"><a href="https://www.528045.com/down/ziliao-c69-1.html">精选资料</a></span></h5></div><div class="seeMore"><a href="/down/">查看更多</a></div></div><div class="submitBox"><div class="submitItem"><span class="turn"></span><h5 class="title"><a title="信息系统项目管理师选择题每日一练(2024)" href="https://www.528045.com/article/6d5f303202.html">信息系统项目管理师选择题每日一练(2024)</a><span class="hot"><a href="https://www.528045.com/article/lnst-c57-1.html">历年试题</a></span></h5></div><div class="submitItem"><span class="turn"></span><h5 class="title"><a title="2023年下半年信息系统项目管理师综合知识真题演练" href="https://www.528045.com/article/f2da969d4f.html">2023年下半年信息系统项目管理师综合知识真题演练</a><span class="hot"><a href="https://www.528045.com/article/lnst-c57-1.html">历年试题</a></span></h5></div><div class="seeMore"><a href="https://www.528045.com/article/lnst-c57-1.html">查看更多</a></div></div></div><div class="meumfie"><h4 class="title"><div class="fl"><span class="icon bg_content bg_icon_ykzl"></span><span class="name">目录</span></div><div class="clearboth"></div></h4><div class="toc"></div></div></div><div class="clearboth"></div></div><script type="text/javascript" src="/skin/static/js/toc.js"></script><div class="popUp popDelay"><div class="maskBg"></div><div class="popCon"><span class="btn btn_close"></span><div class="tip"> 本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页 </div><div class="delayMain"><div class="delaymain_left"><a href="https://www.528045.com"><img src="https://static.528045.com/skin/content_left.png?imageMogr2/format/webp/blur/1x0/quality/35"></a></div><div class="delaymain_right"><div class="news_title"><span class="fl">最新资讯</span ><a href="/" class="fr">更多</a><div class="clearboth"></div></div><ul></ul></div><div class="clearboth"></div></div><div class="bigshow"><a href="https://www.528045.com"><img src="https://static.528045.com/skin/content_bottom.png?imageMogr2/format/webp/blur/1x0/quality/35"></a></div></div></div><div class="footer"><div class="friendLink"><span class="friendTitle">友情链接</span><a href="https://www.lsjlt.com">编程网</a></div><script type="text/javascript" src="/skin/static/js/footermain.js"></script></div><div class="popCommon"><span class="mask"></span><div class="popCon"></div></div><div class="ajaxrightbtn"><div class="funBtnbox"><div class="rb_fk rb_ty br_bom"><div class="wx_mo1 _mo1"><i class="dtmuban-iconfont icon-fankui2"></i><p>反馈</p></div><a href="javascript:void(0);" onclick="Dsb('urs-form-modalfk');"><div class="_mo2 rb_gradient br_bom"><p>我要<br>反馈</p></div></a></div></div><div class="fbs fbs-gotp back2top" style="display: none;"><div class="rb_top rb_ty br_all"><div class="top_mo1 _mo1 "><i class="dtmuban-iconfont icon-zhiding"></i></div><a href="javascript:void(0);" title="返回顶部"><div class="_mo2 rb_gradient br_all"><p>返回<br>顶部</p></div></a></div></div></div><div id="urs-form-modalfk-bg" class="urs-form-modal-bg" style="display: none;"></div><div id="urs-form-modalfk" class="urs-form-modal" style="display: none;"><div class="urs-form-component plan-get-form-mini js-apply-form clearfix"><div class="urs-component-head"><div class="icon-close" onclick="Dhb('urs-form-modalfk');"><img id="close-btn" src="https://static.528045.com/skin/ic_delete_normal_24px.png"></div><p class="form-title">留言反馈</p><p></p><p class="form-line"></p></div><div class="urs-component-tab"><h5>感谢您的提交,我们服务专员将在<span>30分钟内</span>给您回复</h5><div class="get-plan-form-item"><i class="u-item-icon dtmuban-iconfont icon-fanganguihua"></i><input class="u-input js-apply-phone" type="text" id="titleb" name="titleb" value="我要反馈留言,看到请回复" placeholder="留言标题"><span id="dtitlea"></span></div><div class="get-plan-form-item"><select name="typeidb" id="typeidb" class="u-select"><option value="">请选择类型</option><option value="0">问题反馈</option><option value="1">意见建议</option><option value="2">倒卖举报</option><option value="3">不良信息</option><option value="4">其他</option></select></div><div class="get-plan-form-item"><i class="u-item-icon dtmuban-iconfont icon-yonghu"></i><input class="u-input js-apply-name" type="text" id="truenameb" name="truenameb" placeholder="您的姓名" value=""><span id="dtruenameb"></span></div><div class="get-plan-form-item"><i class="u-item-icon dtmuban-iconfont icon-liuyan"></i><input class="u-input js-apply-phone" type="text" id="emailb" name="emailb" placeholder="您的邮箱" value=""><span id="demailb"></span></div><div class="get-plan-form-item"><i class="u-item-icon dtmuban-iconfont icon-shouji"></i><input class="u-input js-apply-phone" type="text" id="telephoneb" name="telephoneb" placeholder="您的手机" value=""><span id="dtelephoneb"></span></div><div class="get-plan-form-item"><i class="u-item-icon dtmuban-iconfont icon-liuyan2"></i><textarea class="u-textarea js-apply-content" id="contentb" name="contentb" placeholder="留言说明,文字为2-100字" value=""></textarea><span id="dcontentb"></span></div><button type="submit" name="submit" class="btn btn-red" onclick="checkaguestbook();">立即提交</button></div></div></div><style> .drop_more li{ list-style: none;} </style><script type="text/javascript" src="/file/script/config.js"></script><script type="text/javascript" src="/file/script/common.js"></script><script type="text/javascript" src="/skin/static/js/commonpop.js"></script><script type="text/javascript" src="/skin/static/js/header.js"></script><script type="text/javascript" src="/skin/static/js/footer.js"></script><script type="text/javascript" src="/skin/static/js/listconcommon.js"></script><script src="/skin/static/layui/layui.js" type="text/javascript"></script><script src="/skin/static/js/custom-script.js" type="text/javascript"></script><script src="/skin/static/js/indexsms.js?v=20240108.1443"></script><script type="text/javascript"> $(function(){ var destoon_userid = 0,destoon_username = '',destoon_member = destoon_guest = ''; destoon_guest = '<div class="login-li"><a href="javascript:void(0);" lay-on="showLoginPopup" class="a_on_dl" id="dn-login">请登录</a></div><div class="login-li"><a href="javascript:void(0);" lay-on="showLoginPopup" class="a_to">免费注册</a></div>'; destoon_member += destoon_guest; $('#m52_member').html(destoon_member); }); </script></body></html><script type="text/javascript" src="/skin/static/js/contentie.js"></script>