首页 > 解决方案 > 如何将 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
    };
}

标签: javascriptangular

解决方案


推荐阅读