5

我有一个关于 react 的聊天应用程序。

我需要以下内容:

  • 当用户写一个微笑的名字时,例如:smile:应该转换成emojione而不是 unicode
  • 输入必须是下面的代码。
  • 输入中的表情符号应该与对话中的表情相同。
<div contentEditable
     styles={this.state.messageInputStyle}
     className="message-input">
</div>
4

2 回答 2

1

我使用了 emojione这个代码片段,基本上想出了一个非常无反应的解决方案,如下所示。希望能帮助到你。

import React from 'react';
import {render} from 'react-dom';
import emojione from 'emojione';

class App extends React.Component {

    constructor(props) {
        super(props);
    }

    updateText = () => {
        const html = emojione.shortnameToImage(this.refs.inputDiv.innerHTML);
        let sel, range;

        if (window.getSelection) {
            // IE9 and non-IE
            sel = window.getSelection();

            if (sel.getRangeAt && sel.rangeCount) {
                range = sel.getRangeAt(0);
                range.deleteContents();

                // Range.createContextualFragment() would be useful here but is
                // non-standard and not supported in all browsers (IE9, for one)
                let el = this.refs.inputDiv;
                el.innerHTML = html;
                let frag = document.createDocumentFragment(), node, lastNode;

                while ((node = el.firstChild)) {
                    lastNode = frag.appendChild(node);
                }
                range.insertNode(frag);

                // Preserve the selection
                if (lastNode) {
                    range = range.cloneRange();
                    range.setStartAfter(lastNode);
                    range.collapse(true);
                    sel.removeAllRanges();
                    sel.addRange(range);
                }
            }
        } else if (document.selection && document.selection.type !== "Control") {
            // IE < 9
            document.selection.createRange().pasteHTML(html);
        }
    };


    render() {
        return (
            <div ref="inputDiv" contentEditable onInput={this.updateText}/>
        );
    }

}

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

这是工作示例 https://codesandbox.io/s/ol2lmkqqlq

于 2018-02-03T22:29:42.787 回答
1

是使用和道具制作contentEditablediv的好方法。我用它的功能。htmlonChangeemojioneshortnameToImage

这是一个工作的codepen

ContentEditable如果您希望样式来自该州,则可以将样式添加到道具中

唯一需要修复的是添加表情符号后的插入符号位置。

class Application extends React.Component {
  state = {
    value: "Start Writing Here"
  };

  render() {
    return (
      <ContentEditable
        html={emojione.shortnameToImage(this.state.value)}
        onChange={this._onChange}
      />
    );
  }

  _onChange = e => {
    this.setState({ value: e.target.value });
  };
}

var ContentEditable = React.createClass({
  render: function() {
    return (
      <div
        contentEditable
        className="message-input"
        onInput={this.emitChange}
        onBlur={this.emitChange}
        dangerouslySetInnerHTML={{ __html: this.props.html }}
      />
    );
  },

  shouldComponentUpdate: function(nextProps) {
    return nextProps.html !== this.getDOMNode().innerHTML;
  },

  componentDidUpdate: function() {
    if (this.props.html !== this.getDOMNode().innerHTML) {
      this.getDOMNode().innerHTML = this.props.html;
    }
  },

  emitChange: function() {
    var html = this.getDOMNode().innerHTML;

    if (this.props.onChange && html !== this.lastHtml) {
      this.props.onChange({ target: { value: html } });
    }

    this.lastHtml = html;
  }
});

React.render(<Application />, document.getElementById("app"));
html, body {
  height: 100%
}

.message-input {
  width: 100%;
  height: 100%;
  font-size: 30px;
}

.emojione {
  height: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.min.js"></script>
<div id="app"></div>

于 2018-02-03T17:22:35.637 回答