我有一个名为#myHiddenField
的隐藏字段。
此字段的内容在各个地方以编程方式更改。
我想要一种检测变化的方法。除非我输入字段,否则更改事件不会触发,但这是不可能的。
是否有一种jQuery方法可以检测字段中的程序化内容变化?
答案 0 :(得分:26)
您应该能够通过以下方式触发更改事件:
$('#myHiddenField').change();
OR
$('#myHiddenField').trigger('change');
当然,这需要负责更新字段的代码块,以便在完成其工作后进行其中一个调用。
答案 1 :(得分:6)
DOM无法检测到事件的程序化提升。我昨天碰到了这个。我不记得我在哪里阅读它,但解决方法是在jQuery元素上实际调用.trigger()
。 jQuery Doc
答案 2 :(得分:1)
案例1: 您希望自己以编程方式更改值,并且只想在值更改时调度事件。
$('#myfield').text('New value');
//$('#myfield').val('New value');
$('#myfield').trigger('change');
案例2:
假设您要检测对您未编写的字段的编程更改。因此,您无法触发“更改”事件。
在这种情况下,使用'DOMSubtreeModified'来检测对父元素的后代元素的编程更改。
示例:
<div id="product-addons-total">
<div id="total_price">200</div>
</div>
$(document).ready(function() {
jQuery('#product-addons-total').on("DOMSubtreeModified",function(){
console.log('content changed');
//tamp_price_change_handler();
});
});
现在,如果“total_price”的值以某种方式以编程方式更改,则会触发“DOMSubtreeModified”事件。 例如:
jQuery('#total_price').text('300');
案例2的注意事项: DOMSubtreeModified 可以创建无限循环并极大地降低性能。相反,鼓励使用 MutationObserver 。
MutationObserver示例:
// create an observer instance
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
// Let's configure the observer
var config = { childList: true, subtree:true, attributes: true, characterData: true,
characterDataOldValue: true, attributeOldValue: true };
//Let's get a node.
var target = jQuery('#product-addons-total').get(0);
// Let's pass the target and configuration to the observe function.
observer.observe(target, config);
案例3:
以上方法可以检测DOM的变化。但是,如果要以编程方式更改输入字段的值,则不会触发这些事件。在这种情况下,唯一的方法是手动触发事件。 因此,首先更改输入字段的值,然后手动触发事件。
$('#inputfield').val(456465).trigger('change');
//Now the change event will fire.
$('#inputfield').on('change', function() {
console.log('input filed has been changed');
});
答案 3 :(得分:0)
在jQuery中使用.val()设置值不会触发更改事件,因此您必须使用.change()或.trigger(&#39;更改&#39;)来触发改变事件。您可以选择使用.change(function(){...})或.on(&#39;更改&#39;,function(){...}来检测字段的更改事件。
$('#myHiddenField').change(function() {
alert('content changed to: ' + $('#myHiddenField').val());
});
$('#btnChange').click(function() {
$('#myHiddenField').val("new content");
$('#myHiddenField').change();
});
https://jsfiddle.net/qeg5of2a/1/
或
$('#myHiddenField').on('change', function() {
alert('content changed to: ' + $('#myHiddenField').val());
});
$('#btnChange').click(function() {
$('#myHiddenField').val("new content");
$('#myHiddenField').trigger('change');
});
https://jsfiddle.net/qeg5of2a/2/
.change只是.on(&#39;更改&#39;,处理程序)和.trigger(&#39;更改&#39;)的快捷方式,所以要么很好
答案 4 :(得分:0)
您可以对JQ对象的方法(例如val
或html
进行重写以实现此目的(或者可能覆盖“纯JS”对象的方法)。我个人无法让MutationObserver
工作,我提出的这个解决方案可能更简单:
const jqInvoiceNo = $('#InvoiceNo');
const jqProto = Object.getPrototypeOf( jqInvoiceNo );
const valOverride = function( newVal ){
console.log( '£ override val, invoice no: ' + newVal );
// essential function 'call'... note usage
// we assume that if newVal is undefined this means we are using the
// parameterless JQ method signature version, which returns the value
if( newVal === undefined ){
return jqProto.val.call( this );
}
jqProto.val.call( this, newVal );
// ... then do something else, having intercepted the value-setting mechanism
};
jqInvoiceNo.val = valOverride;
... // later, in your code:
jqInvoiceNo.val( '99' );
重要说明:此代码只写覆盖/覆盖此一个JQ对象的val方法。必须要注意的是,如果你去其他地方$( '#InvoiceNo' )
,你实际上将创建一个全新的JQ对象,而没有被覆盖的val
方法。换句话说,在这种情况下,您可以跟踪JQ对象。
你也可以用同样的方式覆盖任何“纯JS”对象的方法,特别是(对于这种情况)setAttribute
。
对于那些还不知道的人来说,JQ对象的第一个元素,即[0]
,是它所包含的“真正的”JS对象。
const invoiceNo = $('#InvoiceNo')[ 0 ];
const proto = Object.getPrototypeOf( invoiceNo );
const setAttributeOverride = function( attr, newVal ){
console.log( '£ override setAttribute, invoice no: ' + newVal );
// essential function 'call'... note usage:
proto.setAttribute.call( this, attr, newVal );
if( attr === 'value' ){
// ... then do something else, having intercepted the value-setting mechanism
}
};
// note that only this object 'invoiceNo' will be given the overridden method:
invoiceNo.setAttribute = setAttributeOverride;
.... // later, in your code:
$( '#InvoiceNo' )[ 0 ].setAttribute( 'value', '99' );
与上面给出的JQ示例不同,只有一个这样的“纯JS”对象......所以在代码中的任何地方运行$( '#InvoiceNo' )[ 0 ]
总会给你相同的JS对象。当然,在“纯JS”中设置属性(或者更确切地说是“属性”)的常规方法是
object.value = newValue;
...据我所知,哪个命令不能被“覆盖”。据推测,如果你比我更成功,可以用MutationObserver
检测到这一点。
PS究竟如何在调用val
或html
之类的JQ方法时设置其“真正的JS”对象的值,我不知道。如果你想要可以实际上覆盖这些方法来“自己动手”,利用“等效”JQ对象引用相同底层JS对象的事实,即自$( '#InvoiceNo' )[ 0 ]
以来总是指同一个JS对象。但在这种情况下,您必须覆盖{strong>所有 JQ对象的val
或html
,即修改原型本身:
const jqInvoiceNo = $('#InvoiceNo');
const jqProto = Object.getPrototypeOf( jqInvoiceNo );
jqProto.superValMethod = jqProto.val;
const valOverride = function( newVal ){
if( newVal === undefined ){
return jqProto.superValMethod.call( this );
}
jqProto.superValMethod.call( this, newVal );
const ourPureJSObject = this[ 0 ];
// do something with this ... it will always the right one!
};
jqProto.val = valOverride;