快速键入时,.keyup() 上的非拉丁字符替换不起作用
Non latin characters replace on .keyup() does not work when typing fast
我有 jQuery 代码将西里尔文用户输入替换为拉丁字符。当用户输入不是太快(每分钟 60-70 个字符)时,此方法工作正常,但当用户输入速度比这快时,它混合了西里尔字符和拉丁字符,可能是因为无法及时捕获 keyup
事件。我该如何解决这个问题?
$("input[name*=Name]").not("input[name*=Main]").keyup(function (e) {
if (e.keyCode === 8 || e.keyCode === 46 || e.keyCode === 9 || e.keyCode === 13 || e.keyCode === 17 || e.keyCode === 18 || e.keyCode === 37 || e.keyCode === 38 || e.keyCode === 39 || e.keyCode === 40 || e.keyCode === 16 || e.keyCode === 20) {
return false;
} else {
var englishchars = ["a", "b", "v", "g", "d", "e", "yo", "zh", "z", "i", "yi", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "kh", "c", "ch", "sh", "shch", "i", "e", "yu", "ya", ""];
var slavicchars = ["а", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ы", "э", "ю", "я", "ь"];
var verified = String.fromCharCode(e.wich).match(/[^а-яё]/);
if (verified) {
e.preventDefault();
var lastchar = this.value.length > 1 ? this.value.substr(-1) : this.value;
var russiancharindex = jQuery.inArray(lastchar, slavicchars);
if (russiancharindex > 0) {
var englishcharindex = englishchars[russiancharindex];
this.value = this.value.replace(lastchar, englishcharindex);
} else {
return false;
}
} else {
return false;
}
}
});
(...) probably because cannot catch keyup event in time (...)
这是因为 keyup
释放按键时捕获事件,而按下按键时将字符插入文本框。
因此,短时间按下两个键(键入快),两个字符都已经存在于文本框中,然后一个一个地释放键,你只检查输入的最后一个字符value
,但是第一个释放的键在最后一个字符之前被寻址到一个。
var lastchar = this.value.length > 1 ? this.value.substr(-1) : this.value;
var russiancharindex = jQuery.inArray(lastchar, slavicchars);
// ...
同样是这个原因,当你向后移动光标在文本中间插入一个字母时,它不会起作用。
这个怎么样?
在每个 keyup
上,它将匹配字符串中的每个 非 ascii 字符(而不是只匹配最后一个字符)。
注意.更新输入值将导致光标失去其当前位置并移动到输入的末尾。为防止这种情况(如果您在中间某处编辑该字段),请在更新之前存储其位置并在之后恢复。
(缩短了您的 if(e.keyCode ...)
条件并在 keyCodes 中添加了 space [32])
// keep these variables outside of the handler, so that they're not redeclared unnecessarily:
var charsObject = {
'a' : 'а',
'б' : 'b',
'в' : 'v',
// ...
}, keyCodes = [8,46,9,13,17,18,32,37,38,39,40,16,20];
$("input[name*=Name]:not([name*=Main])").keyup(function(e){
if (keyCodes.indexOf( e.keyCode ) < 0) {
// store current cursor position:
var start = this.selectionStart, end = this.selectionEnd;
$(this).val($(this).val().replace(/[^\u0000-\u007f]/g, function(char, key) {
// return replacement letter, or the original letter if it's not a "charsObject" key:
return charsObject[char] || char;
}));
// restore cursor position after field update:
this.setSelectionRange(start, end);
}
});
终于找到了更好的解决方案。
$("input[name*=Name]:not([name*=Main])").focusout(function (e) {
var englishchars = ["a", "b", "v", "g", "d", "e", "yo", "zh", "z", "i", "yi", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "kh", "c", "ch", "sh", "shch", "i", "e", "yu", "ya", "'"];
var slavicchars = ["а", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ы", "э", "ю", "я", "ь"];
var t = $(this).val().toLowerCase();
var word = new Array();
$.each(t.split(""), function (key, val) {
var verified = String.fromCharCode(e.wich).match(/[^а-яё]/);
if (verified) {
e.preventDefault();
var russiancharindex = jQuery.inArray(val, slavicchars);
if (russiancharindex >= 0) {
var englishcharindex = englishchars[russiancharindex];
word.push(englishcharindex);
} else {
word.push(val);
}
} else {
return false;
}
return word;
});
$(this).val(word.join("").replace(",", ""));
});
我有 jQuery 代码将西里尔文用户输入替换为拉丁字符。当用户输入不是太快(每分钟 60-70 个字符)时,此方法工作正常,但当用户输入速度比这快时,它混合了西里尔字符和拉丁字符,可能是因为无法及时捕获 keyup
事件。我该如何解决这个问题?
$("input[name*=Name]").not("input[name*=Main]").keyup(function (e) {
if (e.keyCode === 8 || e.keyCode === 46 || e.keyCode === 9 || e.keyCode === 13 || e.keyCode === 17 || e.keyCode === 18 || e.keyCode === 37 || e.keyCode === 38 || e.keyCode === 39 || e.keyCode === 40 || e.keyCode === 16 || e.keyCode === 20) {
return false;
} else {
var englishchars = ["a", "b", "v", "g", "d", "e", "yo", "zh", "z", "i", "yi", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "kh", "c", "ch", "sh", "shch", "i", "e", "yu", "ya", ""];
var slavicchars = ["а", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ы", "э", "ю", "я", "ь"];
var verified = String.fromCharCode(e.wich).match(/[^а-яё]/);
if (verified) {
e.preventDefault();
var lastchar = this.value.length > 1 ? this.value.substr(-1) : this.value;
var russiancharindex = jQuery.inArray(lastchar, slavicchars);
if (russiancharindex > 0) {
var englishcharindex = englishchars[russiancharindex];
this.value = this.value.replace(lastchar, englishcharindex);
} else {
return false;
}
} else {
return false;
}
}
});
(...) probably because cannot catch keyup event in time (...)
这是因为 keyup
释放按键时捕获事件,而按下按键时将字符插入文本框。
因此,短时间按下两个键(键入快),两个字符都已经存在于文本框中,然后一个一个地释放键,你只检查输入的最后一个字符value
,但是第一个释放的键在最后一个字符之前被寻址到一个。
var lastchar = this.value.length > 1 ? this.value.substr(-1) : this.value;
var russiancharindex = jQuery.inArray(lastchar, slavicchars);
// ...
同样是这个原因,当你向后移动光标在文本中间插入一个字母时,它不会起作用。
这个怎么样?
在每个 keyup
上,它将匹配字符串中的每个 非 ascii 字符(而不是只匹配最后一个字符)。
注意.更新输入值将导致光标失去其当前位置并移动到输入的末尾。为防止这种情况(如果您在中间某处编辑该字段),请在更新之前存储其位置并在之后恢复。
(缩短了您的 if(e.keyCode ...)
条件并在 keyCodes 中添加了 space [32])
// keep these variables outside of the handler, so that they're not redeclared unnecessarily:
var charsObject = {
'a' : 'а',
'б' : 'b',
'в' : 'v',
// ...
}, keyCodes = [8,46,9,13,17,18,32,37,38,39,40,16,20];
$("input[name*=Name]:not([name*=Main])").keyup(function(e){
if (keyCodes.indexOf( e.keyCode ) < 0) {
// store current cursor position:
var start = this.selectionStart, end = this.selectionEnd;
$(this).val($(this).val().replace(/[^\u0000-\u007f]/g, function(char, key) {
// return replacement letter, or the original letter if it's not a "charsObject" key:
return charsObject[char] || char;
}));
// restore cursor position after field update:
this.setSelectionRange(start, end);
}
});
终于找到了更好的解决方案。
$("input[name*=Name]:not([name*=Main])").focusout(function (e) {
var englishchars = ["a", "b", "v", "g", "d", "e", "yo", "zh", "z", "i", "yi", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "kh", "c", "ch", "sh", "shch", "i", "e", "yu", "ya", "'"];
var slavicchars = ["а", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ы", "э", "ю", "я", "ь"];
var t = $(this).val().toLowerCase();
var word = new Array();
$.each(t.split(""), function (key, val) {
var verified = String.fromCharCode(e.wich).match(/[^а-яё]/);
if (verified) {
e.preventDefault();
var russiancharindex = jQuery.inArray(val, slavicchars);
if (russiancharindex >= 0) {
var englishcharindex = englishchars[russiancharindex];
word.push(englishcharindex);
} else {
word.push(val);
}
} else {
return false;
}
return word;
});
$(this).val(word.join("").replace(",", ""));
});