在自动更正时,跟踪文本字段中光标位置的更好方法是什么



我正在开发一个jQuery插件,用于实时(自动更正)将拉丁字符转换为日语假名符号(实时示例),如果我打字不太快,它可以正常工作。。这是个问题。

例如:

wakarimasu->わかります

然而,当我以正常速度打字时,我会得到这个:

wakarimasu->わかりあすm(实际上是wakariasum,光标位于"す"和最后的"m")

如果我键入它而不带"su",我会得到这个:

wakarima->わかりあm(实际上是wakariam,光标位于"あ"和最后的"m")

我弄清楚了发生这种情况的原因和方式。基本上,"り当我已经键入"m"时,符号仍在从拉丁假名转换为日语假名,在我设法键入"a"之前,它只完成了一点点。由于我的函数在每次转换后都会定位光标,它会将光标定位在"ri"one_answers"m"之间,这就是我的"a"的终点。

其他单词也会出现这种情况,但我以这个单词为例。

我有没有办法以更智能的方式跟踪光标位置,或者有没有办法只更新/转换/替换文本字段的一部分,而不更新整个文本字段(现在的工作方式是获取文本字段中的内容,在函数中的变量中用假名替换拉丁语,用变量中的新字符串更新文本字段,然后定位光标)?告诉访客不要打字太快不是真正的方法。。

图例:wa=わka=かri=りma=まsu=すa=あ

可以在我提供的链接中查看源代码。谢谢

编辑:需要考虑的另一件事是,用户可能会左右移动光标来添加或删除字符/符号。这会使定位稍微复杂一些,但目前它是有效的

function translateWord( textarea, oldText, newText ) {
var ctpos   = getCaretPosition( textarea );
var textStr = textarea.value;
var oldTextLen  = oldText.split("").length;
var newTextLen  = newText.split("").length;
var txtDiffLen  = ( newTextLen - oldTextLen );
var escText = oldText.replace( /([()[]\/+*?.-])/g, "\$1" );
var regExpr = new RegExp( "\b"+escText+"\b", 'gi' );
var diffStr = textStr.match( regExpr );
diffStr = ( diffStr ) ? diffStr.length : 1;
var newStr  = textStr.replace( regExpr, newText );
ctpos   = ( ctpos + ( txtDiffLen * diffStr ) );
textarea.value = newStr;
setCaretPosition( textarea, ctpos );
}
function getCaretPosition( textarea ) {
if ( textarea.selectionStart ) {
return textarea.selectionStart;
}
else if ( !document.selection ) {
return 0;
}
var c   = "01",
sel = document.selection.createRange(),
dul = sel.duplicate(),
len = 0;
dul.moveToElementText( textarea );
sel.text  = c;
len = dul.text.indexOf( c );
sel.moveStart( 'character', -1 );
sel.text  = "";
return len;
}
function setCaretPosition( textarea, pos ) {
if ( textarea.setSelectionRange ) {
textarea.focus();
textarea.setSelectionRange( pos, pos );
}
else if ( textarea.createTextRange ) {
var range = textarea.createTextRange();
range.collapse( true );
range.moveEnd( 'character', pos );
range.moveStart( 'character', pos );
range.select();
}
}
translateWord( document.getElementById('text-input'), 'wakarimasu', 'わかります' );

我知道这是一个老问题,但这段代码会帮助一些像我这样的人:)来自其他答案的混合函数:)

为了结束这一次,我设法弄清楚问题实际上是第三个字符(在本例中为"m")进入了与"ri"相同的.keyup迭代,而不是像我之前认为的那样(症状相同,原因不同)。。

为了解决这个问题,我刚刚修改了.keyup代码,在偏移量上加+1,如果转换后字符串中还有拉丁字符(roumaji),则将光标向右移动一个位置。

最新更新