单击按钮不会使用draft.js添加内联样式

时间:2018-04-14 13:01:09

标签: javascript reactjs draftjs

我正在尝试使用draft.js将富文本编辑器添加到react项目中。我已经能够添加它并通过遵循他们的文档来处理键盘命令。我还添加了两个按钮来做粗体和斜体,但问题是,当我点击按钮时,编辑器状态不会改变,并且没有添加内联样式但是如果我选择文本并单击按钮样式被添加到该文本。我无法理解我在哪里做错了。

import React, { Component } from 'react';
import {Editor, EditorState, RichUtils} from 'draft-js';
import './App.css';

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {editorState: EditorState.createEmpty()};
        this.onChange = (editorState) => this.setState({editorState});
        this.handleKeyCommand = this.handleKeyCommand.bind(this);
    }

    handleKeyCommand(command, editorState) {
        const newState = RichUtils.handleKeyCommand(editorState, command);
        if (newState) {
            this.onChange(newState);
            return 'handled';
        }
        return 'not-handled';
    }

    _onBoldClick() {
        this.onChange(RichUtils.toggleInlineStyle(
            this.state.editorState, 'BOLD'));
    }

    _onItalicClick() {
        this.onChange(RichUtils.toggleInlineStyle(
            this.state.editorState, 'ITALIC'));
    }

    render() {
        return (
            <div className="App">
                <header className="App-header">
                    <h1 className="App-title">Text formatting using Draft.js</h1>
                </header>
                <div className="toolbar">
                    <button className="btn" onClick={this._onBoldClick.bind(this)}>B</button>
                    <button className="btn" onClick={this._onItalicClick.bind(this)}>I</button>
                </div>
                <div className="notePage">
                    <Editor
                        editorState={this.state.editorState}
                        handleKeyCommand={this.handleKeyCommand}
                        onChange={this.onChange}
                        isCollapsed="true"
                    />
                </div>
            </div>
        );
    }
}

2 个答案:

答案 0 :(得分:3)

这是因为默认情况下onClick导致Editor失去焦点。要解决此问题,请执行以下操作:

  _onBoldClick (e) {
    e.preventDefault()
    this.onChange(RichUtils.toggleInlineStyle(
            this.state.editorState, 'BOLD'))
  }

  _onItalicClick (e) {
    e.preventDefault()
    this.onChange(RichUtils.toggleInlineStyle(
            this.state.editorState, 'ITALIC'))
  }

并将 onClick更改为onMouseDown

<button className='btn' onMouseDown={this._onBoldClick.bind(this)}>B</button>

<button className='btn' onMouseDown={this._onItalicClick.bind(this)}>I</button>

附加说明

始终在顶部加Draft.css

import 'draft-js/dist/Draft.css'

来自the documentation

  

渲染编辑器时应包含此CSS,因为这些样式设置了文本对齐,间距和其他重要功能的默认值。没有它,您可能会遇到块定位,对齐和游标行为的问题。

答案 1 :(得分:0)

您可以在 react 16 with hooks 中尝试这样, 只需通过 e 即可,

import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
import {Editor, EditorState, RichUtils} from 'draft-js';
import 'draft-js/dist/Draft.css';
import './MyEditor.css'

export default function MyEditor() {
  
  const [editorState, setEditorState] = React.useState(
    () => EditorState.createEmpty(),
  );

  
  // tried with onclick (but not working as expected) so used mousedown event 
  const _onBoldClick = () => {
    setEditorState(RichUtils.toggleInlineStyle(editorState, 'BOLD'))
  }  
  const _onBoldMouseDown = (e) => {
    e.preventDefault();
    setEditorState(RichUtils.toggleInlineStyle(editorState, 'BOLD'))
  }

  const _onItalicMouseDown = (e) => {
    e.preventDefault();
    setEditorState(RichUtils.toggleInlineStyle(editorState, 'ITALIC'))
  }

  const _onUnderlineMouseDown = (e) => {
    e.preventDefault();
    setEditorState(RichUtils.toggleInlineStyle(editorState, 'UNDERLINE'))
  }

  return(
    <div>
        <button onMouseDown={ e => { _onBoldMouseDown(e) } }>B</button>
        <button onMouseDown={ e => { _onItalicMouseDown(e) } }><i>I</i></button>
        <button onMouseDown={ e => { _onUnderlineMouseDown(e) } }>U</button>

        <div>
          <Editor 
            textAlignment="left" placeholder="Enter something here" 
            editorState={editorState} onChange={setEditorState} />
        </div>
        
    </div>
  ) 
  
    
}

//ReactDOM.render(<MyEditor />, document.getElementById('container'));