2.Draftjs 学习笔记-Rich Styling
来源:互联网 发布:六仔信誉盘源码 编辑:程序博客网 时间:2024/05/23 02:02
前提概要
draftjs的编辑器和input的区别就是,draft的值与状态是通过editorstate管理的,对比文档参考这里,editorstate的API 参考这里
正文
本章节主要是文本的简单样式控制,分别通过快捷键和按钮来实现
1. RichUtils and Key Commands(快捷键)
RichUtils has information about the core key commands available to web editors, such as Cmd+B (bold), Cmd+I (italic), and so on.
RichUtils 包含了快捷键映射的功能
继续修改components/MyEditor.js
import React from 'react';import { Editor, EditorState, RichUtils } from 'draft-js';class MyEditor extends React.Component { constructor(props) { super(props); this.state = { editorState: EditorState.createEmpty() }; this.onChange = (editorState) => this.setState({ editorState }); this.handleKeyCommand = this.handleKeyCommand.bind(this); } handleKeyCommand(command) { const newState = RichUtils.handleKeyCommand(this.state.editorState, command); if (newState) { this.onChange(newState); return 'handled'; } return 'not-handled'; } render() { const {editorState} = this.state; return ( <Editor editorState={editorState} handleKeyCommand={this.handleKeyCommand} onChange={this.onChange} /> ); }}MyEditor.propTypes = {};export default MyEditor;
可以在浏览器查看效果,输入一些文字,选中文字使用ctrl+b,和ctrl+i查看效果。
为何返回值是handled和not-handled?更多文档查看如下:
handleKeyCommand
The command argument supplied to handleKeyCommand is a string value, the name of the command to be executed. This is mapped from a DOM key event. See Advanced Topics - Key Binding for more on this, as well as details on why the function returns handled or not-handled.
2. Styling Controls in UI (通过按钮控制样式)
Here’s a super-basic example with a “Bold” button to toggle the BOLD style.
一个通过按钮来实现加粗的例子:
添加如下代码:
class MyEditor extends React.Component { // … _onBoldClick() { this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'BOLD')); } render() { return ( <div> <button onClick={this._onBoldClick.bind(this)}>Bold</button> <Editor editorState={this.state.editorState} handleKeyCommand={this.handleKeyCommand} onChange={this.onChange} /> </div> ); }}
3.添加多种样式按钮操作
修改components/MyEditor.jsx
import React from 'react';import { Editor, EditorState, RichUtils } from 'draft-js';import Immutable from 'immutable';import "draft-js/dist/Draft.css";import styles from './Rich.less'class MyEditor extends React.Component { constructor(props) { super(props); this.state = { editorState: EditorState.createEmpty() }; this.focus = () => this.refs.editor.focus(); this.onChange = (editorState) => this.setState({ editorState }); this.handleKeyCommand = (command) => this._handleKeyCommand(command); this.onTab = (e) => this._onTab(e); this.toggleBlockType = (type) => this._toggleBlockType(type); this.toggleInlineStyle = (style) => this._toggleInlineStyle(style); } _handleKeyCommand(command) { const {editorState} = this.state; const newState = RichUtils.handleKeyCommand(editorState, command); if (newState) { this.onChange(newState); return true; } return false; } _onTab(e) { const maxDepth = 4; this.onChange(RichUtils.onTab(e, this.state.editorState, maxDepth)); } _toggleBlockType(blockType) { this.onChange( RichUtils.toggleBlockType( this.state.editorState, blockType ) ); } _toggleInlineStyle(inlineStyle) { this.onChange( RichUtils.toggleInlineStyle( this.state.editorState, inlineStyle ) ); } render() { const {editorState} = this.state; // If the user changes block type before entering any text, we can // either style the placeholder or hide it. Let's just hide it now. let className = styles['RichEditor-editor']; var contentState = editorState.getCurrentContent(); if (!contentState.hasText()) { if (contentState.getBlockMap().first().getType() !== 'unstyled') { className += ' ' + styles['RichEditor-hidePlaceholder']; } } return ( <div className={styles["RichEditor-root"]}> <BlockStyleControls editorState={editorState} onToggle={this.toggleBlockType} /> <InlineStyleControls editorState={editorState} onToggle={this.toggleInlineStyle} /> <div className={className} onClick={this.focus}> <Editor blockStyleFn={getBlockStyle} customStyleMap={styleMap} editorState={editorState} handleKeyCommand={this.handleKeyCommand} onChange={this.onChange} onTab={this.onTab} placeholder="Tell a story..." onFocus={()=>{console.log('focus')}} ref='editor' spellCheck={true} /> </div> </div> ); }}const styleMap = { CODE: { backgroundColor: 'rgba(0, 0, 0, 0.05)', fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace', fontSize: 16, padding: 2, },};function getBlockStyle(block) { switch (block.getType()) { case 'blockquote': return styles['RichEditor-blockquote']; default: return null; }}class StyleButton extends React.Component { constructor() { super(); this.onToggle = (e) => { e.preventDefault(); this.props.onToggle(this.props.style); }; } render() { let className = styles['RichEditor-styleButton']; if (this.props.active) { className += ' ' + styles['RichEditor-activeButton']; } return ( <span className={className} onMouseDown={this.onToggle}> {this.props.label} </span> ); }}const BLOCK_TYPES = [ { label: 'H1', style: 'header-one' }, { label: 'H2', style: 'header-two' }, { label: 'H3', style: 'header-three' }, { label: 'H4', style: 'header-four' }, { label: 'H5', style: 'header-five' }, { label: 'H6', style: 'header-six' }, { label: 'Blockquote', style: 'blockquote' }, { label: 'UL', style: 'unordered-list-item' }, { label: 'OL', style: 'ordered-list-item' }, { label: 'Code Block', style: 'code-block' },];const BlockStyleControls = (props) => { const {editorState} = props; const selection = editorState.getSelection(); const blockType = editorState .getCurrentContent() .getBlockForKey(selection.getStartKey()) .getType(); return ( <div className={styles["RichEditor-controls"]}> {BLOCK_TYPES.map((type) => <StyleButton key={type.label} active={type.style === blockType} label={type.label} onToggle={props.onToggle} style={type.style} /> )} </div> );};var INLINE_STYLES = [ { label: 'Bold', style: 'BOLD' }, { label: 'Italic', style: 'ITALIC' }, { label: 'Underline', style: 'UNDERLINE' }, { label: 'Monospace', style: 'CODE' },];const InlineStyleControls = (props) => { var currentStyle = props.editorState.getCurrentInlineStyle(); return ( <div className={styles["RichEditor-controls"]}> {INLINE_STYLES.map(type => <StyleButton key={type.label} active={currentStyle.has(type.style)} label={type.label} onToggle={props.onToggle} style={type.style} /> )} </div> );};MyEditor.propTypes = {};export default MyEditor;
样式文件 component/Rich.less
.RichEditor-root { background: #fff; border: 1px solid #ddd; font-family: 'Georgia', serif; font-size: 14px; padding: 15px;}.RichEditor-editor { border-top: 1px solid #ddd; cursor: text; font-size: 16px; margin-top: 10px;}.RichEditor-editor .public-DraftEditorPlaceholder-root,.RichEditor-editor .public-DraftEditor-content { margin: 0 -15px -15px; padding: 15px;}.RichEditor-editor .public-DraftEditor-content { min-height: 100px;}.RichEditor-hidePlaceholder .public-DraftEditorPlaceholder-root { display: none;}.RichEditor-editor .RichEditor-blockquote { border-left: 5px solid #eee; color: #666; font-family: 'Hoefler Text', 'Georgia', serif; font-style: italic; margin: 16px 0; padding: 10px 20px;}.RichEditor-editor .public-DraftStyleDefault-pre { background-color: rgba(0, 0, 0, 0.05); font-family: 'Inconsolata', 'Menlo', 'Consolas', monospace; font-size: 16px; padding: 20px;}.RichEditor-controls { font-family: 'Helvetica', sans-serif; font-size: 14px; margin-bottom: 5px; user-select: none;}.RichEditor-styleButton { color: #999; cursor: pointer; margin-right: 16px; padding: 2px 0; display: inline-block;}.RichEditor-activeButton { color: #5890ff;}
- 2.Draftjs 学习笔记-Rich Styling
- 1.Draftjs 学习笔记
- 3.Draftjs 学习笔记-Entities
- 4.Draftjs 学习笔记-Decorators
- 7.Draftjs 学习笔记-StateToHtml
- 《Painting and Styling》学习笔记
- 5.Draftjs 学习笔记-自定义控件(多媒体)
- VC++学习笔记(1)------关于Rich Edit控件
- [初探CAB]:Introduction to CAB/SCSF by Rich Newman 学习笔记
- 【深度学习论文笔记】Rich feature hierarchies for accurate object detection and semantic segmentation
- rcnn学习笔记:Rich feature hierarchies for accurate object detection and semantic segmentation
- RCNN学习笔记(1):Rich feature hierarchies for accurate object detection and semantic segmentation
- RCNN学习笔记(2):Rich feature hierarchies for accurate object detection and semantic segmentation
- 【深度学习-RNN】Rich feature hierarchies for accurate object detection and semantic segmentation笔记
- RCNN学习笔记(1):Rich feature hierarchies for accurate object detection and semantic segmentation
- RCNN学习笔记(2):Rich feature hierarchies for accurate object detection and semantic segmentation
- 【转】R-CNN学习笔记2:Rich feature hierarchies for accurate object detection and semantic segmentation
- RCNN学习笔记(1):Rich feature hierarchies for accurate object detection and semantic segmentation
- java笔记--关于线程同步(7种同步方式)
- 双机热备
- Android6.0 WMS(三) WMS窗口次序
- 算法训练 矩阵乘法
- 浅析Java中的集合包(ArrayList,LinkedList,Vector, Stack,HashSet,TreeSet,HashMap,TreeMap)
- 2.Draftjs 学习笔记-Rich Styling
- 我是怎么从0开始跑通ORBSLAM2+kinectv1的(win8或者win10)
- 第十四周项目1(3)--验证二叉排序树相关算法
- 叠罗汉1(最长递增子序列)
- .CreateFeatureClass报错原因解析
- 第六章 数据存储全方案-详解持久化技术
- UVa 10859 Placing Lampposts
- 集成Spring+SpringMVC+Mybatis+Shiro+Maven+JUnit的Java Web框架
- 1 + 2 - 3 + 4........n 提高运行速度