我有一个关于 react 的聊天应用程序。
我需要以下内容:
- 当用户写一个微笑的名字时,例如
:smile:
应该转换成emojione,而不是 unicode。 - 输入必须是下面的代码。
- 输入中的表情符号应该与对话中的表情相同。
<div contentEditable
styles={this.state.messageInputStyle}
className="message-input">
</div>
我有一个关于 react 的聊天应用程序。
我需要以下内容:
:smile:
应该转换成emojione,而不是 unicode。<div contentEditable
styles={this.state.messageInputStyle}
className="message-input">
</div>
我使用了 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'));
这是使用和道具制作contentEditable
div的好方法。我用它的功能。html
onChange
emojione
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;
}
<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>