JQuery를 사용하여 <input type =“text”>의 모든 변경 사항을 즉시 감지


397

다음을 포함하여 여러 가지 방법으로 값을 <input type="text">변경할 수 있습니다.

  • 키 누르기
  • 복사 붙여 넣기
  • JavaScript로 수정
  • 브라우저 또는 툴바에 의해 자동 완성

JavaScript 함수가 변경 될 때마다 (현재 입력 값으로) JavaScript 함수를 호출하고 싶습니다. 그리고 입력이 포커스를 잃을 때가 아니라 바로 호출되기를 원합니다.

모든 브라우저 에서이 작업을 수행하는 가장 깨끗하고 강력한 방법을 찾고 있습니다 (바람직하게 jQuery 사용).



답변:


352

이 jQuery 코드는 모든 요소를 ​​즉시 변경하며 모든 브라우저에서 작동합니다.

 $('.myElements').each(function() {
   var elem = $(this);

   // Save current value of element
   elem.data('oldVal', elem.val());

   // Look for changes in the value
   elem.bind("propertychange change click keyup input paste", function(event){
      // If value has changed...
      if (elem.data('oldVal') != elem.val()) {
       // Updated stored value
       elem.data('oldVal', elem.val());

       // Do action
       ....
     }
   });
 });

19
모든 사람들이 참고할 수 있도록 input모든 최신 브라우저 ( MDN reference )를 다루어야한다고 생각되는 HTML5 이벤트입니다 . keyup약간의 지연으로 나머지 부분을 잡아야합니다 ( input키 다운시 트리거됩니다). propertychange독점 MS 이벤트 paste이며 실제로 필요한지 확실하지 않습니다 .
Jo Liss

71
내가 잘못했거나 텍스트가 다음과 같은 자바 스크립트를 통해 변경된 경우 처리되지 않습니다.document.getElementById('txtInput').value = 'some text';
Mehmet Ataş

5
Mehmet, 코드는 JS를 통해 변경된 값을 포착하기위한 것이 아닙니다.
phatmann

12
@ MehmetAtaş은 부분적으로 정확합니다. 에 대한 참조 input이벤트 여기에이 내용이 자바 스크립트를 통해 수정 될 때이 발생하지 않는 것을 말한다. 그러나이 onpropertychange이벤트 JS를 통해 수정시 시작됩니다 ( 여기 참조 ). 따라서이 코드는 IE의 JS를 통해 내용을 수정할 때 작동하지만 다른 브라우저에서는 작동하지 않습니다.
Vicky Chijwani

2
속성 변경, 키업 등의 입력에서 사용자 지정 이벤트를 트리거 한 다음 어디서나 사용할 수 있습니다.
Ivan Ivković

122

jQuery를위한 실시간 고급 솔루션> = 1.9

$("#input-id").on("change keyup paste", function(){
    dosomething();
})

"클릭"이벤트도 감지하려면 다음을 수행하십시오.

$("#input-id").on("change keyup paste click", function(){
    dosomething();
})

jQuery <= 1.4를 사용 live하는 경우 대신을 사용하십시오 on.


3
단점이 있습니다. 탭 키를 사용하여 입력 필드를 벗어나면 내용을 편집하지 않아도 키업 이벤트가 발생합니다.
Pawka

2
datetimepicker가 # input-id를 채울 때 감지하는 방법? 이벤트 (변경, 붙여 넣기)가 작동하지 않습니다.
Pathros 2016 년

대단해! jquery 1.8.3으로 시도해 보았습니다. 여전히 교체 해야하는 livequery () 코드가 있으므로 1.9.1로 업그레이드 할 수 없습니다. 나는 그것이 오래되었다는 것을 알고 있지만 전체 웹 사이트도 마찬가지입니다.
Asle

참고 : 키보드를 사용하여 유효하지 않은 날짜를 선택하면이 이벤트는 빈 값으로 시작됩니다. 즉. 2 월 30. stackoverflow.com/questions/48564568/…
Olmstov

107

불행히도, 나는 setInterval이 상을받는 다고 생각한다 :

<input type=text id=input_id />
<script>
setInterval(function() { ObserveInputValue($('#input_id').val()); }, 100);
</script>

단 한 줄의 코드로 가장 깨끗한 솔루션입니다. 또한 input가치를 얻을 수있는 모든 다른 이벤트 / 방법에 대해 걱정할 필요가 없기 때문에 가장 강력 합니다.

이 경우 'setInterval'을 사용하는 단점은 적용되지 않는 것 같습니다.

  • 100ms 대기 시간? 많은 응용 분야에서 100ms는 충분히 빠릅니다.
  • 브라우저에로드를 추가 했습니까? 일반적으로 페이지에 중량이 많은 setInterval을 많이 추가하는 것은 좋지 않습니다. 그러나이 특별한 경우에는 추가 된 페이지로드를 감지 할 수 없습니다.
  • 많은 입력으로 확장되지 않습니까? 대부분의 페이지에는 소수의 입력이 많지 않으므로 동일한 setInterval에서 모두 스니핑 할 수 있습니다.

21
이것은 Nintendo 3DS 브라우저 (Version / 1.7552.EU)를 사용할 때 양식에서 입력 필드의 변경 사항을 감지하는 유일한 방법 인 것 같습니다.
Johan

4
참고 : 과부하를 줄일 수 있습니다. 입력에 포커스가있을 때 setInterval을 시작하고 입력에 포커스가없는 경우 clearInterval을 시작하면
Tebe

10
왜 지속적으로 실행될 이유가없는 100ms 간격으로 계속 실행합니까? 이벤트 사람들. 그것을 써.
Gavin

15
@ Gavin,이 특별한 경우에 JS에는 이벤트가 부족합니다 .. 사용자 입력, 사용자 페이스트, 사용자 컷, 자바 스크립트 삽입, 자바 스크립트 제거, 자동 완성 양식, 숨겨진 양식, 표시되지 않는 이벤트 집합을 찾으십시오. 형태.
Naramsim 2016 년

2
@Gavin JS에는 입력이 변경 될 때마다 트리거되는 변경 이벤트가없는 것 같습니다. 이벤트 트리거 솔루션이 작동하지 않는 것을 보려면 document.getElementById (name) .value = Math.random ()을 수행하십시오.
Joeri

58

oninput이벤트에 바인딩하는 것은 대부분의 정상적인 브라우저에서 제대로 작동하는 것 같습니다. IE9도 지원하지만 구현은 버그가 있습니다 (문자를 삭제할 때 이벤트가 시작되지 않음).

jQuery 버전 1.7 이상 on에서이 메소드는 다음과 같이 이벤트에 바인딩하는 데 유용합니다.

$(".inputElement").on("input", null, null, callbackFunction);

12
oninput이벤트가 작동하지 않습니다 input[type=reset]이 테스트에서 볼 수 또는 자바 스크립트 편집 : codepen.io/yukulele/pen/xtEpb
Yukulélé

2
@ Yukulélé, 적어도 우리는 가능한 모든 사용자 행동 을 감지하는 것보다 쉽게 ​​해결할 수 있습니다 .
Pacerier

30

2017 답변 : 입력 이벤트 는 IE8보다 최신 버전에 대해 정확하게 수행합니다.

$(el).on('input', callback)

6
죄송하지만 ... 위의 HRJ 2012 답변과 다른 점은 무엇입니까? 어쨌든 input이벤트가 JS 변경을 감지하지 못했습니다.
David

16

안타깝게도 기준에 맞는 이벤트 또는 이벤트 세트가 없습니다. 키 누르기와 복사 / 붙여 넣기는 모두 keyup이벤트 로 처리 할 수 ​​있습니다 . JS를 통한 변경은 더 까다 롭습니다. 텍스트 상자를 설정하는 코드를 제어 할 수 있다면 가장 좋은 방법은 텍스트 상자에서 함수를 직접 호출하거나 사용자 이벤트를 트리거하도록 수정하는 것입니다.

// Compare the textbox's current and last value.  Report a change to the console.
function watchTextbox() {
  var txtInput = $('#txtInput');
  var lastValue = txtInput.data('lastValue');
  var currentValue = txtInput.val();
  if (lastValue != currentValue) {
    console.log('Value changed from ' + lastValue + ' to ' + currentValue);
    txtInput.data('lastValue', currentValue);
  }
}

// Record the initial value of the textbox.
$('#txtInput').data('lastValue', $('#txtInput').val());

// Bind to the keypress and user-defined set event.
$('#txtInput').bind('keypress set', null, watchTextbox);

// Example of JS code triggering the user event
$('#btnSetText').click(function (ev) {
  $('#txtInput').val('abc def').trigger('set');
});

해당 코드를 제어 할 수없는 경우 setInterval()텍스트 상자를 '감시'하여 변경 사항을 확인할 수 있습니다 .

// Check the textbox every 100 milliseconds.  This seems to be pretty responsive.
setInterval(watchTextbox, 100);

이러한 종류의 능동적 모니터링은 업데이트를 '즉시'포착하지는 않지만 지각 할 수있는 지연이 없을 정도로 빠른 것 같습니다. DrLouie가 의견에서 지적 했듯이이 솔루션은 많은 입력을보아야 할 경우 확장 성이 떨어질 수 있습니다. 항상 두 번째 매개 변수를 조정하여 setInterval()더 자주 또는 덜 자주 점검 할 수 있습니다 .


참고로 실제로 브라우저마다 다양한 정도의 OP 기준과 일치하도록 결합 될 수있는 수많은 이벤트가 있습니다 (첫 번째 질문 의견의 링크 참조). 이 답변은 언급 된 이벤트를 사용하지 않으며 약간의 지연이 있지만 모든 브라우저에서 아이러니하게 작동합니다.)
Crescent Fresh

OP는 JavaScript를 통해 텍스트 상자의 변경 사항을 포착하려고합니다 (예 myTextBox.value = 'foo';: JavaScript 이벤트가 해당 상황을 처리하지 않음)
Annabelle

1
탭을 유지하기 위해 50 개의 필드가있는 사람은 어떻습니까?
DoctorLouie 2009

1
예, 필자의 경우에는 1 개의 필드 만 있지만 여러 필드에서 이것이 왜 제대로 작동하지 않는지 알 수 없습니다. 모든 입력을 확인하는 1 개의 setTimeout을 갖는 것이 가장 효율적일 것입니다.
더스틴 보스 웰

1
@Douglas : 해당 상황을 처리하는 JavaScript 이벤트가 없음 -수정 : IE는으로 처리 할 수 input.onpropertychange있으며 FF2 +, Opera 9.5, Safari 3 및 Chrome 1에서 처리 할 수 ​​있습니다 input.__defineSetter__('value', ...)(DOM 노드에서 작동하지 않는 것으로 문서화되었지만 확인할 수 있음) 효과가있다). IE 구현과의 유일한 차이점은 IE가 프로그래밍 방식 설정뿐만 아니라 주요 이벤트 중에 핸들러를 실행한다는 것입니다.
Crescent Fresh

6

다른 답변을 좋아하지 않으면 약간 다른 해결책이 있습니다.

var field_selectors = ["#a", "#b"];
setInterval(function() { 
  $.each(field_selectors, function() { 
    var input = $(this);
    var old = input.attr("data-old-value");
    var current = input.val();
    if (old !== current) { 
      if (typeof old != 'undefined') { 
        ... your code ...
      }
      input.attr("data-old-value", current);
    }   
  }   
}, 500);

컨텍스트 메뉴 붙여 넣기를 캡처하기 위해 클릭 및 키업에 의존 할 수 없다고 생각하십시오.


이 답변은 저에게 가장 효과적이었습니다. 내가 사용할 때까지 선택기에 문제가 $("input[id^=Units_]").each(function() {
있었습니다

4

이 코드를 어딘가에 추가하면 트릭이 수행됩니다.

var originalVal = $.fn.val;
$.fn.val = function(){
    var result =originalVal.apply(this,arguments);
    if(arguments.length>0)
        $(this).change(); // OR with custom event $(this).trigger('value-changed');
    return result;
};

jQuery 에서 val ()이 change ()를 트리거하지 않는 이 솔루션을 찾았습니다.


3

샘플을 만들었습니다. 그것이 당신을 위해 작동 할 수 있습니다.

var typingTimer;
var doneTypingInterval = 10;
var finaldoneTypingInterval = 500;

var oldData = $("p.content").html();
$('#tyingBox').keydown(function () {
    clearTimeout(typingTimer);
    if ($('#tyingBox').val) {
        typingTimer = setTimeout(function () {
            $("p.content").html('Typing...');
        }, doneTypingInterval);
    }
});

$('#tyingBox').keyup(function () {
    clearTimeout(typingTimer);
    typingTimer = setTimeout(function () {
        $("p.content").html(oldData);
    }, finaldoneTypingInterval);
});


<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>


<textarea id="tyingBox" tabindex="1" placeholder="Enter Message"></textarea>
<p class="content">Text will be replace here and after Stop typing it will get back</p>

http://jsfiddle.net/utbh575s/


3

실제로 자바 스크립트 변경을 감지하기 위해 루프를 설정할 필요가 없습니다. 우리는 이미 감지하려는 요소에 많은 이벤트 리스너를 설정했습니다. 유해하지 않은 이벤트 만 트리거하면 작업이 수행됩니다.

$("input[name='test-element']").on("propertychange change click keyup input paste blur", function(){
console.log("yeh thats worked!");
});

$("input[name='test-element']").val("test").trigger("blur");

그리고 ofc는 프로젝트에서 자바 스크립트 변경을 완전히 제어 할 수있는 경우에만 사용할 수 있습니다.


2

글쎄, 가장 좋은 방법은 당신이 직접 세 가지 기지를 다루는 것입니다. 간단한 : onblur, : onkeyup 등은 원하는대로 작동하지 않으므로 결합하십시오.

KeyUp은 처음 두 개를 다루어야하며 Javascript가 입력 상자를 수정하는 경우 자신의 Javascript가되기를 바랍니다. 따라서 수정하는 함수에 콜백을 추가하십시오.


1
OP는 텍스트 상자를 변경하는 코드를 수정하거나 원하지 않을 수 있지만 간단한 솔루션의 경우 +1입니다.
Annabelle

가능한 모든 이벤트를 열거하는 것이 나에게 강력하지는 않습니다. 사용자가 삭제 키를 누른 경우 (예 : 반복 키) 키업이 작동합니까? 자동 완성 (또는 값을 자동으로 채우는 도구 모음)은 어떻습니까? 아니면 키를 누르지 않는 특수 입력 소스가 있습니까? 나는 당신이 그리워할만한 것이있을 것이라고 걱정할 것입니다.
더스틴 보스 웰

1

다음은 자동 완성 변형을 구현하기 위해 jqueryui 선택기 (목록)를 채우는 데 사용하는 실제 예제입니다. 그러나 드롭 다운 메뉴를 수행하는 jqueryui 자동 완성과 똑같이 작동하고 싶지 않습니다.

$("#tagFilter").on("change keyup paste", function() {
     var filterText = $("#tagFilter").val();
    $("#tags").empty();
    $.getJSON("http://localhost/cgi-bin/tags.php?term=" + filterText,
        function(data) {
            var i;
            for (i = 0; i < data.length; i++) {
                var tag = data[i].value;
                $("#tags").append("<li class=\"tag\">" + tag + "</li>");
            }
        }); 
});

1

장난이 아닙니다! (어쨌든 요즘은 쓸모가 없습니다)

편집 : HTML 이벤트를 제거했습니다. HTML 이벤트를 사용하지 마십시오 ... 대신 Javascript 이벤트 리스너를 사용하십시오.

document.querySelector("#testInput").addEventListener("input", test);

function test(e) {
 var a = document.getElementById('output');
 var b = /^[ -~]+$/;
 if (e.target.value == '' || b.test(e.target.value)) {
  a.innerText = "Text is Ascii?.. Yes";
 } else if (!b.test(e.target.value)) {
  a.innerText = "Text is Ascii?.. No";
 }
}
Try pressing Alt+NumPad2+NumPad3 in the input, it will instantly detect a change, whether you Paste, Type, or any other means, rather than waiting for you to unselect the textbox for changes to detect.

<input id="testInput">
<br>
<a id="output">Text is Ascii?.. Yes</a>


0

<span contenteditable="true" spellcheck="false">대신에 요소를 사용할 수는 없습니다.<input type="text"> ?

<span>( contenteditable="true" spellcheck="false"속성으로) <input>주로 다음 과 같은 이유로 구별됩니다 .

  • 그것은 같은 스타일이 아닙니다 <input> .
  • 그것은이없는 value속성을하지만, 텍스트로 렌더링됩니다innerText 하고 내 몸의 일부를합니다.
  • <input>속성을 설정하더라도 여러 줄이지 만 그렇지 않습니다 multiline="true".

외관을 달성하기 위해 CSS에서 스타일을 지정할 수 있지만 값을 innerText 을 지정하는 한편 이벤트에 사용할 수 .

여기 바이올린이 있습니다.

불행히도 IE와 Edge에서 실제로 작동하지 않는 항목이 있는데 찾을 수 없습니다.


그 방법을 사용하는 것에 대한 접근성 문제가 있다고 생각합니다.
Daniel Tonon 8

0

이 질문은 10 년 전에 게시되었지만 여전히 일부 개선이 필요하다고 생각합니다. 그래서 여기 내 해결책이 있습니다.

$(document).on('propertychange change click keyup input paste', 'selector', function (e) {
    // Do something here
});

이 솔루션의 유일한 문제는 값이 javascript와 같이 변경되면 트리거되지 않는다는 것 $('selector').val('some value')입니다. javascript에서 값을 변경하면 선택기에 이벤트를 발생시킬 수 있습니다.

$(selector).val('some value');
// fire event
$(selector).trigger('change');

-2

이 예를보고 관심있는 이벤트를 선택하십시오.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
<title>evetns</title>
</head>
<body>
<form>
    <input class="controlevents" id="i1" type="text" /><br />
    <input class="controlevents" id="i2" type="text" /><br />
    <input class="controlevents" id="i3" type="text" /><br />
    <input class="controlevents" id="i4" type="text" /><br />
    <input class="controlevents" id="i5" type="text" /><br />
</form>
<div id="datatext"></div>
</body>
</html>
<script>
$(function(){

function testingevent(ev){
    if (ev.currentTarget.tagName=="INPUT")
        $("#datatext").append("<div>id : " + ev.currentTarget.id + ", tag: " + ev.currentTarget.tagName + ", type: "+ ev.type +"</div>");
}   

    var eventlist = ["resizeend","rowenter","dragleave","beforepaste","dragover","beforecopy","page","beforeactivate","beforeeditfocus","controlselect","blur",
                    "beforedeactivate","keydown","dragstart","scroll","propertychange","dragenter","rowsinserted","mouseup","contextmenu","beforeupdate",
                    "readystatechange","mouseenter","resize","copy","selectstart","move","dragend","rowexit","activate","focus","focusin","mouseover","cut",
                    "mousemove","focusout","filterchange","drop","blclick","rowsdelete","keypress","losecapture","deactivate","datasetchanged","dataavailable",
                    "afterupdate","mousewheel","keyup","movestart","mouseout","moveend","cellchange","layoutcomplete","help","errorupdate","mousedown","paste",
                    "mouseleave","click","drag","resizestart","datasetcomplete","beforecut","change","error","abort","load","select"];

    var inputs = $(".controlevents");

    $.each(eventlist, function(i, el){
        inputs.bind(el, testingevent);
    });

});
</script>

4
이벤트 유형을 잊어 버린 것 같습니다 :)
Dustin Boswell

-3

여기 파티에 늦을 수도 있지만 jQuery가 제공하는 .change () 이벤트를 사용할 수는 없습니다.

당신은 같은 것을 할 수 있어야합니다 ...

$(#CONTROLID).change(function(){
    do your stuff here ...
});

항상 다음과 같은 컨트롤 목록에 바인딩 할 수 있습니다 ...

var flds = $("input, textarea", window.document);

flds.live('change keyup', function() {
    do your code here ...
});

라이브 바인더는 현재와 미래에 페이지에 존재하는 모든 요소가 처리되도록합니다.


2
변경 이벤트는 포커스를 잃은 후에 만 ​​발생하므로 사용자가 상자에 입력하는 동안 실행되지 않고 다른 작업을 수행 한 후에 만 ​​실행됩니다.
Eli Sand

2
다른 많은 답변과 마찬가지로 요소의 값이 Javascript에서 수정되면 작동하지 않습니다. OP가 요청한 다른 수정 사례가 누락되었는지 여부는 알 수 없습니다.
Mark Amery

-4

이것은 가장 빠르고 깨끗한 방법입니다.

Jquery를 사용하고 있습니다.

$('selector').on('change', function () {
    console.log(this.id+": "+ this.value);
});

그것은 나를 위해 꽤 잘 작동합니다.


7
이것은 이미 제안되었습니다. 사용자가 텍스트를 입력 할 때 간단한 경우 만 다룹니다.
Christophe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.