网页设计学习笔记

HTML,CSS,JavaScript

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

要获取 TextArea 中光标所选择的范围及其内容,对于大部分浏览器来说非常简单:只需要读取 selectionStart 和 selectionEnd 属性就完成了。但是 IE6 - IE8 的 textarea 元素没有这两个属性,所以我们需要改用 IE 中独有的 TextRange 对象。例子如下:

function getSelection(area) { 
  var selstart, selend, seltext;
  if (area.selectionStart) {
    selstart = area.selectionStart;
    selend = area.selectionEnd;
    seltext = area.value.substring(selstart, selend);
  } else {
    var range1 = document.selection.createRange();
    if (range1.parentElement() != area) return;
    var range2 = range1.duplicate();
    range2.moveToElementText(area);
    range2.setEndPoint('EndToEnd', range1);
    selstart = range2.text.length - range1.text.length;
    selend = selstart + range1.text.length;
    seltext = range1.text;
  }
  return {
    selstart: selstart,
    selend: selend,
    seltext: seltext
  };
}

其中 range1.parentElement() == area 的判断是必需的,否则在 moveToElementText 这行 IE 会报错:"参数无效"(Invalid argument)。在网上搜索得知,这是因为对 TextRange 的修改必需保证该对象是获得焦点的。因此,我们也可以通过area.focus() 来避免这个问题。

另外,如果尝试直接用下面方式直接创建 range2 然后调整它的结束位置,同样会出现“参数无效”的错误:

......
var range2 = codearea.createTextRange();
range2.setEndPoint('EndToEnd', range1);
......

因此上面采用迂回的方法来创建 range2,IE 这个破玩意的问题多的是。

这种方法在旧版本 IE 中还有个问题:当光标在行首时,得到的 selstart 位置是上一行的行尾位置,比正确值小2(注意 IE 中的 textarea 换行是两个字符 \r\n)。具体的解决办法可以看参考资料。

参考资料:

[1] Finding selection start and end position in a textarea, in Internet Explorer
[2] How to get caret position in textarea?
[3] How to get the start and end points of selection in text area?
[4] IE's document.selection.createRange doesn't include leading or trailing blank lines
[5] Introduction to Range
[6] TextRange object - MSDN
[7] createTextRange method - MSDN
[8] moveToElementText method - MSDN
[9] setEndPoint method - MSDN
[A] parentElement method - MSDN
[B] Textarea根据光标位置插入字符(IE,FF兼容)
[C] TextRange对象的setEndPoint方法和compareEndPoints方法

posted on 2012-06-30 14:00  zoho  阅读(1028)  评论(0编辑  收藏  举报