DOM元素未初始化

时间:2020-08-28 17:17:03

标签: javascript reactjs dom

我已经重新使用了用HTML / JS / CSS编写的旧代码,并试图让它做出反应,但是它不起作用。我可能做不到。


import React from 'react'

class ClassCreationForm extends React.Component {

render() {

    // Questions Array
    const questions = [
        { question: 'Enter Your First Name' },
        { question: 'Enter Your Last Name' },
        { question: 'Enter Your Email', pattern: /\S+@\S+\.\S+/ },
        { question: 'Create A Password', type: 'password' }
    ];

    // Transition Times
    const shakeTime = 100; // Shake Transition Time
    const switchTime = 200; // Transition Between Questions

    // Init Position At First Question
    let position = 0;

    // Init DOM Elements
    const formBox = document.querySelector('#form-box');
    const nextBtn = document.querySelector('#next-btn');
    const prevBtn = document.querySelector('#prev-btn');
    const inputGroup = document.querySelector('#input-group');
    const inputField = document.querySelector('#input-field');
    const inputLabel = document.querySelector('#input-label');
    const inputProgress = document.querySelector('#input-progress');
    const progress = document.querySelector('#progress-bar');

    // EVENTS

    // Get Question On DOM Load
    document.addEventListener('DOMContentLoaded', getQuestion);

    // Next Button Click
    nextBtn.addEventListener('click', validate);

    // Input Field Enter Click
    inputField.addEventListener('keyup', e => {
    if (e.keyCode == 13) {
        validate();
    }
    });

    // FUNCTIONS

    // Get Question From Array & Add To Markup
    function getQuestion() {
        // Get Current Question
        inputLabel.innerHTML = questions[position].question;
        // Get Current Type
        inputField.type = questions[position].type || 'text';
        // Get Current Answer
        inputField.value = questions[position].answer || '';
        // Focus On Element
        inputField.focus();

        // Set Progress Bar Width - Variable to the questions length
        progress.style.width = (position * 100) / questions.length + '%';

        // Add User Icon OR Back Arrow Depending On Question
        prevBtn.className = position ? 'fas fa-arrow-left' : 'fas fa-user';

        showQuestion();
    }

    // Display Question To User
    function showQuestion() {
        inputGroup.style.opacity = 1;
        inputProgress.style.transition = '';
        inputProgress.style.width = '100%';
    }

    // Hide Question From User
    function hideQuestion() {
        inputGroup.style.opacity = 0;
        inputLabel.style.marginLeft = 0;
        inputProgress.style.width = 0;
        inputProgress.style.transition = 'none';
        inputGroup.style.border = null;
    }

    // Transform To Create Shake Motion
    function transform(x, y) {
        formBox.style.transform = `translate(${x}px, ${y}px)`;
    }

    // Validate Field
    function validate() {
    // Make Sure Pattern Matches If There Is One
    if (!inputField.value.match(questions[position].pattern || /.+/)) {
        inputFail();
    } else {
        inputPass();
    }
    }

    // Field Input Fail
    function inputFail() {
    formBox.className = 'error';
    // Repeat Shake Motion -  Set i to number of shakes
    for (let i = 0; i < 6; i++) {
        setTimeout(transform, shakeTime * i, ((i % 2) * 2 - 1) * 20, 0);
        setTimeout(transform, shakeTime * 6, 0, 0);
        inputField.focus();
    }
    }

    // Field Input Passed
    function inputPass() {
    formBox.className = '';
    setTimeout(transform, shakeTime * 0, 0, 10);
    setTimeout(transform, shakeTime * 1, 0, 0);

    // Store Answer In Array
    questions[position].answer = inputField.value;

    // Increment Position
    position++;

    // If New Question, Hide Current and Get Next
    if (questions[position]) {
        hideQuestion();
        getQuestion();
    } else {
        // Remove If No More Questions
        hideQuestion();
        formBox.className = 'close';
        progress.style.width = '100%';

        // Form Complete
        formComplete();
    }
    }

    // All Fields Complete - Show h1 end
    function formComplete() {
    const h1 = document.createElement('h1');
    h1.classList.add('end');
    h1.appendChild(
        document.createTextNode(
        `Thanks ${
            questions[0].answer
        } You are registered and will get an email shortly`
        )
    );
    setTimeout(() => {
        formBox.parentElement.appendChild(h1);
        setTimeout(() => (h1.style.opacity = 1), 50);
    }, 1000);
    }

    return(
        <div id="container">
        <h1 class="logo">Form Example</h1>
        <div id="form-box">
            <i id="prev-btn" class="fas fa-arrow-left"></i>
            <i id="next-btn" class="fas fa-arrow-right"></i>
            <div id="input-group">
                <input id="input-field" required> </input>
                <label id="input-label"></label>
                <div id="input-progress"></div>
            </div>
            <div id="progress-bar"></div>
        </div>
        </div>
        )
    }
}

export default ClassCreationForm

我面临的问题是inputLabel.innerHTML生成错误,因为inputLabel为空。我认为这可能是我初始化谁不对的方式。

致谢

1 个答案:

答案 0 :(得分:1)

我已经尝试向您展示React组件的基本结构。这至少应该运行并在标签元素中向您显示第一个问题。

我仍然建议您参加有关如何构建组件以及它们如何工作的教程。这是与常规(原始)JavaScript不同的样式,但是对于初学者来说,它具有很好的学习曲线。

别放弃,你会到达那里的!

import React from 'react'

class ClassCreationForm extends React.Component {

  state: {
    questions: [
      { phrase: 'Enter Your First Name' },
      { phrase: 'Enter Your Last Name' },
      { phrase: 'Enter Your Email', pattern: /\S+@\S+\.\S+/ },
      { phrase: 'Create A Password', type: 'password' }
    ],
    shakeTime: 100,
    switchTime: 200,
    position: 0,
    currentAnswer: ''
  }

  handleKeyUp(event) {
    const { value, keyCode } = event;
    this.setState({
      currentAnswer: value
    });
    if (keyCode == 13) {
      this.validate();
    }
  }

  handleNextClick(event) {
    this.validate();
  }

  validate() {
    console.log(this.state.currentAnswer);
  }

  render() {
    const { questions, position } = this.state;
    const { phrase, type, pattern } = questions[position];
 
    return (
      <div id="container">
        <h1 className="logo">Form Example</h1>
        <div id="form-box">
          <i id="prev-btn" className="fas fa-arrow-left"></i>
          <i 
            id="next-btn" 
            className="fas fa-arrow-right"
            onClick={this.handleNextClick}
          ></i>
          <div id="input-group">
            <input 
              id="input-field" 
              type={type || 'text'}
              onKeyUp={this.handleKeyUp}
              required 
            />
            <label id="input-label">
              { phrase }
            </label>
            <div id="input-progress"></div>
          </div>
          <div id="progress-bar"></div>
        </div>
      </div>
    )
  }

}
相关问题