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对象的方法(如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究竟如何调用JQ方法(如val
或html
)时JQ设置其“真正的JS”对象的值我不知道。 如果你想要你实际上可以覆盖这些方法来“自己动手”,利用“等效”JQ对象引用相同底层JS对象的事实,即因为$( '#InvoiceNo' )[ 0 ]
总是引用到同一个JS对象。 但在这种情况下,你必须覆盖所有 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;
情况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'); });