粘贴文本时,TextChanged的回发不会触发
我在处理这个JavaScript的一个问题:当我粘贴一个数字时,TextChanged的回发不会被触发,而手动输入数值时却能正确触发。
这是一个通用控件,问题可能与回发有关。
js
function verificaIncolla(event, sender) {
try {
var clipboardData = (event.clipboardData || window.clipboardData);
var pasted = clipboardData ? clipboardData.getData('text') : null;
if (!pasted) {
return;
}
var containsLetter = /[A-Za-z\u00C0-\u024F]/.test(pasted);
if (containsLetter) {
return;
}
var cleaned = pasted.replace(/\s+/g, '');
cleaned = cleaned.replace(/[^0-9\.,\-]/g, '');
cleaned = cleaned.replace(/-/g, function (m, offset) {
return (offset === 0) ? '-' : '';
});
if (cleaned.indexOf('-') > 0) {
cleaned = cleaned.replace(/-/g, '');
}
var separators = cleaned.match(/[.,]/g);
if (separators && separators.length > 1) {
var lastSep = cleaned.lastIndexOf('.') > cleaned.lastIndexOf(',') ? '.' : ',';
cleaned = cleaned.replace(/[.,]/g, '');
if (cleaned.length > 2) {
var before = cleaned.substring(0, cleaned.length - 2);
var after = cleaned.substring(cleaned.length - 2);
cleaned = before + lastSep + after;
} else {
cleaned = cleaned + lastSep;
}
}
var start = sender.selectionStart;
var end = sender.selectionEnd;
var value = sender.value || "";
var newValue = value.substring(0, start) + cleaned + value.substring(end);
sender.value = newValue;
var newCaret = start + cleaned.length;
if (typeof sender.setSelectionRange === 'function') {
sender.setSelectionRange(newCaret, newCaret);
}
replaceAllDot(sender);
VerificaTestoImporto(sender);
if (typeof formattaNumero === 'function') {
try { formattaNumero(sender,2); } catch (e) { }
}
} catch (e) {
console.error('verificaIncolla error:', e);
}
}
<asp:TextBox CssClass="form-control" OnTextChanged="txtDecimale_TextChanged" runat="server" ID="txtDecimale" onkeyup="VerificaTestoImporto(this)" onfocus="replaceAllDot(this);" onpaste="verificaIncolla(event,this)" ></asp:TextBox>
如果我从文本框移除 onpaste 事件,TextChanged的回发就会被正确触发。
解决方案
问题在于 verificaIncolla 函数直接通过JavaScript设置了 sender.value,这不会触发浏览器原生的 change 事件,因此ASP.NET的 AutoPostBack依赖该事件的触发。
修复方法是在设置值后派发一个 input 和一个 change 事件。
以下是在你的函数中的修复。
function verificaIncolla(event, sender) {
try {
var clipboardData = (event.clipboardData || window.clipboardData);
var pasted = clipboardData ? clipboardData.getData('text') : null;
if (!pasted) {
return;
}
var containsLetter = /[A-Za-z\u00C0-\u024F]/.test(pasted);
if (containsLetter) {
return;
}
var cleaned = pasted.replace(/\s+/g, '');
cleaned = cleaned.replace(/[^0-9\.,\-]/g, '');
cleaned = cleaned.replace(/-/g, function (m, offset) {
return (offset === 0) ? '-' : '';
});
if (cleaned.indexOf('-') > 0) {
cleaned = cleaned.replace(/-/g, '');
}
var separators = cleaned.match(/[.,]/g);
if (separators && separators.length > 1) {
var lastSep = cleaned.lastIndexOf('.') > cleaned.lastIndexOf(',') ? '.' : ',';
cleaned = cleaned.replace(/[.,]/g, '');
if (cleaned.length > 2) {
var before = cleaned.substring(0, cleaned.length - 2);
var after = cleaned.substring(cleaned.length - 2);
cleaned = before + lastSep + after;
} else {
cleaned = cleaned + lastSep;
}
}
var start = sender.selectionStart;
var end = sender.selectionEnd;
var value = sender.value || "";
var newValue = value.substring(0, start) + cleaned + value.substring(end);
sender.value = newValue;
var newCaret = start + cleaned.length;
if (typeof sender.setSelectionRange === 'function') {
sender.setSelectionRange(newCaret, newCaret);
}
replaceAllDot(sender);
VerificaTestoImporto(sender);
if (typeof formattaNumero === 'function') {
try { formattaNumero(sender, 2); } catch (e) { }
}
// Fire input + change events so ASP.NET AutoPostBack is triggered
sender.dispatchEvent(new Event('input', { bubbles: true }));
sender.dispatchEvent(new Event('change', { bubbles: true }));
} catch (e) {
console.error('verificaIncolla error:', e);
}
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。