代码之家  ›  专栏  ›  技术社区  ›  Basj

在文本区域或ContentEditable div中键入制表符时检测最后一个写入的字

  •  0
  • Basj  · 技术社区  · 7 年前

    如何检测和选择 桌棋类游戏 被压在 textarea 或内容可编辑 div ?

    我开始用一个缓冲区来缓冲最后写的字符或按键,但后来我注意到有多个角盒:

    • 假设用户写 H e L L U 退格 o

    • 用户使用箭头键移动

    • 用户可以将单词分开 空间 (这就是我所使用的) 进入 或逗号等。

    有没有一种很好的方法来检测最后一个单词?

    目标:对自动完成功能进行编码,例如: thx + <TAB> =>文本替换为“非常感谢”。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Rehan Haider    7 年前

    您可以使用当前光标位置来检测最后一个单词。下面是一个简单的例子。

    document.getElementById('foobar').addEventListener('keydown', e => {
      if( e.which == 9 ) {
        e.preventDefault();
        let endingIndex = e.target.selectionStart;
        let startingIndex = endingIndex && endingIndex - 1;
        let value = e.target.value;
        // putt all delemeters in it by which word can be splitted
        let regex = /[ ]/;
    
        while(startingIndex > -1){
          if(regex.test(value[startingIndex])){
            ++startingIndex;
            break;
          }
          --startingIndex;
        }
    
        // note you will have you apply check to avoid negative index
        if(startingIndex < 0) {
            startingIndex = 0;
        }
        console.log(value.substring(startingIndex, endingIndex));
    
        let newText = "replaced";
        value = value.substring(0, startingIndex) + newText + value.substring(endingIndex);
        let cursorPosition = startingIndex + newText.length;
        e.target.value = value;
        e.target.setSelectionRange(cursorPosition, cursorPosition);
      }
      
    });
    <textarea id="foobar"></textarea>
        2
  •  0
  •   Basj    7 年前

    这完全适用于 textarea 为了 contenteditable div:

    var newText = 'hello\nnewline';
    var newHtml = '<b>test</b> and<br>a <a href="hjkh">link</a>';
    
    document.addEventListener("keydown", function(e) {
        var elt = e.target;
        if (elt.tagName.toLowerCase() === 'textarea' || elt.isContentEditable)
        {        
            if (e.keyCode == 9) {
                e.preventDefault();
                if (elt.isContentEditable) {  // for contenteditable
                    elt.focus();
                    sel = document.getSelection();
                    sel.modify("extend", "backward", "word");
                    range = sel.getRangeAt(0);
                    console.log(range.toString().trim());
                    range.deleteContents();
                    var el = document.createElement("div");
                    el.innerHTML = newHtml;
                    var frag = document.createDocumentFragment(), node;
                    while (node = el.firstChild) {
                        frag.appendChild(node);
                    }
                    range.insertNode(frag);
                    range.collapse();
                } else {  // for texterea/input element
                    var endingIndex = elt.selectionStart;
                    var startingIndex = endingIndex && endingIndex - 1;
                    var value = elt.value;
                    var regex = /[ ]/;
                    while (startingIndex > -1) {
                        if (regex.test(value[startingIndex])) {
                            ++startingIndex;
                            break;
                        }
                        --startingIndex;
                    }
                    if (startingIndex < 0) {
                        startingIndex = 0;
                    }
                    value = value.substring(0, startingIndex) + newText + value.substring(endingIndex);
                    var cursorPosition = startingIndex + newText.length;
                    e.target.value = value;
                    e.target.setSelectionRange(cursorPosition, cursorPosition);
                }
            }
        }
    });
    <div contenteditable>Hello, press TAB to replace this WORD<br>Also press TAB after this ONE</div>
    <textarea rows="8" cols="50" id="a">Hello, press TAB to replace this WORD
    Also press TAB after this ONE</textarea>