Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getting offsetLeft of a text range

Can anyone tell me why this code is returning undefined.

I was hoping this would give the left coordinate of the user selected text.

function alertRangeObject(){
    var userSelection;

    if(window.getSelection)
    { 
    userSelection = window.getSelection();
    }
    else if (document.selection)
    {
    userSelection = document.selection.createRange();
    }

    var selectedText = userSelection;
    if (userSelection.text)
    {
        selectedText = userSelection.text;
    }

    var rangeObject = getRangeObject(userSelection);

    function getRangeObject(selectionObject)
    {
        if (selectionObject.getRangeAt)
        return selectionObject.getRangeAt(0);
        else { //safari
            var range = document.createRange();
            range.setStart(selectionObject.anchorNode, selectionObject.anchorOffset);
            range.setEnd(SelectionObject.focusNode, selectionObject.focusOffset);
            return range;
              }
        }


       alert(rangeObject.offsetLeft);
   }

The frustrating thing is when you alert(rangeObject) I get the selected text. But I was I thought that if this was a text range I could use the offsetLeft method to get the left coordinates. Can anyone see what I'm doing wrong. Thanks.

like image 745
Jeff Avatar asked Jan 18 '23 22:01

Jeff


1 Answers

TextRange objects do indeed have offsetLeft and offsetTop properties, but the code you've posted will throw an error in IE < 9 because the getRangeObject() function returns undefined. I'd suggest alternative code. The following will get you the top left coordinates of the selection relative to the viewport in IE >= 4 and recent versions of other browsers that support the getBoundingClientRect() method of Range, and returns (0, 0) in other browsers.

jsFiddle: http://jsfiddle.net/NkSmn/

Code:

function getSelectionTopLeft() {
    var x = 0, y = 0;
    // Use standards-based method only if Range has getBoundingClientRect
    if (window.getSelection && document.createRange
    && typeof document.createRange().getBoundingClientRect != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount > 0) {
            var rect = sel.getRangeAt(0).getBoundingClientRect();
            x = rect.left;
            y = rect.top;
        }
    } else if (document.selection && document.selection.type != "Control") {
        // All versions of IE
        var textRange = document.selection.createRange();
        x = textRange.boundingLeft;
        y = textRange.boundingTop;
    }
    return { x: x, y: y };
}            

I'm working on a Range/Selection position module for Rangy at the moment that uses a similar approach to the above. It's a work in progress but works pretty well in most scenarios and browsers. It should make it into version 1.3. Demo here: http://rangy.googlecode.com/svn/trunk/demos/position.html

As an aside, that code looks like it's based on code from PPK's introduction to Ranges page on quirksmode. It's out of date and the code is confusing and not ideal, but there should be some improvement there in the near future.

like image 168
Tim Down Avatar answered Jan 29 '23 12:01

Tim Down