Cách phát hiện nội dung của hộp văn bản đã thay đổi


417

Tôi muốn phát hiện bất cứ khi nào nội dung của hộp văn bản đã thay đổi. Tôi có thể sử dụng phương thức gõ phím, nhưng điều đó cũng sẽ phát hiện các tổ hợp phím không tạo ra các chữ cái, như các phím mũi tên. Tôi đã nghĩ đến hai phương pháp để làm điều này bằng cách sử dụng sự kiện keyup:

  1. Kiểm tra một cách rõ ràng nếu mã ascii của phím được nhấn là một chữ cái \ backspace \ xóa
  2. Sử dụng các bao đóng để ghi nhớ văn bản trong hộp văn bản trước hành trình phím và kiểm tra xem điều này đã thay đổi.

Cả hai trông hơi cồng kềnh.


7
Đúng, bắt keyup cho điều này là xấu. Bạn có thể dán công cụ mà không cần nhấn phím nào cả.
tiêu

2
bất kỳ cơ hội bạn có thể gửi giải pháp cuối cùng của bạn? Tôi cũng cần phải giải quyết vấn đề này :)
Matt Dotson

1
hoặc .keyup()sự kiện ... thông tin thêm ở đây: stackoverflow.com/questions/3003879/ từ
Victor S

1
Xem $ ("# some-input"). ChangePolling () ; cho một trình bao bọc kiểm tra giá trị hiện tại và kích hoạt .change()nếu nó đã thay đổi.
Joel Purra

bạn cũng cần kiểm tra stackoverflow.com/a/23266812/3160597
azerafati

Câu trả lời:


714

Bắt đầu quan sát sự kiện 'đầu vào' thay vì 'thay đổi'.

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

... đó là tốt đẹp và sạch sẽ, nhưng có thể được mở rộng hơn nữa để:

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

12
"Sống" không được dùng nữa. vì vậy, hãy sử dụng 'on' stackoverflow.com/a/15111970/1724777
NavaRajan

21
Sự sụp đổ duy nhất của 'đầu vào' là nó không tương thích với IE <9
Catfish

5
đầu vào là sự kiện html5 không được hỗ trợ trong tất cả các trình duyệt. developer.mozilla.org/en-US/docs/Web/API/window.oninput
commonpike

18
Bạn cũng có thể bao gồm nhiều cơ sở hơn bằng cách sử dụng: .on ('dán thay đổi thuộc tính đầu vào', function () {
Graeck

23
Sự sụp đổ duy nhất của IE <9 là không ai sử dụng nó!
sohaiby

67

Sử dụng sự kiện onchange trong HTML / JavaScript chuẩn.

Trong jQuery đó là sự kiện thay đổi () . Ví dụ:

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

BIÊN TẬP

Sau khi đọc một số ý kiến, những gì về:

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

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

3
Vâng, điều này tương tự với những gì tôi đề xuất trong tùy chọn # 2 trong câu hỏi của tôi. Tôi thích đóng cửa vì sử dụng toàn cầu sẽ làm cho chức năng này chỉ hoạt động cho một hộp văn bản. Dù sao, có vẻ như jquery kỳ lạ không có cách nào đơn giản hơn để làm điều này.
olamundo

1
Nó thực sự kỳ lạ, nhưng tôi nghi ngờ có một cách tốt hơn để làm điều đó. Bạn có thể sử dụng setInterval và sau đó kiểm tra xem nội dung có bị thay đổi cứ sau 0,1 giây không và sau đó làm gì đó. Điều này cũng sẽ bao gồm bột nhão chuột và như vậy. Nhưng nó không có vẻ quá thanh lịch.
Waleed Amjad

4
Vẫn có thể thay đổi nội dung mà không cần nhấn phím, ví dụ bằng cách dán bằng chuột. Nếu bạn quan tâm về điều này, về mặt lý thuyết bạn cũng có thể bắt các sự kiện chuột, nhưng thiết lập đó thậm chí còn xấu hơn. Mặt khác, nếu bạn sẵn sàng bỏ qua các thay đổi do chuột điều khiển, điều này sẽ làm được.
Adam Bellaire

45

Sự kiện 'thay đổi' không hoạt động chính xác, nhưng 'đầu vào' là hoàn hảo.

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

7
Điều này hoạt động hoàn hảo cho tình huống của tôi, mặc dù việc sử dụng .onđược khuyến nghị từ 1.7 trở đi (chứ không phải .bind).
Nick

8
OP không xác định nhu cầu tương thích trình duyệt chéo. @schwarzkopfb cung cấp một giải pháp. Không có lý do để bỏ phiếu xuống vì bạn có đại diện để làm như vậy.
David East

3
@David anh cũng không chỉ định trình duyệt nào
ozz

9
@ jmo21 Tôi nghĩ rằng chúng ta có thể giả định để phát triển web khi trình duyệt không cụ thể, giải pháp sẽ có chức năng chéo. Các tiêu chuẩn là hỗ trợ tất cả các trình duyệt.
Chris

3
@Chris "Định mức hỗ trợ tất cả các trình duyệt" - chỉ khi bạn là người tàn bạo. Không có lý do chính đáng nào để tránh sự tốt lành của HTML5 cho 2% người dùng toàn cầu trên IE 8/9. caniuse.com/#feat=input-event
Yarin

39

Còn cái này thì sao:

<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;
});

Điều này hoạt động trong IE8 / IE9, FF, Chrome


1
Vấn đề tôi gặp phải với câu trả lời này là nó kích hoạt một khi bạn làm mờ hộp văn bản, ngay cả khi giá trị không thay đổi. Thủ phạm là "thay đổi".
Justin

Bạn có đang sử dụng Chrome không? Có vẻ như đó là một lỗi với chrome và không phải là sự kiện thay đổi của jQuery bug.jquery.com/ticket/9335
Catfish

hoạt động nhưng có một lỗi nhỏ nếu bạn thực hiện một console.loggiá trị của trường mà nó ghi nhật ký hai lần bất cứ khi nào bạn nhập vào một ký tự.
Samuel M.

21

Sử dụng các bao đóng để ghi nhớ văn bản trong hộp kiểm trước hành trình phím và kiểm tra xem điều này đã thay đổi.

Vâng. Bạn không nhất thiết phải sử dụng các bao đóng, nhưng bạn sẽ cần nhớ giá trị cũ và so sánh nó với giá trị mới.

Tuy nhiên! Điều này vẫn sẽ không nắm bắt được mọi thay đổi, bởi vì có một cách chỉnh sửa nội dung hộp văn bản không liên quan đến bất kỳ phím nhấn nào. Ví dụ: chọn một phạm vi văn bản sau đó nhấp chuột phải. Hoặc kéo nó. Hoặc thả văn bản từ một ứng dụng khác vào hộp văn bản. Hoặc thay đổi một từ thông qua kiểm tra chính tả của trình duyệt. Hoặc là...

Vì vậy, nếu bạn phải phát hiện mọi thay đổi, bạn phải bỏ phiếu cho nó. Bạn có thể window.setIntervalkiểm tra trường so với giá trị trước đó mỗi giây. Bạn cũng có thể dây onkeyupvào chức năng tương tự để thay đổi điều đó được gây ra bởi keypresses được phản ánh nhanh hơn.

Cồng kềnh? Đúng. Nhưng đó là hoặc chỉ làm theo cách trao đổi HTML thông thường và không thử cập nhật tức thì.


1
Ngày nay, inputsự kiện HTML5 là khả thi và hoạt động trong các phiên bản hiện tại của tất cả các trình duyệt chính.
Tim Down

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

Bạn có thể sử dụng sự kiện 'đầu vào' để phát hiện thay đổi nội dung trong hộp văn bản. Đừng sử dụng 'live' để liên kết sự kiện vì nó không được dùng trong Jquery-1.7, vì vậy hãy sử dụng 'on'.


@NavaRajan Chỉ cần thử nghiệm lại trong IE9. thực sự không hoạt động trên backspace.
Flores

Tôi muốn KHÔNG sử dụng .live, nhưng vấn đề tôi gặp phải là bằng cách nào đó tôi đã "quay về tương lai" và trong một dự án mvc3 mà trưởng nhóm muốn gắn bó với "ngoài luồng" chỉ có EF 4.0, nhưng jquery 1.5.1 đang được sử dụng THUS .on () không có trong 1.5.1, vì nó đã được thêm vào trong phiên bản jquery 1.7 api.jquery.com/on
Tom Stickel

5

Tôi giả sử rằng bạn đang muốn làm một cái gì đó tương tác khi hộp văn bản thay đổi (tức là lấy một số dữ liệu qua ajax). Tôi đã tìm kiếm chức năng tương tự. Tôi biết sử dụng toàn cầu không phải là giải pháp mạnh mẽ hay thanh lịch nhất, nhưng đó là những gì tôi đã làm. Đây là một ví dụ:

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);
    }
}

Một điều quan trọng cần lưu ý ở đây là tôi đang sử dụng setTimeout chứ không phải setInterval vì tôi không muốn gửi nhiều yêu cầu cùng một lúc. Điều này đảm bảo rằng bộ hẹn giờ "dừng" khi biểu mẫu được gửi và "bắt đầu" khi yêu cầu hoàn tất. Tôi làm điều này bằng cách gọi checkSearchChanged khi cuộc gọi ajax của tôi hoàn tất. Rõ ràng bạn có thể mở rộng điều này để kiểm tra độ dài tối thiểu, v.v.

Trong trường hợp của tôi, tôi đang sử dụng ASP.Net MVC để bạn có thể xem cách kết hợp điều này với MVC Ajax cũng như trong bài sau:

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


4

Tôi khuyên bạn nên xem qua tiện ích tự động hoàn thành giao diện người dùng jQuery. Họ đã xử lý hầu hết các trường hợp ở đó vì cơ sở mã của họ trưởng thành hơn hầu hết các trường hợp ngoài kia.

Dưới đây là một liên kết đến một trang demo để bạn có thể xác minh nó hoạt động. http://jqueryui.com/demos/autocomplete/#default

Bạn sẽ nhận được nhiều lợi ích nhất từ ​​việc đọc nguồn và xem cách họ giải quyết nó. Bạn có thể tìm thấy nó ở đây: https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.autocomplete.js .

Về cơ bản họ làm tất cả, họ ràng buộc input, keydown, keyup, keypress, focus and blur. Sau đó, họ có xử lý đặc biệt cho tất cả các loại khóa như page up, page down, up arrow key and down arrow key. Một bộ đếm thời gian được sử dụng trước khi nhận được nội dung của hộp văn bản. Khi người dùng nhập một khóa không tương ứng với một lệnh (phím lên, phím xuống và vv), có một bộ đếm thời gian khám phá nội dung sau khoảng 300 mili giây. Có vẻ như trong mã này:

// 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 );
},

Lý do để sử dụng bộ đếm thời gian là để UI có cơ hội được cập nhật. Khi Javascript đang chạy, UI không thể được cập nhật, do đó, gọi chức năng trì hoãn. Điều này hoạt động tốt cho các tình huống khác như giữ tập trung vào hộp văn bản (được sử dụng bởi mã đó).

Vì vậy, bạn có thể sử dụng tiện ích con hoặc sao chép mã vào tiện ích của riêng mình nếu bạn không sử dụng Giao diện người dùng jQuery (hoặc trong trường hợp của tôi là phát triển tiện ích tùy chỉnh).


2

Tôi muốn hỏi tại sao bạn đang cố gắng phát hiện khi nội dung của hộp văn bản thay đổi trong thời gian thực ?

Một cách khác là đặt bộ hẹn giờ (thông qua setIntval?) Và so sánh giá trị đã lưu cuối cùng với giá trị hiện tại và sau đó đặt lại bộ hẹn giờ. Điều này sẽ đảm bảo bắt được BẤT K change thay đổi nào, cho dù do phím, chuột, một số thiết bị đầu vào khác mà bạn không xem xét hoặc thậm chí JavaScript thay đổi giá trị (một khả năng khác không ai đề cập) từ một phần khác của ứng dụng.


tình huống của tôi (dẫn đến câu hỏi này) là tôi cần hiển thị nút 'Cập nhật giỏ hàng' khi số lượng trong hộp văn bản được thay đổi. Người dùng không biết họ cần mất tập trung và có thể không thấy nút.
Simon_Weaver

Xin lỗi, tôi không chắc chắn rằng điều này trả lời câu hỏi "tại sao không kiểm tra khác biệt theo lịch trình". Chỉ cần kiểm tra thường xuyên đủ (cứ sau 1/4 giây) và người dùng sẽ không biết bất kỳ sự khác biệt nào.
DVK

1

Bạn có cân nhắc sử dụng sự kiện thay đổi không?

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

5
AFAIK, nó chỉ được kích hoạt khi mất tiêu điểm của phần tử. Một người quen thuộc với việc đóng cửa có lẽ biết về điều này. :)
simon

có, điều này sẽ không xảy ra - sự kiện thay đổi chỉ được gọi khi hộp văn bản mất tiêu điểm. Tôi muốn xử lý thay đổi ngay sau khi nhấn phím.
olamundo

1

Sử dụng textchangesự kiện thông qua shim jQuery tùy chỉnh để inputtương thích trình duyệt chéo . http://benalpert.com/2013/06/18/a-gần-perinf-oninput-shim-for-ie-8-and-9.html (github mới nhất gần đây nhất: https://github.com/pandell /jquery-splendid-textchange/blob/master/jquery.splendid.textchange.js )

Điều này xử lý tất cả các thẻ đầu vào bao gồm <textarea>content</textarea>, không phải lúc nào cũng hoạt động với change keyupv.v. (!) Chỉ jQuery on("input propertychange")xử lý <textarea>các thẻ một cách nhất quán và ở trên là một shim cho tất cả các trình duyệt không hiểu inputsự kiện.

<!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>

Kiểm tra thùng rác

Điều này cũng xử lý dán, xóa và không trùng lặp nỗ lực trên keyup.

Nếu không sử dụng shim, hãy sử dụng on("input propertychange")các sự kiện jQuery .

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

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

0

Có một ví dụ hoạt động hoàn chỉnh ở đây .

<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

Một cái gì đó như thế này sẽ hoạt động, chủ yếu là vì focusfocusoutsẽ kết thúc với hai giá trị riêng biệt. Tôi đang sử dụng dataở đây vì nó lưu trữ các giá trị trong phần tử nhưng không chạm vào DOM. Nó cũng là một cách dễ dàng để lưu trữ giá trị được kết nối với phần tử của nó. Bạn có thể dễ dàng sử dụng một biến có phạm vi cao hơn.

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

Mã này phát hiện bất cứ khi nào nội dung của hộp văn bản được người dùng thay đổi và sửa đổi bằng mã 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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.