テキストボックスのコンテンツを検出する方法が変更されました


417

テキストボックスのコンテンツが変更されたときに検出したいと思います。keyupメソッドを使用できますが、矢印キーのように文字を生成しないキーストロークも検出されます。keyupイベントを使用してこれを行う2つの方法を考えました。

  1. 押されたキーのASCIIコードがletter \ backspace \ deleteかどうかを明示的に確認します
  2. クロージャーを使用して、キーストロークの前のテキストボックス内のテキストを記憶し、これが変更されたかどうかを確認します。

どちらもちょっと面倒に見えます。


7
うん、これのキーアップをキャッチするのは悪い。キーを押すことなく、何でも貼り付けることができます。
13:06

2
最終的な解決策を投稿できる可能性はありますか?私もこの問題を解決する必要があります:)
Matt Dotson

1
または.keyup()イベント...詳細: stackoverflow.com/questions/3003879/...
ビクターS

1
$( "#some-input")。changePolling()を参照してください。現在の値をチェックし、.change()変更された場合にトリガーするラッパーの場合。
Joel Purra、2012

あなたもこれを確認する必要が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
'live'は非推奨です。その「オン」を利用してstackoverflow.com/a/15111970/1724777
NavaRajan

21
唯一の没落「入力」のそれはIE <9と互換性がないということである
ナマズ

5
入力はすべてのブラウザでサポートされているわけではないhtml5イベントです。developer.mozilla.org/en-US/docs/Web/API/window.oninput
commonpike 2013年

18
.on( 'input propertychange paste'、function(){
Graeck

23
IE <9の唯一の欠点は、誰もそれを使用しないことです!
sohaiby 2015

67

HTML /標準JavaScriptでonchangeイベントを使用します。

jQueryではchange()イベントです。例えば:

$('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で提案したものと似ています。グローバルを使用すると、この関数が1つのテキストボックスでのみ機能するようになるため、私はクロージャーを好みます。とにかく、奇妙なjqueryにはこれを行う簡単な方法がないようです。
olamundo 2009

1
それは確かに奇妙ですが、私はそれを行うより良い方法があるとは思いません。setIntervalを使用して、コンテンツが0.1秒ごとに変更されたかどうかを確認してから、何かを行うことができます。これには、マウスペーストなども含まれます。しかし、それはあまりにもエレガントに聞こえません。
Waleed Amjad

4
マウスで貼り付けるなどして、キーストロークなしでコンテンツを変更することも可能です。これを気にすれば、理論的にはマウスイベントをキャッチすることもできますが、その設定はさらに醜いです。一方、マウスによる変更を無視しても構わない場合は、これで十分です。
アダムベレア

45

「変更」イベントは正しく機能しませんが、「入力」は完全です。

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

7
これは私の状況では完全に機能しますが、.on(ではなく.bind)1.7以降からの使用が推奨されています。
Nick

8
OPは、ブラウザー間の互換性の必要性を指定していません。@schwarzkopfbがソリューションを提供しました。投票する担当者がいるため、投票する理由はありません。
David East

3
@David彼はまた、どのブラウザを指定していない
ozz

9
@ jmo21私は、ブラウザーが特定されていない場合にソリューションが部門連係である必要がある場合、Web開発を想定できると思います。標準はすべてのブラウザをサポートしています。
Chris

3
@Chris「規範はすべてのブラウザをサポートしています」-あなたがサディストである場合のみ。IE 8/9のグローバルユーザーの2%がHTML5の良さを回避する正当な理由はありません。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
この回答で私が抱えている問題は、値を変更していなくても、テキストボックスをぼかすと発火することです。犯人は「変化」です。
ジャスティン

Chromeを使用していますか?それはクロムのバグであり、jQueryの変更イベントではないようです。bugs.jquery.com/ ticket / 9335
Catfish

機能しconsole.logますが、文字を入力するたびにフィールドの値を2回記録すると、マイナーなバグが発生します。
Samuel M.

21

クロージャを使用して、キーストロークの前のチェックボックスのテキストを思い出し、これが変更されたかどうかを確認します。

うん。必ずしもクロージャーを使用する必要はありませんが、古い値を覚えて新しい値と比較する必要があります。

しかしながら!キーボックスを使用しないテキストボックスコンテンツを編集する方法があるため、これはすべての変更をキャッチしません。たとえば、テキストの範囲を選択してから右クリックしてカットします。またはそれをドラッグします。または、別のアプリからテキストボックスにテキストをドロップします。または、ブラウザのスペルチェックを介して単語を変更します。または...

したがって、すべての変更を検出する必要がある場合は、それをポーリングする必要があります。window.setInterval(たとえば)秒ごとにフィールドを以前の値と照合することができます。また、配線可能性がonkeyup変化するように同じ関数にされているキー入力によって引き起こされるが迅速に反映されています。

面倒?はい。しかし、それはそれであるか、それを通常のHTML onchangeの方法で行うだけで、即時更新を試みないでください。


1
最近、HTML5 inputイベントは実行可能であり、すべての主要ブラウザの現在のバージョンで動作します。
Tim Down

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

'input'イベントを使用して、テキストボックスのコンテンツの変更を検出できます。Jquery-1.7で非推奨になっているため、イベントのバインドに「live」を使用しないでください。したがって、「on」を使用してください。


@NavaRajan IE9でもう一度テストしました。バックスペースでは実際には機能しません。
フローレス

.liveを使用したくないが、私が抱えている問題は、「未来に戻る」ことと、チームリーダーが「そのまま」に固執したいmvc3プロジェクトに何らかの形で行ってしまったことです。 EF 4.0のみですが、jquery 1.5.1が使用されていますTHUS .on()は1.5.1にはありませんでした。jquery
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);
    }
}

ここで注意すべき重要な点の1つは、同時に複数のリクエストを送信したくないため、setIntervalではなくsetTimeoutを使用していることです。これにより、フォームが送信されるとタイマーが「停止」し、リクエストが完了するとタイマーが「開始」します。これを行うには、私のajax呼び出しが完了したときにcheckSearchChangedを呼び出します。もちろん、これを拡張して最小長などをチェックすることもできます。

私の場合、私は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。テキストボックスのコンテンツを取得する前にタイマーが使用されます。ユーザーがコマンドに対応しないキー(上キー、下キーなど)を入力すると、約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?を介して)タイマーを設定し、最後に保存された値を現在の値と比較して、タイマーをリセットする方法があります。これにより、キー、マウス、考慮しなかったその他の入力デバイス、またはJavaScriptがアプリの別の部分から値を変更した(他の可能性については誰も言及していない)場合でも、すべての変更をキャッチできます。


私の状況(この質問につながった)は、テキストボックスの数量が変更されたときに[カートの更新]ボタンを表示する必要があることです。ユーザーはフォーカスを失う必要があることを理解していないため、ボタンが表示されない場合があります。
Simon_Weaver 2009年

「スケジュールで差分を確認しないのはなぜですか」という質問にこれで答えられるかどうかはわかりません。十分な頻度(1/4秒ごと)で確認するだけで、ユーザーは違いを知ることができません。
DVK

1

変更イベントの使用を検討しますか?

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

5
AFAIK、それは要素のフォーカスが失われたときにのみトリガーされます。クロージャーに精通している人は、おそらくこれについて知っています。:)
サイモン

はい、これはできません-changeイベントは、テキストボックスがフォーカスを失ったときにのみ呼び出されます。キーを押した直後の変化に対応したい。
olamundo 2009

1

textchangeブラウザー間のinput互換性のために、カスタマイズされたjQueryシムを介してイベントを使用します。http://benalpert.com/2013/06/18/a-near-perfect-oninput-shim-for-ie-8-and-9.html(最も最近分岐された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")イベントを使用します。

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

このようなものが機能するはずです。主な理由はfocusfocusout最終的に2つの異なる値になるためです。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.