javascript - 如何使常规 javascript 在 React 应用程序中工作

标签 javascript reactjs

嗨,我正在尝试实现这个文本拼写 https://codepen.io/soulwire/pen/mErPAK/?editors=1010 在我的 React 应用程序中,但我收到错误类型错误:无法读取 null 的属性“innerText”。

   9 |   this.update = this.update.bind(this)
  10 | }
  11 | setText(newText) {
> 12 |   const oldText = this.el.innerText
  13 |   const length = Math.max(oldText.length, newText.length)
  14 |   const promise = new Promise(resolve => (this.resolve = resolve))
  15 |   this.queue = []

到目前为止,这就是我所做的 https://codesandbox.io/s/oxm38v7x9y

  1. 创建新组件 scrable.js
  2. 从codepen移走了代码
  3. 导入到 index.js

你不需要修复codesandbox,只要一点点线索就足够了:)

import React, { Component } from "react"

export default class Scrable extends Component {
  render() {
    const phrases = [
      "Neo,",
      "sooner or later",
      "you're going to realize",
      "just as I did",
      "that there's a difference",
      "between knowing the path",
      "and walking the path",
    ]
    const el = document.querySelector(".text")
    const fx = new TextScramble(el)
    console.log(el)
    let counter = 0
    const next = () => {
      fx.setText(phrases[counter]).then(() => {
        setTimeout(next, 800)
      })
      counter = (counter + 1) % phrases.length
    }
    next()
    return (
      <TextScramble>
        <div className="text" />
      </TextScramble>
    )
  }
}

export class TextScramble extends Component {
  constructor(el) {
    super()
    this.el = el
    this.chars = "!<>-_\\/[]{}—=+*^?#________"
    this.update = this.update.bind(this)
  }
  setText(newText) {
    const oldText = this.el.innerText
    const length = Math.max(oldText.length, newText.length)
    const promise = new Promise(resolve => (this.resolve = resolve))
    this.queue = []
    for (let i = 0; i < length; i++) {
      const from = oldText[i] || ""
      const to = newText[i] || ""
      const start = Math.floor(Math.random() * 40)
      const end = start + Math.floor(Math.random() * 40)
      this.queue.push({ from, to, start, end })
    }
    cancelAnimationFrame(this.frameRequest)
    this.frame = 0
    this.update()
    return promise
  }
  update() {
    let output = ""
    let complete = 0
    for (let i = 0, n = this.queue.length; i < n; i++) {
      let { from, to, start, end, char } = this.queue[i]
      if (this.frame >= end) {
        complete++
        output += to
      } else if (this.frame >= start) {
        if (!char || Math.random() < 0.28) {
          char = this.randomChar()
          this.queue[i].char = char
        }
        output += `<span class="dud">${char}</span>`
      } else {
        output += from
      }
    }
    this.el.innerHTML = output
    if (complete === this.queue.length) {
      this.resolve()
    } else {
      this.frameRequest = requestAnimationFrame(this.update)
      this.frame++
    }
  }
  randomChar() {
    return this.chars[Math.floor(Math.random() * this.chars.length)]
  }
  render() {
    return <div />
  }
}

最佳答案

大家好,感谢您的评论,

我能够让它发挥作用。下面是我的代码。欢迎任何建议

我不完全确定这是正确的方法,但它确实有效

import React, { Component } from 'react'

export default class Scrable extends Component {
  constructor(el) {
    super(el)
    this.el = el
    this.chars = "!<>-_\\/[]{}—=+*^?#________"
    // this.update = this.update.bind(this)
  }
  componentDidMount(){
    const phrases = [
      'Neo,',
      'sooner or later',
      'you\'re going to realize',
      'just as I did',
      'that there\'s a difference',
      'between knowing the path',
      'and walking the path'
    ]

    const el = document.querySelector('.text')
    const fx = new TextScramble(el)

    let counter = 0
    const next = () => {
      fx.setText(phrases[counter]).then(() => {
        setTimeout(next, 800)
      })
      counter = (counter + 1) % phrases.length
    }

    next()
    console.log(el)
  }
  render() {
    const phrases = [
      "Neo,",
      "sooner or later",
      "you're going to realize",
      "just as I did",
      "that there's a difference",
      "between knowing the path",
      "and walking the path",
    ]

    return (
      <div>
        <div className="text">text</div>
      </div>
    )
  }
}

class TextScramble {
  constructor(el) {
    this.el = el
    this.chars = '!<>-_\\/[]{}—=+*^?#________'
    this.update = this.update.bind(this)
    console.log(this)
  }
  setText(newText) {
    const oldText = this.el.innerText
    const length = Math.max(oldText.length, newText.length)
    const promise = new Promise((resolve) => this.resolve = resolve)
    this.queue = []
    for (let i = 0; i < length; i++) {
      const from = oldText[i] || ''
      const to = newText[i] || ''
      const start = Math.floor(Math.random() * 40)
      const end = start + Math.floor(Math.random() * 40)
      this.queue.push({ from, to, start, end })
    }
    cancelAnimationFrame(this.frameRequest)
    this.frame = 0
    this.update()
    return promise
  }
  update() {
    let output = ''
    let complete = 0
    for (let i = 0, n = this.queue.length; i < n; i++) {
      let { from, to, start, end, char } = this.queue[i]
      if (this.frame >= end) {
        complete++
        output += to
      } else if (this.frame >= start) {
        if (!char || Math.random() < 0.28) {
          char = this.randomChar()
          this.queue[i].char = char
        }
        output += `<span class="dud">${char}</span>`
      } else {
        output += from
      }
    }
    this.el.innerHTML = output
    if (complete === this.queue.length) {
      this.resolve()
    } else {
      this.frameRequest = requestAnimationFrame(this.update)
      this.frame++
    }
  }
  randomChar() {
    return this.chars[Math.floor(Math.random() * this.chars.length)]
  }
}

关于javascript - 如何使常规 javascript 在 React 应用程序中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55436405/

相关文章:

javascript - 如何在显示后消失警报 div

Visual Studio 2019 中的 asp.net core React redux 项目中的 JavaScript

javascript - 如何在reactjs中获取以前的状态值

javascript - 跨浏览器转换和转换问题

javascript - 有条件地渲染中继器中的元素

javascript - Components.utils.import() 中是否可以使用相对 URL/路径?

javascript - Vue.js 防止布局跳转

reactjs - 使用react-router设置初始路由

reactjs - react 脚本 : not found when building docker image in CI, 但在本地工作

javascript - Chrome中的音频时间戳不正确