วิธีการตรวจสอบเนื้อหาของกล่องข้อความมีการเปลี่ยนแปลง


417

ฉันต้องการตรวจสอบเมื่อใดก็ตามที่เนื้อหาของกล่องข้อความเปลี่ยนไป ฉันสามารถใช้วิธีการคีย์อัพ แต่จะตรวจจับการกดแป้นที่ไม่ได้สร้างตัวอักษรเช่นเดียวกับปุ่มลูกศร ฉันคิดถึงวิธีการสองวิธีในการทำเช่นนี้โดยใช้เหตุการณ์คีย์อัป:

  1. ตรวจสอบอย่างชัดเจนว่ารหัส ascii ของปุ่มกดเป็นตัวอักษร \ backspace \ delete
  2. ใช้การปิดเพื่อจดจำสิ่งที่เป็นข้อความในกล่องข้อความก่อนการกดแป้นและตรวจสอบว่ามีการเปลี่ยนแปลงหรือไม่

ทั้งคู่ดูค่อนข้างยุ่งยาก


7
ใช่การจับคีย์อัพสำหรับสิ่งนี้ไม่ดี คุณสามารถวางสิ่งต่าง ๆ โดยไม่ต้องกดปุ่มใด ๆ เลย
— อะไรต่อมิอะไร

2
โอกาสใดที่คุณสามารถโพสต์โซลูชั่นสุดท้ายของคุณ? ฉันจำเป็นต้องแก้ปัญหานี้ด้วย :)
— 48425 Matt

1
หรือ.keyup()กิจกรรม ... ข้อมูลเพิ่มเติมได้ที่นี่: stackoverflow.com/questions/3003879/…
— Victor S

1
ดู$ ("# some-input") changePolling () ; สำหรับ wrapper ที่ตรวจสอบค่าปัจจุบันและทริกเกอร์.change()หากมีการเปลี่ยนแปลง
— Joel Purra

คุณต้องตรวจสอบstackoverflow.com/a/23266812/3160597
— azerafati

คำตอบ:


714

เริ่มสังเกตเหตุการณ์ 'อินพุต' แทน 'เปลี่ยน'

jQuery('#some_text_box').on('input', function() {
    // do your stuff
});

... ซึ่งดีและสะอาด แต่อาจขยายเพิ่มเติมไปที่:

jQuery('#some_text_box').on('input propertychange paste', function() {
    // do your stuff
});

12
'สด' เลิกใช้แล้ว เพื่อใช้ประโยชน์จาก 'กับ' stackoverflow.com/a/15111970/1724777
— NavaRajan

21
ข้อเสียเพียงอย่างเดียวของ 'อินพุต' คือไม่เข้ากันได้กับ IE <9
— Catfish

5
input เป็นเหตุการณ์ html5 ที่ไม่รองรับในเบราว์เซอร์ทั้งหมด developer.mozilla.org/en-US/docs/Web/API/window.oninput
— commonpike

18
คุณสามารถครอบคลุมฐานเพิ่มเติมได้โดยใช้: .on ('input property paste paste', function () {
— Graeck

23
ข้อเสียเพียงอย่างเดียวของ IE <9 คือไม่มีใครใช้เลย!
— sohaiby

67

ใช้เหตุการณ์ onchange ใน HTML / JavaScript มาตรฐาน

ใน jQuery นั่นคือการเปลี่ยนแปลง ()เหตุการณ์ ตัวอย่างเช่น:

$('element').change(function() { // do something } );

แก้ไข

หลังจากอ่านความคิดเห็นแล้วคุณจะทำอย่างไร:

$(function() {
    var content = $('#myContent').val();

    $('#myContent').keyup(function() { 
        if ($('#myContent').val() != content) {
            content = $('#myContent').val();
            alert('Content has been changed');
        }
    });
});

3
ใช่มันคล้ายกับสิ่งที่ฉันแนะนำในตัวเลือก # 2 ในคำถามของฉัน ฉันชอบการปิดเพราะใช้ทั่วโลกจะทำให้ฟังก์ชั่นนี้ใช้ได้กับกล่องข้อความเดียวเท่านั้น อย่างไรก็ตามดูเหมือนว่า jquery แปลก ๆ ไม่มีวิธีการที่ง่ายกว่านี้
— olamundo

1
มันแปลกจริง ๆ แต่ฉันสงสัยว่ามีวิธีที่ดีกว่าในการทำมัน คุณสามารถใช้ setInterval แล้วตรวจสอบว่าเนื้อหามีการเปลี่ยนแปลงทุกๆ 0.1 วินาทีหรือไม่และทำอะไรบางอย่าง ซึ่งจะรวมถึงการวางเมาส์และอื่น ๆ แต่มันไม่ได้ฟังดูหรูหราเกินไป
— Waleed Amjad

4
ยังคงเป็นไปได้ว่าเนื้อหาสามารถเปลี่ยนแปลงได้โดยไม่ต้องกดแป้นตัวอย่างเช่นโดยการวางเมาส์ หากคุณสนใจในเรื่องนี้คุณสามารถจับเหตุการณ์เมาส์ในทางทฤษฎีได้เช่นกัน แต่การตั้งค่านั้นก็น่าเกลียดกว่าเดิม ในทางกลับกันถ้าคุณยินดีที่จะเพิกเฉยต่อการเปลี่ยนแปลงที่เกิดจากเมาส์สิ่งนี้จะทำ
— Adam Bellaire

45

เหตุการณ์ 'เปลี่ยน' ไม่ทำงานอย่างถูกต้อง แต่ 'อินพุต' นั้นสมบูรณ์แบบ

$('#your_textbox').bind('input', function() {
    /* This will be fired every time, when textbox's value changes. */
} );

7
สิ่งนี้ทำงานได้อย่างสมบูรณ์แบบสำหรับสถานการณ์ของฉันแม้ว่า.onจะแนะนำให้ใช้ตั้งแต่ 1.7 เป็นต้นไป (มากกว่า.bind)
— Nick

8
OP ไม่ได้ระบุความจำเป็นในการใช้งานร่วมกันข้ามเบราว์เซอร์ @schwarzkopfb จัดหาวิธีแก้ปัญหา ไม่มีเหตุผลในการลงคะแนนเพราะคุณมีตัวแทนที่จะทำเช่นนั้น
— David East

3
@ David นอกจากนี้เขายังไม่ได้ระบุเบราว์เซอร์
— Ozz

9
@ jmo21 ฉันคิดว่าเราสามารถสันนิษฐานได้สำหรับการพัฒนาเว็บเมื่อเบราว์เซอร์ไม่เฉพาะเจาะจงโซลูชันควรทำงานข้ามระบบ บรรทัดฐานรองรับเบราว์เซอร์ทั้งหมด
— Chris

3
@Chris "บรรทัดฐานรองรับเบราว์เซอร์ทั้งหมด" - เฉพาะในกรณีที่คุณเป็นคนซาดิสม์ ไม่มีเหตุผลที่ดีที่จะหลีกเลี่ยงความดีของ HTML5 สำหรับผู้ใช้ทั่วโลก 2% ใน IE 8/9 caniuse.com/#feat=input-event
— Yarin

39

เกี่ยวกับสิ่งนี้:

<jQuery 1.7

$("#input").bind("propertychange change keyup paste input", function(){
    // do stuff;
});

> jQuery 1.7

$("#input").on("propertychange change keyup paste input", function(){
    // do stuff;
});

สามารถใช้งานได้กับ IE8 / IE9, FF, Chrome


1
ปัญหาที่ฉันมีกับคำตอบนี้คือไฟเมื่อคุณเบลอกล่องข้อความแม้ว่าค่าจะไม่เปลี่ยนแปลง ผู้กระทำผิดคือ "เปลี่ยน"
— Justin

คุณใช้ Chrome อยู่หรือเปล่า ดูเหมือนว่ามันเป็นข้อผิดพลาดกับโครเมี่ยมและไม่ใช่เหตุการณ์การเปลี่ยนแปลงของ jQuery bugs.jquery.com/ticket/9335
— Catfish

ใช้งานได้ แต่มีข้อผิดพลาดเล็กน้อยหากคุณทำconsole.logค่าของฟิลด์ที่บันทึกสองครั้งเมื่อคุณป้อนอักขระ
— ซามูเอลเอ็ม

21

ใช้การปิดเพื่อจดจำสิ่งที่เป็นข้อความในช่องทำเครื่องหมายก่อนที่จะกดปุ่มและตรวจสอบว่ามีการเปลี่ยนแปลง

อ๋อ คุณไม่จำเป็นต้องใช้การปิด แต่คุณจำเป็นต้องจำค่าเก่าและเปรียบเทียบกับสิ่งใหม่

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

ดังนั้นหากคุณต้องตรวจจับการเปลี่ยนแปลงทุกครั้งคุณต้องสำรวจความคิดเห็น คุณสามารถwindow.setIntervalตรวจสอบฟิลด์กับค่าก่อนหน้านี้ทุก ๆ (พูด) วินาที นอกจากนี้คุณยังสามารถลวดonkeyupฟังก์ชั่นเดียวกันดังนั้นการเปลี่ยนแปลงที่จะเกิดจากการกดแป้นจะสะท้อนให้เห็นได้เร็วขึ้น

ยุ่งยาก? ใช่. แต่นั่นเป็นเพียงวิธีการเปลี่ยน HTML ปกติและอย่าพยายามอัปเดตทันที


1
ทุกวันนี้inputเหตุการณ์HTML5 สามารถใช้งานได้และทำงานได้กับเบราว์เซอร์หลักทุกรุ่นในปัจจุบัน
— Tim Down

13
$(document).on('input','#mytxtBox',function () { 
 console.log($('#mytxtBox').val());
});

คุณสามารถใช้เหตุการณ์ 'อินพุท' เพื่อตรวจจับการเปลี่ยนแปลงเนื้อหาในกล่องข้อความ อย่าใช้ 'สด' เพื่อผูกกิจกรรมเนื่องจากเลิกใช้ใน Jquery-1.7 ดังนั้นใช้ประโยชน์จาก 'เปิด'


@NavaRajan เพิ่งทดสอบอีกครั้งใน IE9 ไม่ทำงานบน backspace จริงๆ
— ฟลอเรส

ฉันไม่ต้องการใช้ชีวิต แต่ปัญหาที่ฉันมีคือฉันกลับไป "กลับสู่อนาคต" และในโครงการ mvc3 ซึ่งผู้นำทีมต้องการติดกับ "นอกกรอบ" ดังนั้นจึงไม่ เฉพาะ EF 4.0 แต่กำลังใช้ jquery 1.5.1 THUS .on () ไม่ได้อยู่ใน 1.5.1 เนื่องจากมีการเพิ่มใน jquery เวอร์ชัน 1.7 api.jquery.com/on
— Tom Stickel

5

ฉันคิดว่าคุณกำลังมองหาที่จะทำสิ่งที่โต้ตอบเมื่อกล่องข้อความเปลี่ยนแปลง (เช่นดึงข้อมูลบางอย่างผ่าน ajax) ฉันกำลังมองหาฟังก์ชั่นเดียวกันนี้ ฉันรู้ว่าการใช้ทั่วโลกไม่ใช่โซลูชันที่แข็งแกร่งหรือสง่างามที่สุด แต่นั่นคือสิ่งที่ฉันไปด้วย นี่คือตัวอย่าง:

var searchValue = $('#Search').val();
$(function () {
    setTimeout(checkSearchChanged, 0.1);
});

function checkSearchChanged() {
    var currentValue = $('#Search').val();
    if ((currentValue) && currentValue != searchValue && currentValue != '') {
        searchValue = $('#Search').val();
        $('#submit').click();
    }
    else {
        setTimeout(checkSearchChanged, 0.1);
    }
}

สิ่งสำคัญประการหนึ่งที่ควรทราบที่นี่คือฉันใช้ setTimeout และไม่ได้ตั้งค่า Interterval เนื่องจากฉันไม่ต้องการส่งคำขอหลายรายการพร้อมกัน สิ่งนี้ทำให้มั่นใจได้ว่าตัวจับเวลา "หยุด" เมื่อส่งแบบฟอร์มและ "เริ่มต้น" เมื่อคำขอเสร็จสมบูรณ์ ฉันทำสิ่งนี้โดยการเรียก checkSearchChanged เมื่อการโทร ajax ของฉันเสร็จสิ้น เห็นได้ชัดว่าคุณสามารถขยายสิ่งนี้เพื่อตรวจสอบความยาวขั้นต่ำ ฯลฯ

ในกรณีของฉันฉันใช้ ASP.Net MVC เพื่อให้คุณสามารถดูวิธีการผูกกับ MVC Ajax และในโพสต์ต่อไปนี้:

http://geekswithblogs.net/DougLampe/archive/2010/12/21/simple-interactive-search-with-jquery-and-asp.net-mvc.aspx


4

ฉันอยากจะแนะนำให้ดูที่วิดเจ็ตเติมข้อความอัตโนมัติ jQuery UI พวกเขาจัดการกรณีส่วนใหญ่ที่นั่นเนื่องจากฐานรหัสของพวกเขาเป็นผู้ใหญ่กว่าคนส่วนใหญ่ออกมี

ด้านล่างคือลิงค์ไปยังหน้าตัวอย่างเพื่อให้คุณสามารถตรวจสอบได้ http://jqueryui.com/demos/autocomplete/#default

คุณจะได้รับประโยชน์สูงสุดจากการอ่านแหล่งข้อมูลและดูว่าพวกเขาแก้ไขอย่างไร คุณสามารถค้นหาได้ที่นี่: https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.autocomplete.js

โดยพื้นฐานแล้วพวกเขาทำทุกinput, keydown, keyup, keypress, focus and blurอย่าง page up, page down, up arrow key and down arrow keyจากนั้นพวกเขามีการจัดการพิเศษสำหรับทุกประเภทของคีย์เช่น มีการใช้ตัวจับเวลาก่อนรับเนื้อหาของกล่องข้อความ เมื่อผู้ใช้พิมพ์คีย์ที่ไม่สอดคล้องกับคำสั่ง (คีย์ up, down down และอื่น ๆ ) จะมีตัวจับเวลาที่สำรวจเนื้อหาหลังจากนั้นประมาณ 300 มิลลิวินาที ดูเหมือนว่าในรหัส:

// switch statement in the 
switch( event.keyCode ) {
            //...
            case keyCode.ENTER:
            case keyCode.NUMPAD_ENTER:
                // when menu is open and has focus
                if ( this.menu.active ) {
                    // #6055 - Opera still allows the keypress to occur
                    // which causes forms to submit
                    suppressKeyPress = true;
                    event.preventDefault();
                    this.menu.select( event );
                }
                break;
            default:
                suppressKeyPressRepeat = true;
                // search timeout should be triggered before the input value is changed
                this._searchTimeout( event );
                break;
            }
// ...
// ...
_searchTimeout: function( event ) {
    clearTimeout( this.searching );
    this.searching = this._delay(function() { // * essentially a warpper for a setTimeout call *
        // only search if the value has changed
        if ( this.term !== this._value() ) { // * _value is a wrapper to get the value *
            this.selectedItem = null;
            this.search( null, event );
        }
    }, this.options.delay );
},

เหตุผลที่ใช้ตัวจับเวลาคือเพื่อให้ UI ได้รับโอกาสในการอัปเดต เมื่อ Javascript กำลังเรียกใช้ UI ไม่สามารถอัปเดตได้ดังนั้นการเรียกไปยังฟังก์ชั่นการหน่วงเวลา สิ่งนี้ทำงานได้ดีสำหรับสถานการณ์อื่น ๆ เช่นการมุ่งเน้นไปที่กล่องข้อความ (ใช้โดยรหัสนั้น)

ดังนั้นคุณสามารถใช้วิดเจ็ตหรือคัดลอกรหัสลงในวิดเจ็ตของคุณเองหากคุณไม่ได้ใช้ jQuery UI (หรือในกรณีของฉันในการพัฒนาวิดเจ็ตที่กำหนดเอง)


2

ผมอยากจะถามว่าทำไมคุณกำลังพยายามที่จะตรวจสอบเมื่อเนื้อหาของช่องที่มีการเปลี่ยนแปลงในเวลาจริง ?

อีกทางเลือกหนึ่งคือการตั้งเวลา (ผ่าน setIntval?) และเปรียบเทียบค่าที่บันทึกล่าสุดกับค่าปัจจุบันแล้วรีเซ็ตตัวจับเวลา สิ่งนี้จะรับประกันว่าจะได้รับการเปลี่ยนแปลงใด ๆ ไม่ว่าจะเกิดจากกุญแจ, เมาส์, อุปกรณ์ป้อนข้อมูลอื่น ๆ ที่คุณไม่ได้พิจารณาหรือแม้แต่การเปลี่ยนค่าจาวาสคริปต์


สถานการณ์ของฉัน (ซึ่งทำให้ฉันมีคำถามนี้) คือฉันต้องแสดงปุ่ม 'อัปเดตรถเข็น' เมื่อปริมาณในกล่องข้อความเปลี่ยนไป ผู้ใช้ไม่มีความคิดที่พวกเขาต้องสูญเสียการโฟกัสและอาจไม่เห็นปุ่ม
— Simon_Weaver

ขออภัยฉันไม่แน่ใจว่านี่จะตอบคำถามของ "ทำไมไม่ตรวจสอบความแตกต่างในตาราง" เพียงตรวจสอบบ่อยครั้งพอ (ทุก ๆ 1/4 ของวินาที) และผู้ใช้จะไม่ทราบความแตกต่าง
— DVK

1

คุณพิจารณาใช้เหตุการณ์การเปลี่ยนแปลงหรือไม่

$("#myTextBox").change(function() { alert("content changed"); });

5
AFAIK จะถูกกระตุ้นเมื่อการโฟกัสขององค์ประกอบหายไป คนที่คุ้นเคยกับการปิดอาจรู้เกี่ยวกับเรื่องนี้ :)
— simon

ใช่สิ่งนี้จะไม่ทำ - เหตุการณ์การเปลี่ยนแปลงจะถูกเรียกก็ต่อเมื่อกล่องข้อความหมดโฟกัส ฉันต้องการจัดการการเปลี่ยนแปลงทันทีหลังจากกดแป้น
— olamundo

1

ใช้textchangeเหตุการณ์ผ่าน jQuery shim ที่กำหนดเองเพื่อinputความเข้ากันได้ข้ามเบราว์เซอร์ http://benalpert.com/2013/06/18/a-near-perfect-oninput-shim-for-ie-8-and-9.html http://genubperpert.com/?hl=th (GitHub ที่แยกจากกันล่าสุด: https://github.com/pandell /jquery-splendid-textchange/blob/master/jquery.splendid.textchange.js )

จับนี้แท็กเข้าทั้งหมดรวมทั้ง<textarea>content</textarea>ที่ไม่เคยทำงานร่วมกับchange keyupฯลฯ (!) เท่านั้น jQuery on("input propertychange")จับ<textarea>แท็กอย่างต่อเนื่องและที่กล่าวมาเป็นชิมเบราว์เซอร์ทั้งหมดที่ไม่เข้าใจinputเหตุการณ์

<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://raw.githubusercontent.com/pandell/jquery-splendid-textchange/master/jquery.splendid.textchange.js"></script>
<meta charset=utf-8 />
<title>splendid textchange test</title>

<script> // this is all you have to do. using splendid.textchange.js

$('textarea').on("textchange",function(){ 
  yourFunctionHere($(this).val());    });  

</script>
</head>
<body>
  <textarea style="height:3em;width:90%"></textarea>
</body>
</html>

ทดสอบ JS Bin

นอกจากนี้ยังจัดการวางลบและไม่ทำซ้ำความพยายามในการคีย์

หากไม่ได้ใช้ชิมให้ใช้ jQuery on("input propertychange")events

// works with most recent browsers (use this if not using src="...splendid.textchange.js")

$('textarea').on("input propertychange",function(){ 
  yourFunctionHere($(this).val());    
});  

0

มีตัวอย่างการทำงานที่สมบูรณ์เป็นที่นี่

<html>
<title>jQuery Summing</title>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"> </script>
$(document).ready(function() {
$('.calc').on('input', function() {
var t1 = document.getElementById('txt1');
var t2 = document.getElementById('txt2');
var tot=0;
if (parseInt(t1.value))
tot += parseInt(t1.value);
if (parseInt(t2.value))
tot += parseInt(t2.value);
document.getElementById('txt3').value = tot;
});
});
</script>
</head>
<body>
<input type='text' class='calc' id='txt1'>
<input type='text' class='calc' id='txt2'>
<input type='text' id='txt3' readonly>
</body>
</html>

0

บางสิ่งเช่นนี้ควรใช้งานได้เป็นหลักเพราะfocusและfocusoutจะจบลงด้วยค่าที่แยกกันสองค่า ฉันกำลังใช้dataที่นี่เพราะมันเก็บค่าในองค์ประกอบ แต่ไม่ได้สัมผัส DOM นอกจากนี้ยังเป็นวิธีที่ง่ายในการจัดเก็บค่าที่เชื่อมต่อกับองค์ประกอบ คุณสามารถใช้ตัวแปรที่มีขอบเขตสูงกว่าได้อย่างง่ายดาย

var changed = false;

$('textbox').on('focus', function(e) {
    $(this).data('current-val', $(this).text();
});

$('textbox').on('focusout', function(e) {
    if ($(this).data('current-val') != $(this).text())
        changed = true;
    }
    console.log('Changed Result', changed);
}

0

รหัสนี้จะตรวจจับเมื่อใดก็ตามที่เนื้อหาของกล่องข้อความมีการเปลี่ยนแปลงโดยผู้ใช้และแก้ไขโดยรหัส Javascript

var $myText = jQuery("#textbox");

$myText.data("value", $myText.val());

setInterval(function() {
    var data = $myText.data("value"),
    val = $myText.val();

    if (data !== val) {
        console.log("changed");
        $myText.data("value", val);
    }
}, 100);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.