Javascript 是否有Internet Explorer认可的selectionStart和selectionEnd替代品?

Javascript 是否有Internet Explorer认可的selectionStart和selectionEnd替代品?,javascript,internet-explorer,Javascript,Internet Explorer,查找在真实浏览器中选择的内容非常简单: var range = { start: textbox.selectionStart, end: textbox.selectionEnd } 但IE像往常一样不明白。最好的跨浏览器方式是什么?我当前的解决方案冗长且基于,但我愿意接受更好的解决方案 function getSelection(inputBox) { if ("selectionStart" in inputBox) { return {

查找在真实浏览器中选择的内容非常简单:

var range = {
  start: textbox.selectionStart,
  end: textbox.selectionEnd
}

但IE像往常一样不明白。最好的跨浏览器方式是什么?

我当前的解决方案冗长且基于,但我愿意接受更好的解决方案

function getSelection(inputBox) {
    if ("selectionStart" in inputBox) {
        return {
            start: inputBox.selectionStart,
            end: inputBox.selectionEnd
        }
    }

    //and now, the blinkered IE way
    var bookmark = document.selection.createRange().getBookmark()
    var selection = inputBox.createTextRange()
    selection.moveToBookmark(bookmark)

    var before = inputBox.createTextRange()
    before.collapse(true)
    before.setEndPoint("EndToStart", selection)

    var beforeLength = before.text.length
    var selLength = selection.text.length

    return {
        start: beforeLength,
        end: beforeLength + selLength
    }
}

IE的射程实现是一件令人毛骨悚然的事情。它确实希望您使用可执行的命令界面,而不是任何涉及到文本索引的内容

我知道有两种获取指数的方法,它们都有问题。第一个使用range.text,如示例代码中所示。不幸的是,range.text有一个去掉前导和尾随新行的习惯,这意味着如果插入符号/选择位于第一行以外的行的开头,beforeLength将被(新行数*2)个字符去掉,您将得到错误的选定文本


第二种方法是使用range.moveStart/End(在重复的范围内),如此问题的答案所述:(但是,当您使用已知的textarea父级时,您可以忽略有关节点查找的内容)。这并没有同样的问题,但它确实会报告所有索引,就好像换行符是简单的LF字符一样,即使textarea.value和range.text会将它们作为CRLF序列返回!因此,您不能直接使用它们来索引文本区域,但您可以使用一组换行符计数来修复它们,或者在使用之前只使用字符串替换掉值中的所有CR。

我将再次发布此函数,因为此问题已从另一个问题链接到另一个问题

以下内容将在所有浏览器中完成这项工作,并在不严重影响性能的情况下处理所有新行问题。我是在之后才想到这个的,现在我非常确信这是最好的函数

更新

此函数假定textarea/input具有焦点,因此您可能需要在调用它之前调用textarea的
focus()
方法

function getInputSelection(el) {
    var start = 0, end = 0, normalizedValue, range,
        textInputRange, len, endRange;

    if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
        start = el.selectionStart;
        end = el.selectionEnd;
    } else {
        range = document.selection.createRange();

        if (range && range.parentElement() == el) {
            len = el.value.length;
            normalizedValue = el.value.replace(/\r\n/g, "\n");

            // Create a working TextRange that lives only in the input
            textInputRange = el.createTextRange();
            textInputRange.moveToBookmark(range.getBookmark());

            // Check if the start and end of the selection are at the very end
            // of the input, since moveStart/moveEnd doesn't return what we want
            // in those cases
            endRange = el.createTextRange();
            endRange.collapse(false);

            if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
                start = end = len;
            } else {
                start = -textInputRange.moveStart("character", -len);
                start += normalizedValue.slice(0, start).split("\n").length - 1;

                if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
                    end = len;
                } else {
                    end = -textInputRange.moveEnd("character", -len);
                    end += normalizedValue.slice(0, end).split("\n").length - 1;
                }
            }
        }
    }

    return {
        start: start,
        end: end
    };
}

var el = document.getElementById("your_input");
el.focus();
var sel = getInputSelection(el);
alert(sel.start + ", " + sel.end);


这与新线有关。请参阅@bobince的答案了解相关背景,我的答案了解解决方案。我们是否可以在非病毒性许可证下获得此许可证,或者甚至将其贡献给公共领域?(这是那些关心版权的人的声音:-)@Tomasz:嗯,我将textarea/input selection内容移动到了一个单独的库中,因为它的工作方式与文档中的选择完全不同:。关于许可,标准的Stack Overflow Creative Commons许可证有什么问题吗?@Tomasz:很公平。我发现自由软件授权的细节令人困惑和乏味,但我理解一般原则。对于我要赠送的东西,我很乐意以用户最方便的方式授权。@Tim Down我无法使用您的函数在IE 6中获得正确的选择开始/结束值。请检查并让我知道这个函数是否测试得很好?我为我返回0,0。我错过什么了吗?
  function getCursorPosition($element) {
    var position = 0,
        selection;

    if (document.selection) {
      // IE Support
      $element.focus();
      selection = document.selection.createRange();
      selection.moveStart ('character', -$element.value.length);
      position = selection.text.length;
    } else if ($element.selectionStart || $element.selectionStart === 0) {
      position = $element.selectionStart;
    }

    return position;
  }

  function setCursorPosition($element, position) {
    var selection;

    if (document.selection) {
      // IE Support
      $element.focus ();
      selection = document.selection.createRange();
      selection.moveStart ('character', -$element.value.length);
      selection.moveStart ('character', position);
      selection.moveEnd ('character', 0);
      selection.select ();
    } else if ($element.selectionStart || $element.selectionStart === 0) {
      $element.selectionStart = position;
      $element.selectionEnd = position;
      $element.focus ();
    }
  }