文字打字效果

2 篇文章 0 订阅

@ 打字效果

react 打字效果

class Typing {
  constructor(opts) {
    this.opts = opts || {};
    this.source = opts.source;
    this.output = opts.output;
    this.delay = opts.delay || 120;
    this.chain = {
      parent: null,
      dom: this.output,
      val: []
    };
    if (!(typeof this.opts.done === 'function')) this.opts.done = function () {
    };
  }

  init() {
    //初始化函数
    this.chain.val = this.convert(this.source, this.chain.val);
  }

  convert(dom, arr) {
    //将dom节点的子节点转换成数组,
    let children = Array.from(dom.childNodes)
    for (let i = 0; i < children.length; i++) {
      let node = children[i]
      if (node.nodeType === 3) {
        arr = arr.concat(node.nodeValue.split(''))   //将字符串转换成字符串数组,后面打印时才会一个一个的打印
      } else if (node.nodeType === 1) {
        let val = []
        val = this.convert(node, val)
        arr.push({
          'dom': node,
          'val': val
        })
      }
    }
    return arr
  }

  print(dom, val, callback) {
    setTimeout(function () {
      dom.appendChild(document.createTextNode(val));
      callback();
    }, this.delay);
  }

  play(ele) {
    //当打印最后一个字符时,动画完毕,执行done
    if (!ele.val.length) {
      if (ele.parent) this.play(ele.parent);
      else this.opts.done();
      return;
    }
    let current = ele.val.shift()  //获取第一个元素,同时删除数组中的第一个元素
    if (typeof current === 'string') {
      this.print(ele.dom, current, () => {
        this.play(ele); //继续打印下一个字符
      })
    } else {
      let dom = current.dom.cloneNode() //克隆节点,不克隆节点的子节点,所以不用加参数true
      ele.dom.appendChild(dom)
      this.play({
        parent: ele,
        dom,
        val: current.val
      })
    }
  }

  start() {
    this.init();
    this.play(this.chain);
  }
}

调用


  const typing = new Typing({
      source:this.source,
      output:this.output,
      delay:30
    })
    typing.start()

//html
<div style={{display:'none'}} ref={el => this.source = el} dangerouslySetInnerHTML={{__html:this.props.source}}/>
<div ref={el => this.output = el}/>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值