入力値が実際に変更された場合にのみ入力値を更新するだけで、ほとんどの問題を防ぐことができます。
$( '#sample' ).on( 'keyup', function( event ) {
var str = $( this ).val();
str = str.replace(/[^A-Za-z-0-9.'\s]/g, "").substring(0,15);
if($( this ).val() != str) {
$( this ).val( str );
}
});
テキストの途中から文字を削除することを解決するには、キャレットの位置を覚えてリセットする必要があります。そのために、次の関数を使用できます。
$.fn.getCaretPosition = function() {
var el = $(this).get(0);
var pos = 0;
if ('selectionStart' in el) {
pos = el.selectionStart - 1;
} else if ('selection' in document) {
el.focus();
var Sel = document.selection.createRange();
var SelLength = document.selection.createRange().text.length;
Sel.moveStart('character', -el.value.length);
pos = Sel.text.length - SelLength;
}
return pos;
}
$.fn.setCaretPosition = function(pos) {
if ($(this).get(0).setSelectionRange) {
$(this).get(0).setSelectionRange(pos, pos);
} else if ($(this).get(0).createTextRange) {
var range = $(this).get(0).createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
}
そして、keyup ハンドラーを拡張します。
$('#sample').on('keyup', function(event) {
var str = $(this).val();
str = str.replace(/[^A-Za-z-0-9.'\s]/g, "").substring(0, 15);
if ($(this).val() != str) {
var pos = $(this).getCaretPosition();
$(this).val(str);
$(this).setCaretPosition(pos);
}
});
更新されたFIDDLEを参照してください。