source

현재 커서 위치의 텍스트 영역에 텍스트를 삽입하는 방법은 무엇입니까?

nicesource 2023. 8. 2. 09:13
반응형

현재 커서 위치의 텍스트 영역에 텍스트를 삽입하는 방법은 무엇입니까?

사용자의 커서 위치에 있는 텍스트 영역에 텍스트를 추가하는 간단한 기능을 만들고 싶습니다.깨끗한 기능이 필요합니다.그냥 기본.나머지는 제가 해결할 수 있습니다.

사용하다selectionStart/selectionEnd 입력 요소의 속성(작업 대상)<textarea>또한)

function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
        myField.focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    //MOZILLA and others
    else if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        myField.value = myField.value.substring(0, startPos)
            + myValue
            + myField.value.substring(endPos, myField.value.length);
    } else {
        myField.value += myValue;
    }
}

이 스니펫은 jQuery 1.9+: http://jsfiddle.net/4MBUG/2/ 의 몇 줄에서 도움이 될 수 있습니다.

$('input[type=button]').on('click', function() {
    var cursorPos = $('#text').prop('selectionStart');
    var v = $('#text').val();
    var textBefore = v.substring(0,  cursorPos);
    var textAfter  = v.substring(cursorPos, v.length);

    $('#text').val(textBefore + $(this).val() + textAfter);
});

새 답변:

https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setRangeText

하지만 이것에 대한 브라우저 지원에 대해서는 잘 모르겠습니다.

Chrome 81에서 테스트됨.

function typeInTextarea(newText, el = document.activeElement) {
  const [start, end] = [el.selectionStart, el.selectionEnd];
  el.setRangeText(newText, start, end, 'select');
}

document.getElementById("input").onkeydown = e => {
  if (e.key === "Enter") typeInTextarea("lol");
}
<input id="input" />
<br/><br/>
<div>Press Enter to insert "lol" at caret.</div>
<div>It'll replace a selection with the given text.</div>

이전 답변:

Erik Pukinskis의 대답을 JS로 순수하게 수정했습니다.

function typeInTextarea(newText, el = document.activeElement) {
  const start = el.selectionStart
  const end = el.selectionEnd
  const text = el.value
  const before = text.substring(0, start)
  const after  = text.substring(end, text.length)
  el.value = (before + newText + after)
  el.selectionStart = el.selectionEnd = start + newText.length
  el.focus()
}

document.getElementById("input").onkeydown = e => {
  if (e.key === "Enter") typeInTextarea("lol");
}
<input id="input" />
<br/><br/>
<div>Press Enter to insert "lol" at caret.</div>

Chrome 47, 81 및 Firefox 76에서 테스트되었습니다.

동일한 필드에 입력하는 동안(자동 완성 또는 유사한 효과의 경우) 현재 선택한 텍스트의 값을 변경하려면 다음을 선택합니다.document.activeElement첫 번째 매개 변수로 사용합니다.

이것은 가장 우아한 방법은 아니지만 꽤 간단합니다.

사용 예:

typeInTextarea('hello');
typeInTextarea('haha', document.getElementById('some-id'));

적절한 자바스크립트를 위해.

HTMLTextAreaElement.prototype.insertAtCaret = function (text) {
  text = text || '';
  if (document.selection) {
    // IE
    this.focus();
    var sel = document.selection.createRange();
    sel.text = text;
  } else if (this.selectionStart || this.selectionStart === 0) {
    // Others
    var startPos = this.selectionStart;
    var endPos = this.selectionEnd;
    this.value = this.value.substring(0, startPos) +
      text +
      this.value.substring(endPos, this.value.length);
    this.selectionStart = startPos + text.length;
    this.selectionEnd = startPos + text.length;
  } else {
    this.value += text;
  }
};

파이어폭스, 크롬, 오페라, 사파리 및 에지에서 작동하는 간단한 솔루션이지만 이전 IE 브라우저에서는 작동하지 않을 수 있습니다.

var target = document.getElementById("mytextarea_id")

if (target.setRangeText) {
    //if setRangeText function is supported by current browser
    target.setRangeText(data)
} else {
    target.focus()
    document.execCommand('insertText', false /*no UI*/, data);
}

setRangeText함수를 사용하여 현재 선택 영역을 제공된 텍스트로 대체하거나 선택 영역이 없는 경우 커서 위치에 텍스트를 삽입할 수 있습니다.파이어폭스에서만 지원되는 것으로 알고 있습니다.

다른 브라우저의 경우 현재 초점을 맞춘 HTML 요소에만 영향을 미치고 다음과 같은 동작을 갖는 "insertText" 명령이 명령은setRangeText

기사에서 부분적으로 영감을 받았습니다.

저는 간단한 자바스크립트를 좋아하고, 주로 jQuery를 가지고 있습니다.가 생각해 낸 것은 다음과 같습니다.

function typeInTextarea(el, newText) {
    var start = el.prop("selectionStart")
    var end = el.prop("selectionEnd")
    var text = el.val()
    var before = text.substring(0, start)
    var after  = text.substring(end, text.length)
    el.val(before + newText + after)
    el[0].selectionStart = el[0].selectionEnd = start + newText.length
    el.focus()
}

$("button").on("click", function() {
    typeInTextarea($("textarea"), "some text")
    return false
})

여기 데모가 있습니다. http://codepen.io/erikpukinskis/pen/EjaaMY?editors=101

Rab의 답변은 훌륭하지만 Microsoft Edge에는 적합하지 않기 때문에 Edge에 대한 작은 적응형도 추가했습니다.

https://jsfiddle.net/et9borp4/

function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
        myField.focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    // Microsoft Edge
    else if(window.navigator.userAgent.indexOf("Edge") > -1) {
      var startPos = myField.selectionStart; 
      var endPos = myField.selectionEnd; 

      myField.value = myField.value.substring(0, startPos)+ myValue 
             + myField.value.substring(endPos, myField.value.length); 

      var pos = startPos + myValue.length;
      myField.focus();
      myField.setSelectionRange(pos, pos);
    }
    //MOZILLA and others
    else if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        myField.value = myField.value.substring(0, startPos)
            + myValue
            + myField.value.substring(endPos, myField.value.length);
    } else {
        myField.value += myValue;
    }
}

function insertAtCaret(text) {
  const textarea = document.querySelector('textarea')
  textarea.setRangeText(
    text,
    textarea.selectionStart,
    textarea.selectionEnd,
    'end'
  )
}

setInterval(() => insertAtCaret('Hello'), 3000)
<textarea cols="60">Stack Overflow Stack Exchange Starbucks Coffee</textarea>

텍스트를 삽입한 후 사용자가 입력을 터치하지 않으면 '입력' 이벤트가 트리거되지 않으며 값 속성이 변경 내용을 반영하지 않습니다.따라서 텍스트를 프로그래밍 방식으로 삽입한 후 입력 이벤트를 트리거하는 것이 중요합니다.필드에 초점을 맞추는 것만으로는 충분하지 않습니다.

다음은 끝에 입력 트리거가 있는 Snorvarg의 답변 사본입니다.

function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
        myField.focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    // Microsoft Edge
    else if(window.navigator.userAgent.indexOf("Edge") > -1) {
      var startPos = myField.selectionStart; 
      var endPos = myField.selectionEnd; 

      myField.value = myField.value.substring(0, startPos)+ myValue 
             + myField.value.substring(endPos, myField.value.length); 

      var pos = startPos + myValue.length;
      myField.focus();
      myField.setSelectionRange(pos, pos);
    }
    //MOZILLA and others
    else if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        myField.value = myField.value.substring(0, startPos)
            + myValue
            + myField.value.substring(endPos, myField.value.length);
    } else {
        myField.value += myValue;
    }
    triggerEvent(myField,'input');
}

function triggerEvent(el, type){
  if ('createEvent' in document) {
    // modern browsers, IE9+
    var e = document.createEvent('HTMLEvents');
    e.initEvent(type, false, true);
    el.dispatchEvent(e);
  } else {
    // IE 8
    var e = document.createEventObject();
    e.eventType = type;
    el.fireEvent('on'+e.eventType, e);
  }
}

triggerEvent 함수에 대한 크레딧은 plainjs.com 에 있습니다.

oninput 이벤트에 대한 자세한 내용은 w3schools.com 을 참조하십시오.

저는 채팅을 위한 이모티콘 선택기를 만들다가 이것을 발견했습니다.사용자가 이모티콘 몇 개를 선택하고 "보내기" 버튼을 누르면 입력 필드가 사용자에 의해 터치되지 않습니다.값 속성을 확인할 때 입력 필드에 삽입된 이모지 유니코드가 표시되더라도 항상 비어 있었습니다.사용자가 필드를 터치하지 않으면 '입력' 이벤트가 발생하지 않으며 해결책은 이렇게 트리거하는 것이었습니다.이걸 알아내는데 꽤 오랜 시간이 걸렸습니다누군가에게 시간을 좀 절약해 주기를 바랍니다.

아래 코드는 드미트리 쿠비슈킨이 https://github.com/grassator/insert-text-at-cursor 패키지를 타이프스크립트로 변환한 것입니다.


/**
 * Inserts the given text at the cursor. If the element contains a selection, the selection
 * will be replaced by the text.
 */
export function insertText(input: HTMLTextAreaElement | HTMLInputElement, text: string) {
  // Most of the used APIs only work with the field selected
  input.focus();

  // IE 8-10
  if ((document as any).selection) {
    const ieRange = (document as any).selection.createRange();
    ieRange.text = text;

    // Move cursor after the inserted text
    ieRange.collapse(false /* to the end */);
    ieRange.select();

    return;
  }

  // Webkit + Edge
  const isSuccess = document.execCommand("insertText", false, text);
  if (!isSuccess) {
    const start = input.selectionStart;
    const end = input.selectionEnd;
    // Firefox (non-standard method)
    if (typeof (input as any).setRangeText === "function") {
      (input as any).setRangeText(text);
    } else {
      if (canManipulateViaTextNodes(input)) {
        const textNode = document.createTextNode(text);
        let node = input.firstChild;

        // If textarea is empty, just insert the text
        if (!node) {
          input.appendChild(textNode);
        } else {
          // Otherwise we need to find a nodes for start and end
          let offset = 0;
          let startNode = null;
          let endNode = null;

          // To make a change we just need a Range, not a Selection
          const range = document.createRange();

          while (node && (startNode === null || endNode === null)) {
            const nodeLength = node.nodeValue.length;

            // if start of the selection falls into current node
            if (start >= offset && start <= offset + nodeLength) {
              range.setStart((startNode = node), start - offset);
            }

            // if end of the selection falls into current node
            if (end >= offset && end <= offset + nodeLength) {
              range.setEnd((endNode = node), end - offset);
            }

            offset += nodeLength;
            node = node.nextSibling;
          }

          // If there is some text selected, remove it as we should replace it
          if (start !== end) {
            range.deleteContents();
          }

          // Finally insert a new node. The browser will automatically
          // split start and end nodes into two if necessary
          range.insertNode(textNode);
        }
      } else {
        // For the text input the only way is to replace the whole value :(
        const value = input.value;
        input.value = value.slice(0, start) + text + value.slice(end);
      }
    }

    // Correct the cursor position to be at the end of the insertion
    input.setSelectionRange(start + text.length, start + text.length);

    // Notify any possible listeners of the change
    const e = document.createEvent("UIEvent");
    e.initEvent("input", true, false);
    input.dispatchEvent(e);
  }
}

function canManipulateViaTextNodes(input: HTMLTextAreaElement | HTMLInputElement) {
  if (input.nodeName !== "TEXTAREA") {
    return false;
  }
  let browserSupportsTextareaTextNodes;
  if (typeof browserSupportsTextareaTextNodes === "undefined") {
    const textarea = document.createElement("textarea");
    textarea.value = "1";
    browserSupportsTextareaTextNodes = !!textarea.firstChild;
  }
  return browserSupportsTextareaTextNodes;
}

자신의 참조를 위해 수정된 함수를 게시하고 있습니다.에서는 " 예는선택항삽입다니합목을한이제▁from다▁a▁item"에서 한 항목을 삽입합니다.<select>개체 및 캐럿을 태그 사이에 넣습니다.

//Inserts a choicebox selected element into target by id
function insertTag(choicebox,id) {
    var ta=document.getElementById(id)
    ta.focus()
    var ss=ta.selectionStart
    var se=ta.selectionEnd
    ta.value=ta.value.substring(0,ss)+'<'+choicebox.value+'>'+'</'+choicebox.value+'>'+ta.value.substring(se,ta.value.length)
    ta.setSelectionRange(ss+choicebox.value.length+2,ss+choicebox.value.length+2)
}
/**
 * Usage "foo baz".insertInside(4, 0, "bar ") ==> "foo bar baz"
 */
String.prototype.insertInside = function(start, delCount, newSubStr) {
    return this.slice(0, start) + newSubStr + this.slice(start + Math.abs(delCount));
};

$('textarea').bind("keydown keypress", function (event) {
    var val = $(this).val();
    var indexOf = $(this).prop('selectionStart');
    if(event.which === 13) {
        val = val.insertInside(indexOf, 0,  "<br>\n");
        $(this).val(val);
        $(this).focus();
    }
});

아드리아노의 답변을 확장하면 "텍스트 바꾸기"가 작동하도록 커서 끝을 고려할 수도 있습니다.

$('input[type=button]').on('click', function() {
    var cursorStart = $('#text').prop('selectionStart');
    var cursorEnd = $('#text').prop('selectionEnd');
    var v = $('#text').val();
    var textBefore = v.substring(0,cursorStart);
    var textAfter  = v.substring(cursorEnd);
    $('#text').val(textBefore + $(this).val() + textAfter);
});

로변됨으로 .getElementById(myField):

function insertAtCursor(myField, myValue) {
    // IE support
    if (document.selection) {
        document.getElementById(myField).focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    // MOZILLA and others
    else if (document.getElementById(myField).selectionStart || document.getElementById(myField).selectionStart == '0') {
        var startPos = document.getElementById(myField).selectionStart;
        var endPos = document.getElementById(myField).selectionEnd;
        document.getElementById(myField).value =
                document.getElementById(myField).value.substring(0, startPos)
                + myValue
                + document.getElementById(myField).value.substring(endPos, document.getElementById(myField).value.length);
    } else {
        document.getElementById(myField).value += myValue;
    }
}

언급URL : https://stackoverflow.com/questions/11076975/how-to-insert-text-into-the-textarea-at-the-current-cursor-position

반응형