텍스트 영역 변경 감지


132

자바 스크립트를 사용하여 텍스트 영역에서 변경 이벤트를 어떻게 감지합니까?
입력 할 때 남은 문자 수를 감지하려고합니다.

onchange 이벤트를 사용해 보았지만 초점이 맞지 않을 때만 시작됩니다.

답변:


97

당신은 사용해야합니다 onkeyup 및 onchange 이를 위해. onchange는 상황에 맞는 메뉴 붙여 넣기를 방지하고 모든 키 입력시 onkeyup이 실행됩니다.

코드 샘플 은 textArea 에 maxlength를 부과하는 방법에 대한 답변을 참조하십시오 .


3
Josh가 이미 말한 것을 강조하고 싶었습니다. 키 다운이 아니라 키 업을 사용해야한다고 강조하고 싶었습니다. 실제로 텍스트 영역이 변경되기 전에 키 다운이 호출 된 것 같습니다. 따라서 잘못된 길이를 사용하게 될 것입니다. t 당신이 얼마나 떨어져 있는지 정말로 알고 있습니다 : 입력하거나 삭제할 수 있으며 텍스트를 선택하여 +/- 1 이상을 의미 할 수 있습니다).
— brianmearns

65
나는 여기에 -1을주고있다, 미안하다! onkeyup입력 감지에 대한 끔찍한 이벤트입니다. oninput및 onpropertychange(IE 지원을 위해)를 사용하십시오 .
— Andy E

6
은 "유일한"문제가 onchange되는 NOT 컨텍스트 메뉴 잘라 내기 / 붙여 넣기가 발생하면 발사했다.
— Tom

4
onkeydown 및 setTimeout을 사용하면 키가 릴리스되기를 기다리지 않고 즉각적인 변경 감지 기능을 사용할 수 있습니다. 잘라 내기 및 붙여 넣기도 잡아야하는 경우 잘라 내기 및 붙여 넣기 이벤트를 사용하십시오.
— Kevin B

1
경고 : onkeyup은 문제를 일으킬 수 있습니다. 예 : 입력 내용이 변경된 경우에만 수행해야한다고 가정합니다. 키업이 입력을 변경한다고 가정하면 사실이 아닙니다. 입력에 집중하십시오. "탭"을 사용하여 다음 필드로 이동하십시오. 이제 "shift + tab"을 사용하여 입력으로 돌아갑니다. 키업이 발생했지만 사용자가 실제로 입력을 변경하지 않았습니다.
— Zig Mandel

117

2012 년, PC 이후 시대가 여기에 있으며, 우리는 여전히 이와 같은 기본적인 문제로 어려움을 겪고 있습니다. 이것은 매우 간단 해야합니다 .

그 꿈이 성취 될 때까지 여기에 가장 좋은 방법은 다음과 같습니다. 브라우저 : 와 이벤트 의 조합을 사용하십시오inputonpropertychange .

var area = container.querySelector('textarea');
if (area.addEventListener) {
  area.addEventListener('input', function() {
    // event handling code for sane browsers
  }, false);
} else if (area.attachEvent) {
  area.attachEvent('onpropertychange', function() {
    // IE-specific event handling code
  });
}

이 input이벤트는 IE9 +, FF, Chrome, Opera 및 Safari 를 onpropertychange처리하고 IE8을 처리합니다 (IE6 및 7에서도 작동하지만 몇 가지 버그가 있음).

사용의 장점 input과 onpropertychange그들이 (가압 때처럼 불필요하게 발생하지 않는다는 것입니다 Ctrl또는 Shift키); 따라서 텍스트 영역 내용이 변경 될 때 상대적으로 비싼 작업을 실행하려면이 방법을 사용하십시오 .

이제 IE는 항상 그렇듯이 절반을 지원하는 작업을 수행합니다. 텍스트 영역에서 문자가 삭제 될 때 IE input에서도 onpropertychange실행 되지 않습니다 . 따라서 IE에서 문자 삭제를 처리 해야하는 경우 (사용자가 키를 누르고있는 경우에도 한 번만 실행되므로 / 사용과 반대)를 사용 하십시오.keypresskeyupkeydown

출처 : http://www.alistapart.com/articles/expanding-text-areas-made-elegant/

편집 : 주석에서 올바르게 지적했듯이 위의 솔루션조차 완벽하지 않은 것 같습니다 addEventListener. 텍스트 영역에 속성 이 있다고해서 정상적인 브라우저로 작업하고 있음을 의미하지는 않습니다 . 마찬가지로 attachEvent속성 의 존재는 IE를 의미 하지 않습니다 . 코드를 완전히 기밀로 유지하려면 코드를 변경하는 것이 좋습니다. 포인터에 대해서는 Tim Down의 주석 을 참조하십시오 .


1
이것이 가장 좋은 방법입니다. 나는 여기서 추론을 좋아하지 않는다 (브라우저 지원 addEventListener은 input이벤트 지원을 의미하지 않으며 그 반대도 마찬가지이다). 기능 감지가 더 좋습니다. 이에 대한 토론은 이 블로그 게시물 을 참조하십시오 .
— Tim Down

이것에 대해 Tim과 완전히 동의하십시오. oninput이 작업을 수행하는 방법이지만 addEventListener브라우저 지원을위한 테스트 로 사용해서는 안됩니다 . 어쨌든 +1
— Ben D

1
동의하지 않으면 입력이 IE9를 처리하지 않습니다. 불행히도 컨텍스트 메뉴를 통한 잘라 내기 / 붙여 넣기도 입력되며 백 스페이스도 마찬가지입니다. 나는 테스트를 귀찮게하지 않았지만 IE10 +가 그 문제를 해결 한 내기에 돈을 쓰지 않을 것입니다.
— Stefan Steiger

1
@StefanSteiger 그렇기 때문에 keypressIE9 (및 이후 버전)에서도 해당 사건을 처리하기 위해 이벤트를 사용하는 것이 좋습니다 .
— Vicky Chijwani

input.oninput객체 속성 을 구현하여 이벤트 핸들러를 정의 할 수도 있습니다 .
— 핸들

20
  • Google-Chrome의 경우 입력이 충분합니다 (Windows 7 버전 22.0.1229.94 m에서 테스트 됨).
  • IE 9의 경우 oninput은 컨텍스트 메뉴 및 백 스페이스를 통한 잘라내기를 제외한 모든 것을 포착합니다.
  • IE 8의 경우, oninput 외에도 붙여 넣기를 잡으려면 onpropertychange가 필요합니다.
  • IE 9 + 8의 경우 백 스페이스를 잡으려면 키업이 필요합니다.
  • IE 9 + 8의 경우 컨텍스트 메뉴를 통해 절단을 잡는 유일한 방법은 onmousemove입니다.

Firefox에서는 테스트되지 않았습니다.

    var isIE = /*@cc_on!@*/false; // Note: This line breaks closure compiler...

    function SuperDuperFunction() {
        // DoSomething
    }


    function SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally() {
        if(isIE) // For Chrome, oninput works as expected
            SuperDuperFunction();
    }

<textarea id="taSource"
          class="taSplitted"
          rows="4"
          cols="50"
          oninput="SuperDuperFunction();"
          onpropertychange="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();"
          onmousemove="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();"
          onkeyup="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();">
Test
</textarea>

1
멋진 기능 이름 :)
— Jonas Gröger

8

나는 이것이 당신의 질문이 아니라는 것을 알고 있지만 이것이 유용 할 것이라고 생각했습니다. 특정 응용 프로그램의 경우 키를 누를 때마다 변경 기능이 실행되지 않는 것이 좋습니다. 이것은 다음과 같은 방법으로 달성 할 수 있습니다.

var text = document.createElement('textarea');
text.rows = 10;
text.cols = 40;
document.body.appendChild(text);

text.onkeyup = function(){
var callcount = 0;
    var action = function(){
        alert('changed');
    }
    var delayAction = function(action, time){
        var expectcallcount = callcount;
        var delay = function(){
            if(callcount == expectcallcount){
                action();
            }
        }
        setTimeout(delay, time);
    }
    return function(eventtrigger){
        ++callcount;
        delayAction(action, 1200);
    }
}();

특정 지연 시간 내에 최신 이벤트가 발생했는지 테스트하여 작동합니다. 행운을 빕니다!


1
'스로틀 링'지연 조치의 경우 +1! 내 앱에서 비슷한 것을 사용합니다.
— psulek

7

이 질문은 JavaScript에만 해당된다는 것을 알고 있지만 현재 모든 브라우저에서 텍스트 영역이 변경 될 때 항상 감지 할 수있는 좋은 방법은 없습니다. jquery가 우리를 위해 그것을 돌 보았다는 것을 배웠습니다. 텍스트 영역의 상황에 맞는 메뉴 변경 사항도 처리합니다. 입력 유형에 관계없이 동일한 구문이 사용됩니다.

    $('div.lawyerList').on('change','textarea',function(){
      // Change occurred so count chars...
    });

또는

    $('textarea').on('change',function(){
      // Change occurred so count chars...
    });

4
변경 이벤트가 일반 JS보다 jQuery와 더 일관성이 없다는 것을 알았습니다. jQuery를 bind("input cut paste"...사용했으며 키보드 또는 상황에 맞는 메뉴를 사용하여 입력, 잘라 내기 및 붙여 넣기의 매력처럼 작동합니다. 드래그 앤 드롭 텍스트도 가능합니다.
— Lawrence Dol 2013

2
불행히도 FF는에 change대한 이벤트를 발생시키지 않습니다 textarea.
— dma_k

4

텍스트 영역 변경시 이벤트를 듣고 원하는대로 변경할 수 있습니다. 한 가지 예가 있습니다.

(() => {
	const textArea = document.getElementById('my_text_area');
  textArea.addEventListener('input', () => {
    let textLn =  textArea.value.length;
    if(textLn >= 100) {
      textArea.style.fontSize = '10pt';
    }

  })
})()
<html>
<textarea id='my_text_area' rows="4" cols="50" style="font-size:40pt">
This text will change font after 100.
</textarea>
</html>


1

HTML5 입력 검증 / 패턴 속성과 쌍을 이루면 키업으로 충분합니다. 따라서 입력을 확인하고 .checkValidity () 상태에 따라 작동하는 패턴 (정규식)을 만듭니다. 아래와 같은 것이 효과가 있습니다. 귀하의 경우 정규식을 길이와 일치 시키길 원할 것입니다. 내 솔루션은 온라인에서 사용 가능 / 데모 가능 합니다 .

<input type="text" pattern="[a-zA-Z]+" id="my-input">

var myInput = document.getElementById = "my-input";

myInput.addEventListener("keyup", function(){
  if(!this.checkValidity() || !this.value){
    submitButton.disabled = true;
  } else {
    submitButton.disabled = false;
  }
});

0

내가 jquery없이 단일 텍스트 영역에 대해 IE 11에 사용한 코드 :

자바 스크립트 :

// Impede que o comentário tenha mais de num_max caracteres
var internalChange= 0; // important, prevent reenter
function limit_char(max)
{ 
    if (internalChange == 1)
    {
        internalChange= 0;
        return;
    }
    internalChange= 1;
    // <form> and <textarea> are the ID's of your form and textarea objects
    <form>.<textarea>.value= <form>.<textarea>.value.substring(0,max);
}

그리고 html :

<TEXTAREA onpropertychange='limit_char(5)' ...

-1

이거 한번 해봐. 간단하고 2016 년부터 대부분의 브라우저에서 작동 할 것이라고 확신합니다.

<textarea id="text" cols="50" rows="5" onkeyup="check()" maxlength="15"></textarea> 
<div><span id="spn"></span> characters left</div>

function check(){
    var string = document.getElementById("url").value
    var left = 15 - string.length;
    document.getElementById("spn").innerHTML = left;
}

그래서 당신은 id로 URL을 얻고 있지만 코드에는 표시되지 않습니다.
— AbsoluteƵERØ

-8

가장 좋은 방법은 주어진 시간에 함수가 호출되도록 설정하고이 함수는 텍스트 영역의 내용을 확인하는 것입니다.

self.setInterval('checkTextAreaValue()', 50);

7
폴링은 매우 나쁜 생각입니다. 성능을 떨어 뜨릴뿐입니다. 또한 다른 게시물과 마찬가지로 일부 솔루션이 존재합니다
— Pier-Olivier Thibault

2
이것은 21 세기입니다. 브라우저는 50ms마다 문자열 비교를 처리하는 데 문제가 없어야합니다. 선택기를 캐시하면 완벽하게 수용 가능한 솔루션입니다.
— nullability
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.