選択された領域の、始まりと終わりの文字位置、およびその文字列を返す関数

http://oshiete.goo.ne.jp/qa/6100202.html

投稿しようと思ったのに、アクセス集中とかで投稿できない。
選択範囲の始まりと終わりの位置と、文字列を返す。
もちろんIEは、面倒だ。

<!DOCTYPE html>
<title></title>
<body>

<textarea id="t1">
abc
def
</textarea>
<input type="button" value="Test" onclick="hoge('t1')">
<hr>

<input type="text" id="t2" value="abcdefghijklmn">
<input type="button" value="Test" onclick="hoge('t2')">
<hr>

<div contenteditable="true" id="t3">
ciureveuin<br>
furejvihev<br>
</div>
<input type="button" value="Test" onclick="hoge('t3')">
<hr>

<script>
// http://d.hatena.ne.jp/language_and_engineering/20090225/p1?sid=201781F
// http://d.hatena.ne.jp/brazil/20061021/1161377936

function hoge ( eId ) {
  var n = document.getElementById (eId);
  var r = getSelectionRange (n);
  alert ( 'Strart :' + r.start + '\n' +
          'End    :' + r.end   + '\n' +
          'Text   :' + r.text );
}

//@cc_on
function getSelectionRange ( element ) {
  var obj = { };

  /*@if (@_jscript)
    var doc = element.ownerDocument;
    var range_s, range_e;
    var selectedRange, textRange;

    element.focus ();
    selectedRange = doc.selection.createRange ();
    
    if ('INPUT' === element.nodeName) {
      range_s = element.createTextRange ();
      range_e = element.createTextRange ();
    }
    
    else {
      textRange = doc.body.createTextRange ();
      textRange.moveToElementText (element)
      range_s = textRange.duplicate ();
      range_e = textRange.duplicate ();
    }

    range_s.setEndPoint ('EndToStart', selectedRange);
    obj.start = range_s.text.length;

    range_e.setEndPoint ('EndToEnd', selectedRange);
    obj.end = range_e.text.length;

  @else@*/
    obj.start = element.selectionStart;
    obj.end   = element.selectionEnd;
  /*@end@*/

  obj.text = obj.start == obj.end
    ? null
    : element[
      /INPUT|TEXTAREA/.test (element.nodeName)
        ? 'value'
        : /*@if (@_jscript) 'innerText' @else@*/ 'textContent' /*@end@*/
      ].substring (obj.start, obj.end)

  return obj;
}
</script>