javascript - 如何将 HTML emoji uni-codes 插入特定插入符号位置的文本区域
问题描述
我有一个文本区域,我正在使用 NGX Emoji mart 将表情符号插入该文本区域。在插入任何表情符号之前,我正在获取文本区域的当前插入符号位置,然后将表情符号推入 ngModel。
问题如果我在文本区域写了一些东西,那么如果我选择一个表情符号,它第一次插入到正确的位置(正确的位置),然后表情符号在开头插入。
问题如何将选定的表情符号插入正确的插入符号位置?
对于表情符号,我正在使用这个插件 - https://www.npmjs.com/package/@ctrl/ngx-emoji-mart
对于插入符号位置,我正在使用 Tim Down 的方法 -在 HTML 输入中获取插入符号位置?
组件.html
<div class="message-block">
<textarea class="message-textarea" #messageElement [(ngModel)]="message" (ngModelChange)="onChangeMessage()"
placeholder="enter your message here.."></textarea>
<div class="emoji-picker-btn" (click)="isEmojiDropdownShown = !isEmojiDropdownShown"></div>
</div>
<div class="emoji-picker" *ngIf="isEmojiDropdownShown">
<emoji-mart (emojiSelect)="onSelectEmoji($event)" isNative="true" perLine="7" showPreview="false">
</emoji-mart>
</div>
组件.ts
public message : string = '';
@ViewChild('messageElement', { static: false }) messageElement: ElementRef;
onChangeMessage(){
console.log('model on change');
}
onSelectEmoji(event : any){
let messageEl : HTMLElement = this.messageElement.nativeElement;
let caretPosition = this.getCaretPosition(withoutPatternEl).start;
this.message = [this.message.slice(0, caretPosition), event.emoji.native,
this.message.slice(caretPosition)].join('');
}
插入符号位置
getCaretPosition(el : any){
let start : number = 0;
let end : number = 0;
let normalizedValue : any;
let range : any;
let textInputRange : any;
let len : any;
let endRange : any;
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
start = el.selectionStart;
end = el.selectionEnd;
} else {
range = (<any>document).selection.createRange();
if (range && range.parentElement() == el) {
len = el.value.length;
normalizedValue = el.value.replace(/\r\n/g, "\n");
// Create a working TextRange that lives only in the input
textInputRange = el.createTextRange();
textInputRange.moveToBookmark(range.getBookmark());
// Check if the start and end of the selection are at the very end
// of the input, since moveStart/moveEnd doesn't return what we want
// in those cases
endRange = el.createTextRange();
endRange.collapse(false);
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
start = end = len;
} else {
start = -textInputRange.moveStart("character", -len);
start += normalizedValue.slice(0, start).split("\n").length - 1;
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
end = len;
} else {
end = -textInputRange.moveEnd("character", -len);
end += normalizedValue.slice(0, end).split("\n").length - 1;
}
}
}
}
return {
start: start,
end: end
};
}
解决方案
推荐阅读
- php - 如何在 wordpress 中构建 ajax 选项卡?
- django - 如何为服务器和客户端只定义一次 URL?
- swift - 如何访问存储在“Any”类型变量中的值
- javascript - 如何获取嵌套对象的默认值,包括零作为值
- amazon-ec2 - 无法将目标组添加到 NLB
- node.js - 如何在并行线程节点js中延迟后运行一行代码?
- azure - 如何从已执行的管道中获取自定义输出?
- mysql - 使用 R 在 MySQL 上的临时 JSON 变量中的双引号
- python-3.x - 如何使用带有 lxml 和 python 的预先存在的 etree 元素创建 xml 文档?
- java - 在条件下将字符串或整数数组转换为逗号分隔的整数或字符串