วิธีที่ดีที่สุดในการติดตามการเปลี่ยนตามประเภทที่คุณพิมพ์ = "text"?


449

จากประสบการณ์ของฉันinput type="text" onchangeเหตุการณ์มักจะเกิดขึ้นหลังจากคุณออก ( blur) การควบคุมเท่านั้น

มีวิธีบังคับให้เบราว์เซอร์เรียกเนื้อหาเปลี่ยนแปลงonchangeทุกครั้งtextfieldหรือไม่ ถ้าไม่เป็นวิธีที่ดีที่สุดในการติดตาม "ด้วยตนเอง" นี้คืออะไร?

การใช้onkey*กิจกรรมไม่น่าเชื่อถือเนื่องจากคุณสามารถคลิกขวาที่ฟิลด์และเลือกวางและสิ่งนี้จะเปลี่ยนฟิลด์โดยไม่ต้องป้อนคีย์บอร์ด

เป็นsetTimeoutวิธีเดียวหรือไม่ .. น่าเกลียด :-)


@ มีโอกาสใดบ้างที่คุณจะสามารถอัปเดตคำตอบที่คุณยอมรับเพื่อให้คำตอบที่ล้าสมัยไม่ได้ถูกตรึงไว้ที่ด้านบน
Flimm

คำตอบ:


271

ปรับปรุง:

ดูคำตอบอื่น (2015)


คำตอบเดิม 2009:

ดังนั้นคุณต้องการให้onchangeเหตุการณ์ดำเนินการกับ keydown, เบลอและวางหรือไม่ นั่นคือเวทมนตร์

"onkeydown"หากคุณต้องการที่จะติดตามการเปลี่ยนแปลงที่พวกเขาพิมพ์ใช้ หากคุณต้องการดักจับการดำเนินการด้วยเมาส์ให้ใช้"onpaste"( IE , FF3 ) และ"oninput"( FF, Opera, Chrome, Safari 1 )

1 ใช้งานไม่ได้<textarea>บน Safari ใช้textInputแทน


22
onkeypressonkeydownควรจะนำมาใช้แทน onkeydownไฟไหม้เมื่อมีการคลิกคีย์ หากผู้ใช้กดปุ่มค้างไว้เหตุการณ์จะเริ่มต้นเพียงครั้งเดียวสำหรับอักขระตัวแรก onkeypressยิงเมื่อใดก็ตามที่ถ่านถูกเพิ่มเข้าไปในช่องข้อความ
รบกวน

61
มันไม่ใช่เวทมนตร์ที่จะonchangeจุดไฟในทุกการกระทำ <input onchange="doSomething();" onkeypress="this.onchange();" onpaste="this.onchange();" oninput="this.onchange();">จะทำดีพอสำหรับคนส่วนใหญ่
aroth

1
แล้วการลบข้อความในกล่องป้อนข้อมูลโดยใช้เม้าส์ล่ะ? ฉันไม่คิดว่ามันจะใช้ได้
Jeevan

47
ด้วย jQuery 1.8.3 ดูเหมือนว่า:$().on('change keydown paste input', function() {})
Narfanator

4
@AriWais: ใช่ OMG ส่วนใหญ่ควรเลิกใช้แล้ว Folks คำตอบนี้เป็น8 ปี ฉันหวังว่าจะมีปุ่ม "ไม่สนับสนุน" สำหรับคำตอบเก่า ๆ เช่นนี้และชุมชนสามารถเลือกที่ดีกว่าได้
Crescent Fresh

658

oninputวันนี้ฟัง รู้สึกเหมือนonchangeไม่ต้องเสียสมาธิกับองค์ประกอบ มันคือ HTML5

มันสนับสนุนโดยทุกคน (แม้แต่มือถือ) ยกเว้น IE8 และด้านล่าง สำหรับ IE onpropertychangeเพิ่ม ฉันใช้มันแบบนี้:

const source = document.getElementById('source');
const result = document.getElementById('result');

const inputHandler = function(e) {
  result.innerHTML = e.target.value;
}

source.addEventListener('input', inputHandler);
source.addEventListener('propertychange', inputHandler); // for IE8
// Firefox/Edge18-/IE9+ don’t fire on <select><option>
// source.addEventListener('change', inputHandler); 
<input id="source">
<div id="result"></div>


63
ในโลกที่เปลี่ยนแปลงอย่างเช่นมาตรฐานเว็บบางครั้งคำตอบที่ยอมรับอาจเปลี่ยนไปหลังจากหลายปี ... นี่คือคำตอบที่ยอมรับใหม่สำหรับฉัน
Erick Petrucelli

1
รองรับoninputแม้ใน IE9 แม้ว่าจะเป็นบางส่วน ( caniuse.com/#feat=input-event )
Kenston Choi

การใช้มาร์กอัปใด ๆอาจไม่คุ้มค่าที่ควรใช้innerTextแทนinnerHTML
Jeevan Takhar

47

โค้ดด้านล่างใช้ได้ดีสำหรับฉันด้วย Jquery 1.8.3

HTML: <input type="text" id="myId" />

Javascript / JQuery:

$("#myId").on('change keydown paste input', function(){
      doSomething();
});

11
ห้องสมุด jQuery ไม่ได้ติดแท็กในคำถาม
John Weisz

21
Jquery เป็น Javascript api และฉันถูกนำมาที่นี่ด้วยการค้นหาด้วยคำหลัก Jquery ฉันไม่คิดว่ามันคุ้มค่าที่จะสร้างคำถามใหม่สำหรับแต่ละ javascript qustion สำหรับคำตอบของ Jquery ...
GaelDev

12
หากผู้คนไม่ได้รับอนุญาตให้แนะนำการใช้ห้องสมุดในคำตอบจะมีคำถามที่ไม่ได้ตอบอีกมากมายใน SO
Dietbacon

3
ยิงหลายครั้ง น่าจะเกิดจากการเปลี่ยนแปลงและ keydown การป้อนที่น่าจะเป็นสิ่งจำเป็นเท่านั้นที่นี่
mmm

1
คุณไม่จำเป็นต้องใช้keydownเพราะมันจะทำซ้ำค่าของอินพุตลบออก
Youssef Al Subaihi

43

Javascript เป็นสิ่งที่คาดเดาไม่ได้และตลกที่นี่

  • onchange เกิดขึ้นเฉพาะเมื่อคุณเบลอช่องข้อความ
  • onkeyup& onkeypressไม่ได้เกิดขึ้นกับการเปลี่ยนแปลงข้อความเสมอไป
  • onkeydown เกิดขึ้นกับการเปลี่ยนแปลงข้อความ (แต่ไม่สามารถติดตามการตัดและวางด้วยการคลิกเมาส์)
  • onpasteและoncutเกิดขึ้นกับปุ่มกดและแม้จะมีการคลิกขวาของเมาส์

ดังนั้นในการติดตามการเปลี่ยนแปลงในช่องที่เราต้องonkeydown, และoncut onpasteในการโทรกลับของเหตุการณ์เหล่านี้ถ้าคุณตรวจสอบค่าของกล่องข้อความคุณจะไม่ได้รับค่าที่อัปเดตเนื่องจากค่าจะเปลี่ยนหลังจากการโทรกลับ ดังนั้นทางออกสำหรับสิ่งนี้คือการตั้งค่าฟังก์ชั่นไทม์เอาต์ด้วยการหมดเวลาของ 50 mili-seconds (หรืออาจจะน้อยกว่า) เพื่อติดตามการเปลี่ยนแปลง

นี่เป็นแฮ็คสกปรก แต่นี่เป็นวิธีเดียวที่ฉันค้นคว้า

นี่คือตัวอย่าง http://jsfiddle.net/2BfGC/12/


4
oninputและtextInputเป็นเหตุการณ์ที่เป็นทางออกที่แท้จริงสำหรับสิ่งนี้ แต่ไม่ได้รับการสนับสนุนจากเบราว์เซอร์ทั้งหมด
Sanket Sahu

สำหรับสัญลักษณ์แสดงหัวข้อย่อยที่สองฉันคิดว่าคุณหมายถึงonkeyupและonkeydownที่คล้ายกัน ทั้งสองสามารถจับภาพปุ่ม Ctrl, Alt, Shift และ Meta onkeypressสำหรับสัญลักษณ์ที่สามผมถือว่าคุณหมาย
Daniel Stevens

12

onkeyupเกิดขึ้นหลังจากที่คุณพิมพ์เช่นฉันกดtเมื่อฉันยกนิ้วการกระทำที่เกิดขึ้น แต่ในkeydownการกระทำที่เกิดขึ้นก่อนที่ฉันจะตัวละครหลักt

หวังว่านี่จะเป็นประโยชน์สำหรับใครบางคน

ดังนั้นonkeyupจะดีกว่าเมื่อคุณต้องการส่งสิ่งที่คุณเพิ่งพิมพ์ตอนนี้


8

ฉันมีข้อกำหนดที่คล้ายกัน (ฟิลด์ข้อความสไตล์ Twitter) ที่ใช้และonkeyup ดูแลการดำเนินการวางเมาส์ระหว่างการโฟกัสหายไปจากฟิลด์onchangeonchange

[อัปเดต]ใน HTML5 หรือใหม่กว่าใช้oninputเพื่อรับการอัปเดตตัวละครแบบเรียลไทม์ตามที่อธิบายไว้ในคำตอบอื่น ๆ ด้านบน


oninput มีประโยชน์ถ้าคุณต้องการตรวจสอบเมื่อเนื้อหาของ textarea, input: text, input: password หรือ input: องค์ประกอบการค้นหามีการเปลี่ยนแปลงเพราะเหตุการณ์ onchange ในองค์ประกอบเหล่านี้จะยิงเมื่อองค์ประกอบหมดโฟกัสไม่ใช่ทันทีหลังจากการปรับเปลี่ยน .
hkasera

@hkasera ใช่ด้วย HTML5 oninputเป็นวิธีที่จะไป แต่เมื่อฉันใช้งาน HTML5 ไม่มีอยู่จริงและเรามี IE 8 :( ฉันขอขอบคุณการอัปเดตของคุณเนื่องจากให้ข้อมูลที่เป็นปัจจุบันสำหรับผู้ใช้
Mohnish

8

ฉันคิดว่าในปี 2018 จะดีกว่าที่จะใช้ inputกิจกรรม

-

ตามที่ WHATWG Spec อธิบาย ( https://html.spec.whatwg.org/multipage/indices.html#event-input-input ):

ยิงที่การควบคุมเมื่อผู้ใช้เปลี่ยนค่า (ดูเหตุการณ์การเปลี่ยนแปลงด้วย )

-

นี่คือตัวอย่างของวิธีการใช้งาน:

<input type="text" oninput="handleValueChange()">

7

หากคุณใช้ Internet Explorer เท่านั้นคุณสามารถใช้สิ่งนี้:

<input type="text" id="myID" onpropertychange="TextChange(this)" />

<script type="text/javascript">
    function TextChange(tBox) {
        if(event.propertyName=='value') {
            //your code here
        }
    }
</script>

หวังว่าจะช่วย


8
อาจจะสำหรับโครงการในบ้านฉันเดา ... :)
eselk

94
ขอบคุณพระเจ้าฉันไม่ได้อาศัยอยู่ในบ้านหลังนั้น! : D
Marco Matarazzi

13
10 ปีที่แล้วไม่มีสิ่งใดตลกในประโยคนี้ .. :(
Michał Tabor

4
สำหรับฉันสิ่งนี้ช่วยได้ฉันกำลังพัฒนาโครงการสำหรับมือถือบางรุ่นที่มีระบบปฏิบัติการฝังตัวอยู่ซึ่ง IE เป็นเบราว์เซอร์เดียวเท่านั้น
Anders M.

3
ถ้าคุณใช้เฉพาะ Internet Explorer - LOL ทำวันของฉันในปี 2559!
Jack Black

4

มีวิธีแก้ปัญหาค่อนข้างใกล้ (อย่าแก้ไขวิธีการวางทั้งหมด) แต่ส่วนใหญ่:

มันใช้งานได้กับอินพุตเช่นเดียวกับ textareas:

<input type="text" ... >
<textarea ... >...</textarea>

ทำเช่นนี้:

<input type="text" ... onkeyup="JavaScript: ControlChanges()" onmouseup="JavaScript: ControlChanges()" >
<textarea ... onkeyup="JavaScript: ControlChanges()" onmouseup="JavaScript: ControlChanges()" >...</textarea>

อย่างที่ฉันบอกว่าไม่ใช่ทุกวิธีในการวางไฟเหตุการณ์ในเบราว์เซอร์ทั้งหมด ... ที่เลวร้ายที่สุดบางคนไม่ได้ยิงเหตุการณ์ใด ๆ เลย แต่ตัวจับเวลาน่ากลัวที่จะใช้สำหรับเช่นนี้

แต่วิธีการวางส่วนใหญ่จะทำด้วยแป้นพิมพ์และ / หรือเมาส์ดังนั้นโดยปกติแล้ว onkeyup หรือ onmouseup จะเริ่มทำงานหลังจากวางแล้ว onkeyup จะทำงานเมื่อพิมพ์บนแป้นพิมพ์

ตรวจสอบให้แน่ใจว่ารหัสตรวจสอบเล็กน้อยไม่ต้องใช้เวลามาก ... มิฉะนั้นผู้ใช้จะได้รับการแสดงผลที่ไม่ดี

ใช่เคล็ดลับคือการยิงคีย์และเม้าส์ ... แต่ระวังให้ถูกยิงได้ดังนั้นโปรดระลึกไว้เช่นนี้ !!!


4

โปรดตัดสินแนวทางต่อไปโดยใช้ JQuery:

HTML:

<input type="text" id="inputId" />

จาวาสคริปต์ (JQuery):

$("#inputId").keyup(function(){
        $("#inputId").blur();
        $("#inputId").focus();
});

$("#inputId").change(function(){
        //do whatever you need to do on actual change of the value of the input field
});

ฉันใช้วิธีเดียวกัน
:)

ฉันรู้ว่านี่ไม่ใช่คำตอบล่าสุด แต่จะไม่ทำให้ตาพร่าและมุ่งเน้นการป้อนข้อมูลในทุก ๆ การกดปุ่มขึ้นตำแหน่งเคอร์เซอร์ถ้ามันเป็นที่ใดก็ได้ยกเว้นที่สิ้นสุดของการป้อนข้อมูล?
Michael Martin-Smucker

@ MichaelMartin-Smucker คุณคิดอย่างนั้น แต่ดูเหมือนจะไม่ใช่: jsfiddle.net/gsss8c6L
Clonkex

4

"อินพุต" ใช้งานได้สำหรับฉัน

var searchBar  = document.getElementById("searchBar");
searchBar.addEventListener("input", PredictSearch, false);


3

หากต้องการติดตามแต่ละลองใช้ตัวอย่างนี้และก่อนหน้านั้นจะลดอัตราการกะพริบของเคอร์เซอร์เป็นศูนย์อย่างสมบูรณ์

<body>
//try onkeydown,onkeyup,onkeypress
<input type="text" onkeypress="myFunction(this.value)">
<span> </span>
<script>
function myFunction(val) {
//alert(val);
var mySpan = document.getElementsByTagName("span")[0].innerHTML;
mySpan += val+"<br>";
document.getElementsByTagName("span")[0].innerHTML = mySpan;
}
</script>

</body>

onblur: เหตุการณ์สร้างเมื่อออก

onchange: เหตุการณ์สร้างเมื่อออกหากมีการเปลี่ยนแปลงใด ๆ ในอินพุต

onkeydown: เหตุการณ์สร้างบนการกดปุ่มใด ๆ (สำหรับการกดปุ่มค้างไว้นาน ๆ )

onkeyup: เหตุการณ์สร้างขึ้นในการปล่อยปุ่มใด ๆ

onkeypress: เหมือนกับ onkeydown (หรือ onkeyup) แต่จะไม่ตอบสนองต่อ ctrl, backsace, alt อื่น ๆ


1

2561 ที่นี่นี่คือสิ่งที่ฉันทำ:

$(inputs).on('change keydown paste input propertychange click keyup blur',handler);

หากคุณสามารถชี้ให้เห็นข้อบกพร่องในวิธีการนี้ฉันจะขอบคุณ


2
2019 ตรงนี้และมันจะทำการยิงหลายครั้งสำหรับการกดปุ่มแต่ละครั้ง ตัวอย่างเช่นดูที่นี่: jsfiddle.net/sp00n82/3r4691tq/5
sp00n

1

วิธีที่ 1:เพิ่มตัวฟังเหตุการณ์สำหรับinput:

element.addEventListener("input", myFunction);

 

วิธีที่ 2:กำหนดoninputคุณสมบัติด้วย JavaScript:

element.oninput = function()
{
    myFunction();
};

 

วิธีที่ 3:กำหนดoninputคุณสมบัติด้วย HTML:

<input type="text" oninput="myFunction();">

0

ไม่รองรับ Robert Siemer addEventListener ใน IE8

"IE เวอร์ชันเก่ากว่ารองรับเมธอด EventTarget.attachEvent () ที่เทียบเท่าและเป็นกรรมสิทธิ์" https://developer.mozilla.org/it/docs/Web/API/Element/addEventListener


นี่เป็นเหมือนความคิดเห็นต่อคำตอบที่มีอยู่มากกว่าคำตอบใหม่
slfan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.