2011-08-04 2 views
1

私は驚くことではありませんが、IE8は、<input>または<textarea>というテキストからキャレットの位置を取得することに関して、ChromeとFirefoxとの動作が大きく異なることを発見しました。 ChromeとFirefoxは文字列値内のインデックスと同様にキャレットの位置を報告しますが、IE8ではそうではありません。テキスト入力のIEのキャレット位置が文字列インデックスと同じではないのはなぜですか?回避策は何ですか?

まず第一には、ここで私はクローム/ FirefoxとIEのそれぞれにキャレット位置を取得するために使用する関数です:

function getCaretPosGecko(txtbox) { 
    return txtbox.selectionStart; 
} 

function getCaretPosIE(txtbox) { 
    var range, rangeCopy;  
    txtbox.focus(); 
    range = document.selection.createRange();  
    if (range !== null) { 
     rangeCopy = range.duplicate(); 
     rangeCopy.moveToElementText(txtbox); 
     rangeCopy.setEndPoint('EndToStart', range);  
     return rangeCopy.text.length - range.text.length; 
    } else { 
     return -1; 
    } 
} 

私の知る限り、私が実装しました機能はかなり標準的です。さて、私は<textarea>を持っていて、最初の行には "a"を、2行目には "b"と入力します。上記のコードはChromeとFirefoxで与えられた基準に対して次のキャレット位置を報告します:IE8で

-------------------------------------------------------------------- 
| I put the caret...  | Code reports caret at position...  | 
-------------------------------------------------------------------- 
| 1st line, after the "a" | 1 (As expected)      | 
| 2nd line, before the "b" | 2 (As expected)      | 
| 2nd line, after the "b" | 3 (As expected)      | 
-------------------------------------------------------------------- 

、結果は残念ながら非常に異なっている:

-------------------------------------------------------------------- 
| I put the caret...  | Code reports caret at position...  | 
-------------------------------------------------------------------- 
| 1st line, after the "a" | 1 (As expected)      | 
| 2nd line, before the "b" | 1 (Maybe it doesn't count new lines?) | 
| 2nd line, after the "b" | 4 (Now, it seems to include \r\n?) | 
-------------------------------------------------------------------- 

私はIEを含めていることを仮定しています"\ r \ n"の3番目のケースの計算では、なぜそれは2番目のケースのためにそれを含まない?

さらに重要なことは、この不一致を回避するにはどうすればよいですか?文字列の操作を行うために、テキストボックスの文字列値内にキャレットがどこにあるのかを知る必要があります。私の最初の考えは、IEのキャレット位置をキャレットの前に "\ r \ n"の数だけオフセットすることでしたが、キャレットが行の先頭または最後にある場合は機能しません。 http://jsfiddle.net/FishBasketGordo/ExZM9/

EDIT:以下 @Timダウンの答えはちょうど約上の発見された。ここ

は実施例です。私はいくつかの変更を加える必要がありました。関数は、以下のヤモリアナログとまったく同じ結果を返す:ここ

function getCaretPosIE(txtbox) { 
    var caret, normalizedValue, range, textInputRange, len, endRange;  
    txtbox.focus(); 
    range = document.selection.createRange();  
    if (range && range.parentElement() == txtbox) { 
     len = txtbox.value.length; 
     normalizedValue = txtbox.value.replace(/\r\n/g, ''); 
     textInputRange = txtbox.createTextRange(); 
     textInputRange.moveToBookmark(range.getBookmark()); 
     endRange = txtbox.createTextRange(); 
     endRange.collapse(false); 
     if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) { 
      caret = txtbox.value.replace(/\r\n/g, '\n').length; 
     } else { 
      caret = -textInputRange.moveStart("character", -len); 
      caret += normalizedValue.slice(0, start).split("\n").length - 1; 
     } 
    } 
} 

を補正し、実施例である:相対キャレット位置TEXTAREAのvalueプロパティを取得http://jsfiddle.net/FishBasketGordo/uXWXF/

+0

可能重複[?テキストエリア内のカーソル位置を取得する方法](http://stackoverflow.com/questions/263743/how-to-get-cursor-position-in- textarea) –

+0

この質問に対する回答は、このサイトの他の場所でも複写されていますが、問題はありません。私は単にIEでキャレットの位置を取得しようとしているわけではありません。 IEでキャレットの位置を取得するための標準的な方法と思われるものを使用する場合、キャレットの位置が文字列のインデックスと一致しないという事実を回避しようとしています。事実上の解決策でやったのと同じ問題に誰かが遭遇した場合、この質問は彼らを助けるでしょう。 – FishBasketGordo

+0

あなたが事実上のソリューションを投稿したコードは何ですか? –

答えて