我正在构建一个聊天,我正在使用一个名为
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.native,则长度为 2(而不是 1)。
const newCursor = cusor+emojiObject.emoji.length
以下将新光标位置设置为表情符号之后。为什么超时?这是为了让
setMessage(text)
在使用 ref 设置光标之前有足够的时间用新值更新 dom。
如果不使用
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}
...
/>
显式设置文本输入的
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
无论何时单击表情符号,您都可以将表情符号附加到现有消息中。
const onEmojiClick = (e) => {
setMessage(`${message}${e.emoji}`)
}
<EmojiPicker className={styles.EmojiPickerReact} onEmojiClick={(e)=> onEmojiClick(e)}/>
然后,将输入/文本区域值属性设置为 message.toString()。
<textarea id='message' placeholder="Send a message" value={message.toString()} onChange={(e) => setMessage(e.target.value)} />
希望这有帮助!