无法在 React 应用程序中禁用指针事件 [英] Can't disable pointer-events in React app

查看:36
本文介绍了无法在 React 应用程序中禁用指针事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个 Simon 游戏,其中有 4 个四分之一圆,类名都是colorButton":红色、黄色、蓝色和绿色.

我希望当它轮到计算机时,所有指向 4 个彩色圆圈的指针事件都被禁用,因此您无法点击它们.

在我的代码中我使用:

const colorButtons = document.getElementsByClassName('colorButton');colorButtons.style.pointerEvents = 'none';

但我收到此控制台错误:

未捕获的类型错误:无法设置未定义的属性pointerEvents"在 App.computerMove (http://localhost:8080/bundle.js:14010:42)在 App.startGame (http://localhost:8080/bundle.js:13997:14)

我在这里做错了吗?

完整代码供参考:

import React, { Component } from 'react';从'./colorbutton'导入颜色按钮;导出默认类 App 扩展组件 {构造函数(道具){超级(道具);this.state = {开机:假,开始:假,myTurn:假,compMoves: ['red', 'yellow', 'blue', 'green'],我的移动:[],计数:空};this.colors = ['green', 'red', 'yellow', 'blue'];this.powerOn = this.powerOn.bind(this);this.startGame = this.startGame.bind(this);this.highlightBtn = this.highlightBtn.bind(this);this.computerMove = this.computerMove.bind(this);}开始游戏() {const { powerOn } = this.state;如果(开机){this.setState({ start: true });this.computerMove();}}电脑移动(){如果(!this.state.myTurn){const randNum = Math.floor(Math.random() * 4);const randColor = this.colors[randNum];const count = this.state.count;const colorButtons = document.getElementsByClassName('colorButton');colorButtons.style.pointerEvents = 'none';const compMoves = this.state.compMoves.slice();compMoves.push(randColor);变量 i=0;const repeatMoves = setInterval(() => {this.highlightBtn(compMoves[i]);我++;如果 (i >= compMoves.length) {clearInterval(repeatMoves);}}, 1000);this.setState({compMoves:compMoves,myTurn:真的,计数:计数 + 1});}}高亮Btn(颜色){const audio = document.getElementById(color+'Sound');音频播放();const selectColor = document.getElementById(color);selectColor.style.opacity = 0.5;setTimeout(() =>{ selectColor.style.opacity = 1}, 200);}开机(事件){const { powerOn } = this.state;if (!powerOn) { this.setState({ powerOn: true }) }else { this.setState({ powerOn: false }) }}使成为() {console.log('移动:', this.state.compMoves);const { 计数 } = this.state;返回(

<div className='outer-circle'><颜色按钮颜色='绿色'handleClick={() =>this.highlightBtn('绿色')}/><颜色按钮颜色='红色'handleClick={() =>this.highlightBtn('红色')}/><颜色按钮颜色='黄色'handleClick={() =>this.highlightBtn('黄色')}/><颜色按钮颜色='蓝色'handleClick={() =>this.highlightBtn('蓝色')}/>

<h2>Simon®
<div className='count-display'>{count ?计数:'--'}</div><div className='small-text'>Count</div>

<div className='power-box'><div className='power-text'>OFF</div><label className="switch"><input type="checkbox" onChange={this.powerOn}/><div className="slider round"></div><div className='power-text'>ON</div>

<div className='start-box'><div className='start-button' onClick={this.startGame}></div><div className='small-text'>开始</div>

<div className='strict-button'></div><div className='small-text'>Strict</div>

<p className='footer'><a href='https://github.com/drhectapus/react-simon-game'>Github</a>上的源代码</p>

)}}

解决方案

你的错误的原因是 getElementsByClassName 返回一个类似数组的对象.因此,它没有样式属性.因此, colorButtons.style 是未定义的,而 colorButtons.style.pointerEvents 会导致您的错误.

我还要指出,尽管您的一般方法很不反应.你几乎从不想像这样直接改变 DOM.使用 React,你只是定义组件应该如何呈现给定的 props 和 state.改变 DOM 的一个大问题是,每次触发重新渲染时,您的更改都会被清除.我会考虑用这样的方式处理你想要做的事情:

<颜色按钮颜色='绿色'禁用={ !this.state.myTurn }handleClick={() =>this.highlightBtn('绿色')}/>类 ColorButton 扩展组件 {使成为() {返回 (<div style={{ pointerEvents: this.props.disabled ?'无' : '自动' }}>...

)}}

I'm making a Simon game, where there are 4 quarter circles all with class name 'colorButton': red, yellow blue and green.

I'd like it so that when it's the computer turn, all pointer events to the 4 colored circles are disabled so you can't click on them.

In my code i use:

const colorButtons = document.getElementsByClassName('colorButton');
      colorButtons.style.pointerEvents = 'none';

But I get this console error:

Uncaught TypeError: Cannot set property 'pointerEvents' of undefined
    at App.computerMove (http://localhost:8080/bundle.js:14010:42)
    at App.startGame (http://localhost:8080/bundle.js:13997:14)

Am I doing something wrong here?

Entire code for reference:

import React, { Component } from 'react';

import ColorButton from './colorbutton';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      powerOn: false,
      start: false,
      myTurn: false,
      compMoves: ['red', 'yellow', 'blue', 'green'],
      myMoves: [],
      count: null
    };
    this.colors = ['green', 'red', 'yellow', 'blue'];
    this.powerOn = this.powerOn.bind(this);
    this.startGame = this.startGame.bind(this);
    this.highlightBtn = this.highlightBtn.bind(this);
    this.computerMove = this.computerMove.bind(this);
  }

  startGame() {
    const { powerOn } = this.state;
    if (powerOn) {
      this.setState({ start: true });
      this.computerMove();
    }
  }

  computerMove(){
    if (!this.state.myTurn) {
      const randNum = Math.floor(Math.random() * 4);
      const randColor = this.colors[randNum];
      const count = this.state.count;

      const colorButtons = document.getElementsByClassName('colorButton');
      colorButtons.style.pointerEvents = 'none';

      const compMoves = this.state.compMoves.slice();
      compMoves.push(randColor);

      var i=0;
      const repeatMoves = setInterval(() => {
        this.highlightBtn(compMoves[i]);
        i++;
        if (i >= compMoves.length) {
          clearInterval(repeatMoves);
        }
      }, 1000);

      this.setState({
        compMoves: compMoves,
        myTurn: true,
        count: count + 1
      });
    }
  }

  highlightBtn(color) {
    const audio = document.getElementById(color+'Sound');
    audio.play();

    const selectColor = document.getElementById(color);
    selectColor.style.opacity = 0.5;
    setTimeout(() =>{ selectColor.style.opacity = 1}, 200);
  }

  powerOn(event) {
    const { powerOn } = this.state;
    if (!powerOn) { this.setState({ powerOn: true }) }
    else { this.setState({ powerOn: false }) }
  }

  render() {
    console.log('moves:', this.state.compMoves);
    const { count } = this.state;

    return(
      <div className='container'>
        <div className='outer-circle'>
          <ColorButton
            color='green'
            handleClick={() => this.highlightBtn('green')}
          />
          <ColorButton
            color='red'
            handleClick={() => this.highlightBtn('red')}
           />
          <ColorButton
            color='yellow'
            handleClick={() => this.highlightBtn('yellow')}
          />
          <ColorButton
            color='blue'
            handleClick={() => this.highlightBtn('blue')}
          />
          <div className='inner-circle'>
            <h2>Simon®</h2>
            <div className='count-box'>
              <div className='count-display'>{count ? count : '--'}</div>
              <div className='small-text'>Count</div>
            </div>
          </div>
        </div>
        <div className='controls'>
          <div className='power-box'>
            <div className='power-text'>OFF</div>
            <label className="switch">
              <input type="checkbox" onChange={this.powerOn}/>
              <div className="slider round"></div>
            </label>
            <div className='power-text'>ON</div>
          </div>
          <div className='buttons'>
            <div className='start-box'>
              <div className='start-button' onClick={this.startGame}></div>
              <div className='small-text'>Start</div>
            </div>
            <div className='strict-box'>
              <div className='strict-button'></div>
              <div className='small-text'>Strict</div>
            </div>
          </div>
        </div>

        <p className='footer'>
          Source code on <a href='https://github.com/drhectapus/react-simon-game'>Github</a>
        </p>
      </div>
    )
  }
}

解决方案

The cause of your error is that getElementsByClassName returns an array-like object. Thus, it does not have a style property. Hence, colorButtons.style is undefined and colorButtons.style.pointerEvents causes your error.

I'd also point out though that your general approach is pretty un-react like. You almost never want to mutate the DOM directly like this. With React, you are just defining how a component should render given props and state. One big problem with mutating the DOM is that your changes are going to get wiped away every time a re-render is triggered. I would look into handling what you're trying to do with something like this:

<ColorButton
  color='green'
  disabled={ !this.state.myTurn }
  handleClick={() => this.highlightBtn('green')}
/>

class ColorButton extends Component {
  render() {
    return (
      <div style={{ pointerEvents: this.props.disabled ? 'none' : 'auto' }}>
        ...
      </div>
    )
  }
}

这篇关于无法在 React 应用程序中禁用指针事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆