我正在建立一个聊天,我正在使用一个名为emoji-picker-react
的库,我想将表情符号添加到我的文本字段,然后将其作为消息发送。我使用react,所以我将简化代码的方便。我的信息有用,但我的表情符号不太管用。到目前为止,如果我先点击表情符号,然后再加上一些文字,就没问题了。但如果我先打字,然后试着添加表情符号,就行不通了。而且,如果我想自己发送表情符号,它也不会工作。这是我用来在我的文本框中添加表情符号的方法,两者都是一样的。
这就是我尝试将表情符号添加到我的文本字段的地方,并且正在做我刚刚解释的事情:
const onEmojiClick = (e, emojiObject) => {
document.querySelector("#text").value += emojiObject.emoji
// document.getElementById("text").value += emojiObject.emoji
};
这是我的输入字段:
<input
id="text"
style={inputStyles}
type="text"
placeholder="Type your message"
value={message}
onKeyPress={e => {
if (e.key !== 'Enter') return;
sendMessage(message);
}
}
onChange={e => setMessageForm(e.target.value)}
/>
我肯定是简单的东西,但我无法理解它。我希望有人能指点一下。
谢谢!
@lissettdm答案的小更新
插入表情符号时的常见问题。
插入表情符号后,光标将移动到行尾。
改善回答
光标停留在表情符号所在的位置,以便用户可以输入多个表情符号。
const ref = useRef(null);
const onEmojiClick = (event, emojiObject) => {
const cursor = ref.current.selectionStart;
const text = message.slice(0, cursor) + emojiObject.emoji + message.slice(cursor);
setMessageForm(text);
//Codes added for the new cursor
const newCursor = cursor+emojiObject.emoji.length
setTimeout(() => ref.current.setSelectionRange(newCursor,newCursor), 10)
};
代码解释根据你使用的表情包,emojiObject.emoji
可以是统一的、原生的或id的。常见错误和最大错误是假设1个表情符号= 1个字符(光标+1),事实并非如此。
例如,如果你正在使用emoji-mart,并且你使用emoji。本机,长度为2(不是1)。
const newCursor = cusor+emojiObject.emoji.length
下面将新的光标位置设置为在表情符号之后. 为什么会超时?这是为了让setMessage(text)
有足够的时间来更新dom的新值,在你使用ref设置游标之前。
如果不使用setTimeout
,可能无法正确更新游标。
setTimeout(() => ref.current.setSelectionRange(newCursor,newCursor), 10)
创建对input
节点的引用以获取光标位置并更新消息值:
const ref = useRef(null);
const onEmojiClick = (event, emojiObject) => {
const cursor = ref.current.selectionStart;
const text = message.slice(0, cursor) + emojiObject.emoji + message.slice(cursor);
setMessageForm(text);
};
jsx
<input
id="text"
ref={ref}
...
/>
https://stackblitz.com/edit/react-gg2akb?file=src%2FApp.js
显式设置文本输入的value
不会触发onChange
事件。在保存输入状态的组件中包含表情选择器,并在选择表情符号时调用它的setter(假设你使用功能组件,否则调用this.setState
),将其附加到当前状态。
你可能想要在输入元素上使用ref
和它的selectionStart
属性来读取光标位置,以便在那里插入表情符号。
例如,你可以这样写你的输入组件
import React, { useState, useRef } from 'react'
import /* your EmojiPicker component */
const InputWithEmojiPicker = () => {
const [value, setValue] = useState('')
const inputRef = useRef(null)
const onEmojiClick = (e, emojiObject) => {
const { selectionStart, selectionEnd } = inputRef.current
// replace selected text with clicked emoji
const newVal = value.slice(0, selectionStart) + emojiObject.emoji + value.slice(selectionEnd)
setValue(newValue)
}
return (
<div>
<input type="text" ref={inputRef} value={value} onChange={setValue} />
{/* your EmojiPicker component with onEmojiClick */}
</div>
)
}
export default InputWithEmojiPicker