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

在ContentEditable div上的光标前检测并替换单词[重复]

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

    如何在 contenteditable 把它换成别的东西? 这个 works for a textarea 但对于此contentEditable div不适用:

    document.getElementById('a').addEventListener('keydown', e => {
      if (e.which == 9) {
        e.preventDefault();
        let endingIndex = e.target.selectionStart;     // does not work for contenteditable
        let startingIndex = endingIndex && endingIndex - 1;
        let value = e.target.innerHTML;
        let regex = /[ ]/;
    
        while(startingIndex){
          if(regex.test(value[startingIndex])){
            ++startingIndex;
            break;
          }
          --startingIndex;
        }
        console.log('word before cursor: ' + value.substring(startingIndex, endingIndex));
      }
      
    });
    <div contenteditable id="a">Please click here and hit TAB, the word before cursor should be replaced by something else.</div>
    2 回复  |  直到 7 年前
        1
  •  1
  •   Anton Guz    7 年前

    那是因为 selectionStart 是一个只有 HTMLInputElement 对象类型。 也许你想看看这个 gist 或使用 Range 直接接口。

        2
  •  1
  •   Basj    7 年前

    使用 gist 根据antonguz的回答,这对contenteditable都有效 div textarea :

    function getPos(elt) {
        if (elt.isContentEditable) {  // for contenteditable
            elt.focus();
            let _range = document.getSelection().getRangeAt(0);
            let range = _range.cloneRange();
            range.selectNodeContents(elt);
            range.setEnd(_range.endContainer, _range.endOffset)
            return range.toString().length;
        } else {  // for texterea/input element
            return elt.selectionStart;
        }
    }
    
    function setPos(elt, pos) {
        if (elt.isContentEditable) {  // for contenteditable
            elt.target.focus();
            document.getSelection().collapse(elt.target, pos);
        } else {  // for texterea/input element
            elt.target.setSelectionRange(pos, pos);
        }
    }
    
    function insertText(content) {
        document.execCommand('insertText', false, content) 
    }
    
    document.addEventListener("keydown", function(e) {
        if (e.target.tagName.toLowerCase() === 'textarea' || e.target.isContentEditable)
        {        
            if (e.keyCode == 9) {
                e.preventDefault();
                console.log(getPos(e.target));
                
                let endingIndex = getPos(e.target);
                let startingIndex = endingIndex && endingIndex - 1;
                let value = e.target.isContentEditable ? e.target.innerHTML : e.target.value;
                let regex = /[ ]/;
    
                while (startingIndex) {
                    if (regex.test(value[startingIndex])) {
                        ++startingIndex;
                        break;
                    }
                    --startingIndex;
                }
                console.log('word before cursor: ' + value.substring(startingIndex, endingIndex));
            }
        }
    });
    <div contenteditable>Please click here and hit TAB, the word before cursor should be replaced by something else.</div>
    
    <textarea></textarea>