jQuery - 检测隐藏输入字段的值变化

发布于 2024-11-18 08:55:25 字数 284 浏览 1 评论 0原文

我有一个隐藏文本字段,其值通过 AJAX 响应进行更新。

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

当这个值改变时,我想触发一个 AJAX 请求。谁能建议如何检测变化?

我有以下代码,但不知道如何查找该值:

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

I have a hidden text field whose value gets updated via an AJAX response.

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

When this value changes, I would like to fire an AJAX request. Can anyone advise on how to detect the change?

I have the following code, but do not know how to look for the value:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

单挑你×的.吻 2024-11-25 08:55:25

所以这已经太晚了,但我已经找到了答案,以防它对遇到此线程的任何人有用。

隐藏元素值的更改不会自动触发 .change() 事件。因此,无论您在何处设置该值,您还必须告诉 jQuery 触发它。

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

一旦出现这种情况,

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

应该会按预期工作。

So this is way late, but I've discovered an answer, in case it becomes useful to anyone who comes across this thread.

Changes in value to hidden elements don't automatically fire the .change() event. So, wherever it is that you're setting that value, you also have to tell jQuery to trigger it.

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

Once that's the case,

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

should work as expected.

夏の忆 2024-11-25 08:55:25

由于隐藏输入不会在更改时触发“更改”事件,因此我使用 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] );

Since hidden input does not trigger "change" event on change, I used MutationObserver to trigger this instead.

(Sometimes hidden input value changes are done by some other scripts you can't modify)

This does not work in IE10 and below

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] );
伴我老 2024-11-25 08:55:25

您可以简单地使用下面的函数,您还可以更改类型元素。

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

隐藏元素值的更改不会自动触发 .change() 事件。因此,无论您在何处设置该值,您还必须告诉 jQuery 触发它。

HTML

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

JAVASCRIPT

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/

You can simply use the below function, You can also change the type element.

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

Changes in value to hidden elements don't automatically fire the .change() event. So, wherever it is that you're setting that value, you also have to tell jQuery to trigger it.

HTML

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

JAVASCRIPT

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

should work as expected.

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

神回复 2024-11-25 08:55:25
$('#userid').change(function(){
  //fire your ajax call  
});

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

$('#userid').val(10).change();
青衫负雪 2024-11-25 08:55:25

基于 Viktar 的答案,这里有一个实现,您可以在给定的隐藏输入元素上调用一次,以确保后续更改事件得到每当输入元素的值发生变化时触发:

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

Building off of Viktar's answer, here's an implementation you can call once on a given hidden input element to ensure that subsequent change events get fired whenever the value of the input element changes:

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

Call this on document ready like so:

$(document).ready(function() {
  setupHiddenInputChangeListener($('myinput')[0]);
});
放低过去 2024-11-25 08:55:25

可以使用Object.defineProperty()来重新定义输入元素的“value”属性并在其更改期间执行任何操作。

Object.defineProperty() 允许我们为属性定义 getter 和 setter,从而控制它。

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/

It is possible to use Object.defineProperty() in order to redefine the 'value' property of the input element and do anything during its changing.

Object.defineProperty() allows us to define a getter and setter for a property, thus controlling it.

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/

月亮邮递员 2024-11-25 08:55:25

我从 Vikars 答案开始,但也注意到,当在 HTML 表单中使用隐藏表单字段时,最后的更改并没有'没有被提交。后来我找到了 Thomas 答案,所以我将两者结合到以下解决方案中,这似乎也适用于我的隐藏表单字段提交:

   function replaceWithWrapper(selector, property, callback) {
      function findDescriptor(obj, prop){
         if (obj != null){
            return Object.hasOwnProperty.call(obj, prop)?
               Object.getOwnPropertyDescriptor(obj, prop):
               findDescriptor(Object.getPrototypeOf(obj), prop);
         }
      }

      jQuery(selector).each(function(idx, obj) {
         var {get, set} = findDescriptor(obj, property);

         Object.defineProperty(obj, property, {
            configurable: true,
            enumerable: true,

            get() { //overwrite getter
               var v = get.call(this);  //call the original getter
               //console.log("get '+property+':", v, this);
               return v;
            },
            
            set(v) { //same for setter
               //console.log("set '+property+':", v, this);
               set.call(this, v);
               callback(obj, property, v)
            }
         });
      });
   }

   replaceWithWrapper('#myhiddenfield', 'value', function() {
      console.log('myhiddenfield value changed!');
   });

I started with Vikars answer, but noticed too that when the hidden form fields used in a HTML form that the last changes didn't get submited. Later on I found Thomas answer, so I combined both to the following solution, which seems to work nicely for my hidden form fields also on submit:

   function replaceWithWrapper(selector, property, callback) {
      function findDescriptor(obj, prop){
         if (obj != null){
            return Object.hasOwnProperty.call(obj, prop)?
               Object.getOwnPropertyDescriptor(obj, prop):
               findDescriptor(Object.getPrototypeOf(obj), prop);
         }
      }

      jQuery(selector).each(function(idx, obj) {
         var {get, set} = findDescriptor(obj, property);

         Object.defineProperty(obj, property, {
            configurable: true,
            enumerable: true,

            get() { //overwrite getter
               var v = get.call(this);  //call the original getter
               //console.log("get '+property+':", v, this);
               return v;
            },
            
            set(v) { //same for setter
               //console.log("set '+property+':", v, this);
               set.call(this, v);
               callback(obj, property, v)
            }
         });
      });
   }

   replaceWithWrapper('#myhiddenfield', 'value', function() {
      console.log('myhiddenfield value changed!');
   });
零時差 2024-11-25 08:55:25

此示例在每次隐藏草稿字段更改其值时返回草稿字段值(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  });

       }
  };
})();

This example returns the draft field value every time the hidden draft field changes its value (chrome browser):

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

       }
  };
})();
白衬杉格子梦 2024-11-25 08:55:25

虽然这个帖子已经有 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");
    });
}

Although this thread is 3 years old, here is my solution:

$(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");
    });
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文