将表情符号添加到输入
Add emojis to input
我正在聊天,我正在使用一个名为 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)}
/>
我确信这很简单,但我无法理解它。希望有人能指导一下。
谢谢!
明确设置文本输入的 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
创建对 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}
...
/>
对@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)
有足够的时间用新值更新 dom,然后再使用 ref 设置光标。
如果不使用setTimeout
,光标可能无法正确更新。
setTimeout(() => ref.current.setSelectionRange(newCursor,newCursor), 10)
我正在聊天,我正在使用一个名为 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)}
/>
我确信这很简单,但我无法理解它。希望有人能指导一下。
谢谢!
明确设置文本输入的 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
创建对 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}
...
/>
对@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)
有足够的时间用新值更新 dom,然后再使用 ref 设置光标。
如果不使用setTimeout
,光标可能无法正确更新。
setTimeout(() => ref.current.setSelectionRange(newCursor,newCursor), 10)