React Draft.js 所见即所得:如何以编程方式在光标位置插入文本?

React Draft.js Wysiwyg: How to programmatically insert text at the cursor location?

我正在使用 React Draft Wysiwyg,我需要将应用程序的一个组件中的任意文本插入到编辑器组件中。我通过剪贴板作为从一个组件传输到另一个组件的中介来执行此操作。但是 document.execCommand('paste') 失败了。

有人知道怎么做吗?

我的示例代码在这里;第三个控制台日志为粘贴结果发出 false。

import React, { Component } from 'react';
import { EditorState, convertToRaw, Modifier } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import draftToHtml from 'draftjs-to-html';
import htmlToDraft from 'html-to-draftjs';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
import styled from 'styled-components';

class EditorConvertToHTML extends Component {
  constructor(props) {
    super(props);
    this.state = {editorState: EditorState.createEmpty()};
    this.onChange = (editorState) => this.setState({editorState});
    this.setEditor = (editor) => {
      this.editor = editor;
    };
    this.focusEditor = () => {
      if (this.editor) {
        this.editor.focusEditor();
        console.log("1. Editor has the focus now");
      }
    };
  }

  componentDidMount() {
    this.focusEditor();
  }

  onEditorStateChange = (editorState) => {
    this.setState({
      editorState,
    });
  };

  sendTextToEditor = (text) => {
    var input = document.createElement('input');
    input.setAttribute('value', text);
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input);

    navigator.clipboard.readText()
    .then(text => {
      this.focusEditor();
      console.log('2. Retrieved pasted text from clipboard = ', text);
      result = document.execCommand('paste');
      console.log("3. Paste command's result = ", result);
    })
    .catch(err => {
      console.error('Failed to read clipboard contents: ', err);
    });

    return result;
  }

  render() {
    const { editorState } = this.state;
    return (
      <>
        <EditorStyled>
          <Editor
            ref={this.setEditor}
            editorState={editorState}
            wrapperClassName="demo-wrapper"
            editorClassName="demo-editor"
            onEditorStateChange={this.onEditorStateChange}
          />
        </EditorStyled>
        <button type="button" onClick={this.sendTextToEditor.bind(this, 'Sample text to put in editor')}>Copy sample text to editor</button>
      </>
    );
  }
}

export default EditorConvertToHTML;

const EditorStyled = styled.div`
  width: ${() => "calc(100% - 40px)"};
  min-height: 400px;
  margin: 20px;
  border: 1px solid black;
`;

提前感谢您的帮助!

多亏了 Rosemarie Robertson 的 explanations/article @ https://dev.to/rose/draft-js-simple-content-manipulation-b7a 我让示例工作了。这是代码:

import React, { Component } from 'react';
import { EditorState, Modifier } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
import styled from 'styled-components';

// Following sample is based the article https://dev.to/rose/draft-js-simple-content-manipulation-b7a

class EditorConvertToHTML extends Component {
  constructor(props) {
    super(props);
    this.state = {editorState: EditorState.createEmpty()};
  }

  componentDidMount() {
    this.focusEditor();
  }

  setEditor = (editor) => {
    this.editor = editor;
  };

  focusEditor = () => {
    if (this.editor) {
      this.editor.focusEditor();
      console.log("1. Editor has the focus now");
    }
  };

  onEditorStateChange = (editorState) => {
    this.setState({
      editorState,
    });
  };

  sendTextToEditor = (text) => {
    this.setState({editorState: this.insertText(text, this.state.editorState)});
    this.focusEditor();
  }

  insertText = (text, editorState) => {
    const currentContent = editorState.getCurrentContent(),
          currentSelection = editorState.getSelection();

    const newContent = Modifier.replaceText(
      currentContent,
      currentSelection,
      text
    );

    const newEditorState = EditorState.push(editorState, newContent, 'insert-characters');
    return  EditorState.forceSelection(newEditorState, newContent.getSelectionAfter());
  }

  render() {
    const { editorState } = this.state;
    return (
      <>
        <EditorStyled>
          <Editor
            ref={this.setEditor}
            editorState={editorState}
            wrapperClassName="demo-wrapper"
            editorClassName="demo-editor"
            onEditorStateChange={this.onEditorStateChange}
          />
        </EditorStyled>
        <button type="button" onClick={this.sendTextToEditor.bind(this, 'Sample text to put in editor')}>Copy sample text to editor</button>
      </>
    );
  }
}

export default EditorConvertToHTML;

const EditorStyled = styled.div`
  width: ${() => "calc(100% - 40px)"};
  min-height: 400px;
  margin: 20px;
  border: 1px solid black;
`;