jQuery检测到对字段的编程更改

我有一个名为#myHiddenField的隐藏字段说。

该字段的内容在各个地方以编程方式改变。

我想要一种检测变化的方法。 除非我输入字段,否则更改事件不会触发,但这是不可能的。

是否有jQuery方法来检测字段中的程序化内容更改?

您应该能够通过以下方式触发更改事件:

 $('#myHiddenField').change(); 

要么

 $('#myHiddenField').trigger('change'); 

当然,这将需要负责更新字段的代码块,以便在完成其工作后进行其中一个调用。

DOM无法检测到事件的程序化提升。 我昨天碰到了这个。 我不记得我在哪里阅读它,但解决方法是在jQuery元素上实际调用.trigger() 。 jQuery Doc

在jQuery中使用.val()设置值不会触发更改事件,因此您必须使用.change()或.trigger(’change’)来触发更改事件。 您可以选择使用.change(function(){…})或.on(’change’,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(’change’,handler)和.trigger(’change’)的快捷方式,所以要么很好

您可以使用重写版本的JQ对象的方法(如valhtml来实现此目的(或者可能覆盖“纯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究竟如何调用JQ方法(如valhtml )时JQ设置其“真正的JS”对象的值我不知道。 如果你想要你实际上可以覆盖这些方法来“自己动手”,利用“等效”JQ对象引用相同底层JS对象的事实,即因为$( '#InvoiceNo' )[ 0 ]总是引用到同一个JS对象。 但在这种情况下,你必须覆盖所有 JQ对象的valhtml ,即修改原型本身:

 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; 

情况1:您希望自己以编程方式更改值,并且只想在值更改时调度事件。

 $('#myfield').text('New value'); //$('#myfield').val('New value'); $('#myfield').trigger('change'); 

案例2:

假设您希望检测到不是由您编写的字段的编程更改。 因此,您无法触发“更改”事件。

在这种情况下,使用’DOMSubtreeModified’来检测父元素的后代元素的编程更改。

例:

 
200
$(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'); });