IE 的 document.selection.createRange 不包括前导或尾随空行 [英] IE's document.selection.createRange doesn't include leading or trailing blank lines

查看:18
本文介绍了IE 的 document.selection.createRange 不包括前导或尾随空行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从文本区域中提取准确的选择和光标位置.像往常一样,在大多数浏览器中容易的东西在 IE 中并不容易.

I'm trying to extract the exact selection and cursor location from a textarea. As usual, what's easy in most browsers is not in IE.

我正在使用这个:

var sel=document.selection.createRange();
var temp=sel.duplicate();
temp.moveToElementText(textarea);
temp.setEndPoint("EndToEnd", sel);
selectionEnd = temp.text.length;
selectionStart = selectionEnd - sel.text.length;

在 99% 的情况下都有效.问题是 TextRange.text 不返回前导或尾随换行符.因此,当光标位于一段之后的几个空行时,它会在前一段的末尾产生一个位置 - 而不是实际的光标位置.

Which works 99% of the time. The problem is that TextRange.text doesn't return leading or trailing new line characters. So when the cursor is a couple of blank lines after a paragraph it yields a position at the end of the preceeding paragraph - rather than the actual cursor position.

例如:

the quick brown fox|    <- above code thinks the cursor is here

|    <- when really it's here

我能想到的唯一解决方法是在选择之前和之后临时插入一个字符,抓取实际选择,然后再次删除这些临时字符.这是一个 hack,但在快速实验中看起来它会起作用.

The only fix I can think of is to temporarily insert a character before and after the selection, grab the actual selection and then remove those temp characters again. It's a hack but in a quick experiment looks like it will work.

但首先我想确定没有更简单的方法.

But first I'd like to be sure there's not an easier way.

推荐答案

我正在添加另一个答案,因为我的上一个答案已经变得有些史诗般了.

I'm adding another answer since my previous one is already getting somewhat epic.

这是我认为最好的版本:它采用了 bobince 的方法(在我的第一个答案的评论中提到)并修复了我不喜欢它的两件事,首先是它依赖于流浪的 TextRanges在 textarea 之外(从而损害性能),其次是必须为字符数选择一个巨大数字来移动范围边界的肮脏.

This is what I consider the best version yet: it takes bobince's approach (mentioned in the comments to my first answer) and fixes the two things I didn't like about it, which were first that it relies on TextRanges that stray outside the textarea (thus harming performance), and second the dirtiness of having to pick a giant number for the number of characters to move the range boundary.

function getSelection(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(/
/g, "
");

            // 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("
").length - 1;

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

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

var el = document.getElementById("your_textarea");
var sel = getSelection(el);
alert(sel.start + ", " + sel.end);

这篇关于IE 的 document.selection.createRange 不包括前导或尾随空行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆