Координаты выделенного текста на странице браузера - PullRequest
29 голосов
/ 27 июля 2011

Мне нужны координаты в пикселях начала выделения текста (в любом месте страницы, а не в текстовой области).

Я пытался использовать координаты курсора, но это не сработало, потому чтоКоординаты курсора и начало выделения не всегда совпадают (например, когда пользователь перетаскивает текст).

Надеюсь, у кого-то есть решение!

Ответы [ 2 ]

56 голосов
/ 27 июля 2011

В IE> = 9 и браузерах, отличных от IE (Firefox 4+, браузеры WebKit, выпущенные с начала 2009 г., Opera 11, возможно, ранее), вы можете использовать getClientRects() метод Range,В IE 4 - 10 вы можете использовать свойства boundingLeft и boundingTop для TextRange, которые можно извлечь из выбора.Вот функция, которая будет делать то, что вы хотите в последних браузерах.

Обратите внимание, что в некоторых ситуациях вы можете ошибочно получить координаты 0, 0, как упомянуто в комментариях @Louis.В этом случае вам придется вернуться к временному обходу временной вставки элемента и получения его позиции.

jsFiddle: http://jsfiddle.net/NFJ9r/132/

Код:

function getSelectionCoords(win) {
    win = win || window;
    var doc = win.document;
    var sel = doc.selection, range, rects, rect;
    var x = 0, y = 0;
    if (sel) {
        if (sel.type != "Control") {
            range = sel.createRange();
            range.collapse(true);
            x = range.boundingLeft;
            y = range.boundingTop;
        }
    } else if (win.getSelection) {
        sel = win.getSelection();
        if (sel.rangeCount) {
            range = sel.getRangeAt(0).cloneRange();
            if (range.getClientRects) {
                range.collapse(true);
                rects = range.getClientRects();
                if (rects.length > 0) {
                    rect = rects[0];
                }
                x = rect.left;
                y = rect.top;
            }
            // Fall back to inserting a temporary element
            if (x == 0 && y == 0) {
                var span = doc.createElement("span");
                if (span.getClientRects) {
                    // Ensure span has dimensions and position by
                    // adding a zero-width space character
                    span.appendChild( doc.createTextNode("\u200b") );
                    range.insertNode(span);
                    rect = span.getClientRects()[0];
                    x = rect.left;
                    y = rect.top;
                    var spanParent = span.parentNode;
                    spanParent.removeChild(span);

                    // Glue any broken text nodes back together
                    spanParent.normalize();
                }
            }
        }
    }
    return { x: x, y: y };
}

ОБНОВЛЕНИЕ

Я отправил ошибку WebKit в результате комментариев, и теперь она исправлена.

https://bugs.webkit.org/show_bug.cgi?id=65324

17 голосов
/ 21 октября 2014

Приведенный выше ответ TimDown не работает, если символ вставки находится в пустом элементе.

Код ниже решает проблему. Обратите внимание, что он почти идентичен решению TimDown, за исключением того, что этот код проверяет, что массив range.getClientRects() имеет length>0 перед вызовом range.getClientRects()[0]

function getSelectionCoords() {
    var sel = document.selection, range, rect;
    var x = 0, y = 0;
    if (sel) {
        if (sel.type != "Control") {
            range = sel.createRange();
            range.collapse(true);
            x = range.boundingLeft;
            y = range.boundingTop;
        }
    } else if (window.getSelection) {
        sel = window.getSelection();
        if (sel.rangeCount) {
            range = sel.getRangeAt(0).cloneRange();
            if (range.getClientRects) {
                range.collapse(true);
                if (range.getClientRects().length>0){
                    rect = range.getClientRects()[0];
                    x = rect.left;
                    y = rect.top;
                }
            }
            // Fall back to inserting a temporary element
            if (x == 0 && y == 0) {
                var span = document.createElement("span");
                if (span.getClientRects) {
                    // Ensure span has dimensions and position by
                    // adding a zero-width space character
                    span.appendChild( document.createTextNode("\u200b") );
                    range.insertNode(span);
                    rect = span.getClientRects()[0];
                    x = rect.left;
                    y = rect.top;
                    var spanParent = span.parentNode;
                    spanParent.removeChild(span);

                    // Glue any broken text nodes back together
                    spanParent.normalize();
                }
            }
        }
    }
    return { x: x, y: y };
}
...