텍스트 영역 변경 감지


132

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

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

답변:


97

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

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


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

65
나는 여기에 -1을주고있다, 미안하다! onkeyup입력 감지에 대한 끔찍한 이벤트입니다. oninputonpropertychange(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 및 Safarionpropertychange처리하고 IE8을 처리합니다 (IE6 및 7에서도 작동하지만 몇 가지 버그가 있음).

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

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

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

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


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