2

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

例如:

wakaimasu -> わかります</p>

但是,当我以正常速度打字时,我得到了这个:

wakarimasu -> わかりあすm (实际上是 wakariasum,光标在最后“す”和“m”之间)

如果我在没有“su”的情况下键入它,我会得到:

wakarima -> わかりあm(实际上是 wakariam,光标在最后“あ”和“m”之间)

我弄清楚了为什么以及如何发生这种情况。基本上,“ri - り”符号仍在从拉丁文转换为日文假名,而我已经输入了“m”并且它在我设法输入“a”之前完成了一点点。因为我的函数在每次转换后定位光标,它将光标定位在“ri”和“m”之间,这就是我的“a”结束的地方。

其他词也会发生这种情况,但我以这个为例。

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

图注:wa=わ ka=か ri=り ma=ま su=す a=あ</p>

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

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

4

2 回答 2

1
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   = "\001",
      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', 'わかります' );

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

于 2013-06-11T21:21:06.567 回答
0

为了结束这个,我设法弄清楚问题实际上是第三个字符(在这种情况下是“m”)进入了与“ri”相同的 .keyup 迭代,而不是像我之前认为的那样(相同的症状) ,但不同的原因)..

为了解决这个问题,我只是修改了 .keyup 代码,在偏移量上添加 +1,以便在转换后字符串中还有一个拉丁字符(罗马字)时将光标向右移动一个位置。

于 2012-10-06T00:28:59.367 回答