如何实现对类型(实时)表情符号的反应?



我有一个在 react 上写的聊天应用程序。

我需要以下内容:

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

这里有一个用htmlonChange道具制作contentEditablediv的好方法。 我将其与emojioneshortnameToImage函数一起使用。

这是一个有效的代码笔

如果您希望样式来自状态,可以将样式添加到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>

我使用了表情符号和这个代码片段,基本上提出了一个非常无反应的解决方案,如下所示。希望对您有所帮助。

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

最新更新