jQuery-非表示の入力フィールドで値の変更を検出する


270

AJAX応答によって値が更新される非表示のテキストフィールドがあります。

<input type="hidden" value="" name="userid" id="useid" />

この値が変更されたときに、AJAXリクエストを発行したいと思います。誰でも変更を検出する方法についてアドバイスできますか?

次のコードがありますが、値を探す方法がわかりません。

$('#userid').change( function() {  
    alert('Change!'); 
}) 

2
ajax応答を介して更新される場合は、応答の成功関数で新しいajax要求を実行してみませんか?
BonyT 2011年

2
$( '#userid')。val()は、それがあなたが求めているものである場合に値を提供します
BonyT

更新:非表示フィールドの値が更新されると、変更イベントがトリガーされるようになりました。
Steven

回答:


622

これはかなり遅いですが、このスレッドに出くわした人に役立つように、答えを見つけました。

非表示の要素の値が変更されても、.change()イベントは自動的に発生しません。したがって、その値を設定している場合はどこでも、jQueryにトリガーするように指示する必要があります。

function setUserID(myValue) {
     $('#userid').val(myValue)
                 .trigger('change');
}

そうなれば、

$('#userid').change(function(){
      //fire your ajax call  
})

期待どおりに動作するはずです。


5
ある.trigger()だけで呼び出す以上使用することが一般的により良いですかchange()
ハンナ

1
動作しますが、変更イベントが2回トリガーされるようです。このコードを配置すると、2回トリガーされます。コードを削除すると、トリガーは発生しません。!!
Janx、ベネズエラから2013

1
changeイベントと同じように動作させるには、コードを追加しsetUserID()て、値が実際に変更されているかどうかを確認する必要があります。if ($('#userid').val() != myVaule) { // set val() and trigger change }
nnattawat 2015年

1
あなたはjavascriptを介して変更されていると、そうでない場合はJavaScriptによって行われた変更は.change(ハンドラ)または.on(「変更」、ハンドラ)で捕捉することができないことを「変更」イベントをキャッチしようとしているしている場合に特に便利です
JJK

7
したがって、非表示フィールドの値を変更する関数を制御できない(つまり、トリガーを起動できない)場合、このソリューションは機能しません。
osama yaccoub

31

非表示の入力は変更時に「変更」イベントをトリガーしないため、代わりにMutationObserverを使用してこれをトリガーします。

(非表示の入力値の変更は、変更できない他のスクリプトによって行われる場合があります)

これはIE10以下では機能しません

MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

var trackChange = function(element) {
  var observer = new MutationObserver(function(mutations, observer) {
    if(mutations[0].attributeName == "value") {
        $(element).trigger("change");
    }
  });
  observer.observe(element, {
    attributes: true
  });
}

// Just pass an element to the function to start tracking
trackChange( $("input[name=foo]")[0] );

私の知る限り、mutationobserverはテキストフィールド内の変更に対しても非表示になりません(非表示にされているかどうかに関係なく)
Ole Albers

3
よく働く!@OleAlbers-OPについて質問input[type=hidden]
Shay

1
これを、jqueryのmapコマンドを使用して非表示の入力フィールド値のコレクションを取得する関数と組み合わせて使用​​しました。@lulalala、どうもありがとう!
アダムジョーンズ

2
シンプルでわかりやすい。このソリューションは、「値を変更したときにイベントをトリガーする必要がある」ソリューションとは対照的に、値が変更された時点でプログラマがコードにアクセスできることに依存せず、そうしない限りより有用になります。 IE11より古いバージョンをサポートする必要はありません。それは私にとってはうまくいきました。ありがとう
Joe Salazar、

素晴らしい解決策!ありがとうございました!何らかの理由でtrigger('change')、私はCustomEventを作成しましたので、それを登録してから、私のために仕事をしませんでしたelement.dispatchEvent(myCustomEvent)
tbutcaru

8

以下の関数を使用するだけで、type要素を変更することもできます。

 $("input[type=hidden]").bind("change", function() {
       alert($(this).val()); 
 });

非表示要素の値が変更されても、.change()イベントは自動的に発生しません。したがって、その値を設定している場合はどこでも、jQueryにトリガーするように指示する必要があります。

HTML

 <div id="message"></div>
<input type="hidden" id="testChange" value="0"  />    

ジャバスクリプト

var $message = $('#message');
var $testChange = $('#testChange');
var i = 1;

function updateChange() {
    $message.html($message.html() + '<p>Changed to ' + $testChange.val() + '</p>');
}

$testChange.on('change', updateChange);

setInterval(function() {
    $testChange.val(++i).trigger('change');; 
    console.log("value changed" +$testChange.val());
}, 3000);

updateChange();

期待どおりに動作するはずです。

http://jsfiddle.net/7CM6k/3/


1
うまくいきません...とにかく、隠しフィールドに値を貼り付けることができるのはなぜですか?:/
SimonDugré2014

ねえありがとうございます。貼り付けはありませんが、変更によって隠しフィールドの変更イベントを検出できます
Tarun Gupta 14

@KrisEricksonフィドルをありがとう、変更を明示的に検出できるようにコードを更新しました。更新されたフィドルjsfiddle.net/7CM6k/3を
Tarun Gupta

1
@TarunGuptaええ、それはトリガーで機能していますが、値を変更していません。非表示の値が変更された場合、ブラウザーは変更イベントを発生させません。手動で行う必要があります。
クリスエリクソン2014

すべての非表示フィールドへのバインドに関するこの回答の最初の部分は非常に役に立ちました。ありがとう!
チャド


4

Object.defineProperty()入力要素の「値」プロパティを再定義し、その変更中に何かを行うために使用できます。

Object.defineProperty() プロパティのゲッターとセッターを定義して、それを制御できるようにします。

replaceWithWrapper($("#hid1")[0], "value", function(obj, property, value) { 
  console.log("new value:", value)
});

function replaceWithWrapper(obj, property, callback) {
  Object.defineProperty(obj, property, new function() {
    var _value = obj[property];
    return {
      set: function(value) {
        _value = value;
        callback(obj, property, value)
      },
      get: function() {
        return _value;
      }
    }
  });
}

$("#hid1").val(4);

https://jsfiddle.net/bvvmhvfk/


1
特に他の皆の答えが「自分で変更をトリガーする」ということなので、私はこのアプローチが好きです...これは常に実行可能なわけではありません。
sMyles

1
これはほとんど私にとってはうまくいきますが、非表示フィールドの最終値は実際には変更されていません。jsfiddleをチェックすると、非表示フィールドの値が「123」から変化しない(Chromeを使用)
MetaGuru

非常に近いですが、他の人が述べたように、フィールドの元のミューテーター/セッターへの参照を維持しないため、更新は非表示の入力自体に影響を与えません。このアプローチの一部とstackoverflow.com/a/38802602/4342230の
GuyPaddock

0

この例では、非表示のドラフトフィールドが値を変更するたびに、ドラフトフィールドの値を返します(Chromeブラウザー)。

var h = document.querySelectorAll('input[type="hidden"][name="draft"]')[0];
//or jquery.....
//var h = $('input[type="hidden"][name="draft"]')[0];

observeDOM(h, 'n', function(draftValue){ 
  console.log('dom changed draftValue:'+draftValue);
});


var observeDOM = (function(){
var MutationObserver = window.MutationObserver || 
window.WebKitMutationObserver;

  return function(obj, thistime, callback){
    if(typeof obj === 'undefined'){
      console.log('obj is undefined');
      return;
    }

    if( MutationObserver ){

        // define a new observer
        var obs = new MutationObserver(function(mutations, observer){

            if( mutations[0].addedNodes.length || mutations[0].removedNodes.length ){

               callback('pass other observations back...');

            }else if(mutations[0].attributeName == "value" ){

               // use callback to pass back value of hidden form field                            
               callback( obj.value );

            }

        });

        // have the observer observe obj for changes in children
        // note 'attributes:true' else we can't read the input attribute value
        obs.observe( obj, { childList:true, subtree:true, attributes:true  });

       }
  };
})();

0

オフ構築Viktarの答えは、ここであなたが入力要素の値が変更されるたびに、その後の変更イベントGETは解雇することを確実にするために与えられた隠されたinput要素の後に呼び出すことができます実装です:

/**
 * Modifies the provided hidden input so value changes to trigger events.
 *
 * After this method is called, any changes to the 'value' property of the
 * specified input will trigger a 'change' event, just like would happen
 * if the input was a text field.
 *
 * As explained in the following SO post, hidden inputs don't normally
 * trigger on-change events because the 'blur' event is responsible for
 * triggering a change event, and hidden inputs aren't focusable by virtue
 * of being hidden elements:
 * https://stackoverflow.com/a/17695525/4342230
 *
 * @param {HTMLInputElement} inputElement
 *   The DOM element for the hidden input element.
 */
function setupHiddenInputChangeListener(inputElement) {
  const propertyName = 'value';

  const {get: originalGetter, set: originalSetter} =
    findPropertyDescriptor(inputElement, propertyName);

  // We wrap this in a function factory to bind the getter and setter values
  // so later callbacks refer to the correct object, in case we use this
  // method on more than one hidden input element.
  const newPropertyDescriptor = ((_originalGetter, _originalSetter) => {
    return {
      set: function(value) {
        const currentValue = originalGetter.call(inputElement);

        // Delegate the call to the original property setter
        _originalSetter.call(inputElement, value);

        // Only fire change if the value actually changed.
        if (currentValue !== value) {
          inputElement.dispatchEvent(new Event('change'));
        }
      },

      get: function() {
        // Delegate the call to the original property getter
        return _originalGetter.call(inputElement);
      }
    }
  })(originalGetter, originalSetter);

  Object.defineProperty(inputElement, propertyName, newPropertyDescriptor);
};

/**
 * Search the inheritance tree of an object for a property descriptor.
 *
 * The property descriptor defined nearest in the inheritance hierarchy to
 * the class of the given object is returned first.
 *
 * Credit for this approach:
 * https://stackoverflow.com/a/38802602/4342230
 *
 * @param {Object} object
 * @param {String} propertyName
 *   The name of the property for which a descriptor is desired.
 *
 * @returns {PropertyDescriptor, null}
 */
function findPropertyDescriptor(object, propertyName) {
  if (object === null) {
    return null;
  }

  if (object.hasOwnProperty(propertyName)) {
    return Object.getOwnPropertyDescriptor(object, propertyName);
  }
  else {
    const parentClass = Object.getPrototypeOf(object);

    return findPropertyDescriptor(parentClass, propertyName);
  }
}

このように準備ができたドキュメントでこれを呼び出します:

$(document).ready(function() {
  setupHiddenInputChangeListener($('myinput')[0]);
});

-4

このスレッドは3年前のものですが、これが私の解決策です:

$(function ()
{
    keep_fields_uptodate();
});

function keep_fields_uptodate()
{
    // Keep all fields up to date!
    var $inputDate = $("input[type='date']");
    $inputDate.blur(function(event)
    {
        $("input").trigger("change");
    });
}

3
blurイベントは、入力がフォーカスを失ったときにのみトリガーされます。非表示の入力に対する有効な応答ではありません
manuerumx '11 / 11/15
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.