Подтвердить что ты не робот

React. preventDefault() для события onCopy не работает

Я пытаюсь выяснить, как сделать события буфера обмена возвратами false в событие onCopy. Я использую для проверки обработчика onCopy и e.preventDefault(). Но текст скопирован без препятствий в буфер! Что мне не хватает?

Благодарим вас в Advance.

import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import ReactDOMServer from 'react-dom/server';
import './index.css';


class Copy extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      time: '',
      timer: false,
      counter: 0
    };

    this.handlerCopy = this.handlerCopy.bind(this);
  }

  handlerCopy(e) {

    e.preventDefault(); // must prevent the current event

    this.setState(prevState => ({
      counter: prevState.counter + 1
    }));

    alert('Don\'t copy it!');
  }

  render() {
    return (
      <React.Fragment>
        <p onCopy={this.handlerCopy}>Copy me!</p>
        <p>Copy count: {this.state.counter}</p>
      </React.Fragment>
    );
  }
}

ReactDOM.render(
<Copy />,
document.getElementById('root'));
4b9b3361

Ответ 1

Это действительно хороший вопрос!

Это происходит, потому что Реагирует фактический прослушиватель событий также находится в корневом документе, то есть событие click уже запустилось в корневой каталог. Вы можете использовать e.nativeEvent.stopImmediatePropagation() для предотвращения других прослушивателей событий.

Попробуйте:

import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import ReactDOMServer from 'react-dom/server';
import './index.css';


class Copy extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      time: '',
      timer: false,
      counter: 0
    };

    this.handlerCopy = this.handlerCopy.bind(this);
  }

  handlerCopy(e) {
    console.log(e.target.innerHTML);
    e.preventDefault();
    e.nativeEvent.stopImmediatePropagation();

    this.setState(prevState => ({
      counter: prevState.counter + 1
    }));

    alert('Don\'t copy it!');
  }

  render() {
    return (
      <React.Fragment>
        <p onCopy={this.handlerCopy}>Copy me!</p>
        <p>Copy count: {this.state.counter}</p>
      </React.Fragment>
    );
  }
}

ReactDOM.render(
<Copy />,
document.getElementById('root'));

Ответ 2

Это должен быть комментарий, но у меня недостаточно репутации. Я думаю, что e.preventDefault() достаточно для (по крайней мере) React 16.

Рабочий пример на Codesandbox

Ответ 3

Вышеупомянутое решение, похоже, не работает для меня, но если говорить о значениях счетчика в состоянии, то его получение управляется должным образом, написав обработчик Копировать ниже (Обновление значений состояния).

import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import ReactDOMServer from 'react-dom/server';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      time: '',
      timer: false,
      counter: 0
    };
  }

   handlerCopy(e) {
    var val = this.state.counter;
    val = val + 1;
    this.setState({
      counter: val
    }, function(){
      console.log('new acounter:- ', this.state.counter);
    })
    alert('Don\'t copy it!');
  }


  render() {
    return (
      <React.Fragment>
        <p onCopy={(e) => this.handlerCopy(e)}>Copy me!</p>
        <p>Copy count: {this.state.counter}</p>
      </React.Fragment>
    );
  }
}
document.addEventListener('click', function(e) {
    console.log('propagation',e)
  }, false);


export default App;

Эта функция handlerCopy, упомянутая выше, не вносит никаких изменений для меня @Max Wolfen

 handlerCopy(e) {
    console.log(e.target.innerHTML);
    e.preventDefault();
    e.nativeEvent.stopImmediatePropagation();

    this.setState(prevState => ({
      counter: prevState.counter + 1
    }));

    alert('Don\'t copy it!');
  }