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

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

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

当这个值发生变化时,我希望触发一个AJAX请求。有谁能告诉我如何发现这种变化吗?

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

$('#userid').change( function() {
alert('Change!');
})
319963 次浏览

所以这已经很晚了,但我已经找到了一个答案,以防它对任何遇到这条线索的人有用。

改变隐藏元素的值不会自动触发.change()事件。所以,无论你在哪里设置这个值,你都必须告诉jQuery去触发它。

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

一旦这样,

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

应该按预期工作。

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


$('#userid').val(10).change();

你可以简单地使用下面的函数,你也可以改变类型元素。

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

改变隐藏元素的值不会自动触发.change()事件。所以,无论你在哪里设置这个值,你都必须告诉jQuery去触发它。

超文本标记语言

 <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/ < a href = " http://jsfiddle.net/7CM6k/3/ " > < / >

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

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

可以使用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/

这个例子每次隐藏的draft字段改变它的值时返回draft字段值(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  });


}
};
})();

基于执行官威克塔•的回答,这里有一个实现,你可以在给定的隐藏输入元素上调用一次,以确保当输入元素的值发生变化时,后续的更改事件会被触发:

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

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

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