如何实现与on(实时)emojis的反应?

时间:2018-01-31 21:16:59

标签: javascript reactjs emoji emojione

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

我需要以下内容:

  • 当用户写下微笑名称时,例如:smile:应转换为 emojione 不是unicode
  • 输入必须如下面的代码。
  • 输入中的表情符号应该与他们在对话中看起来一样。
<div contentEditable
     styles={this.state.messageInputStyle}
     className="message-input">
</div>

2 个答案:

答案 0 :(得分:1)

here是一种使用contentEditablehtml道具制作onChange div的好方法。我在emojione的{​​{1}}函数中使用了它。

here is a working codepen

如果您希望它们来自州

,可以将样式添加到shortnameToImage道具中

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

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;
}

答案 1 :(得分:1)

我已经使用emojionethis code snippet基本上提出了一个非反应解决方案,如下所示。希望它有所帮助。

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