Creating a collapsed range from a pixel position in FF/Webkit

前端 未结 5 1835
青春惊慌失措
青春惊慌失措 2020-11-30 06:36

Using JavaScript, I would like to create a collapsed range from a pixel position, in order to insert new nodes in the flow of the document, after the range identified by thi

5条回答
  •  情话喂你
    2020-11-30 06:44

    Under MSIE, you wrote:

    var range = document.selection.createRange();
    range.moveToPoint(x, y); 
    

    For other browsers, the idea is to determine the HTML element at x/y position and to create a one character selection on it. Based on range.getBoundingClientRect(), you can determine if the one character selection if before or after the x/y position. We then can select the next character until the selection position raich the x/y position. I wrote the following implementation for Firefox, Safari and Chrome:

    var nodeInfo = getSelectionNodeInfo(x, y);
    var range = document.createRange();
    range.setStart(nodeInfo.node, nodeInfo.offsetInsideNode);
    range.setEnd(nodeInfo.node, nodeInfo.offsetInsideNode);
    
    /**
    Emulates MSIE function range.moveToPoint(x,y) b
    returning the selection node info corresponding
    to the given x/y location.
    
    @param x the point X coordinate
    @param y the point Y coordinate
    @return the node and offset in characters as 
    {node,offsetInsideNode} (e.g. can be passed to range.setStart) 
    */
    function getSelectionNodeInfo(x, y) {
        var startRange = document.createRange();
        window.getSelection().removeAllRanges();
        window.getSelection().addRange(startRange);
    
        // Implementation note: range.setStart offset is
        // counted in number of child elements if any or
        // in characters if there is no childs. Since we
        // want to compute in number of chars, we need to
        // get the node which has no child.
        var elem = document.elementFromPoint(x, y);
        var startNode = (elem.childNodes.length>0?elem.childNodes[0]:elem);
        var startCharIndexCharacter = -1;
        do {
            startCharIndexCharacter++;
            startRange.setStart(startNode, startCharIndexCharacter);
            startRange.setEnd(startNode, startCharIndexCharacter+1);
            var rangeRect = startRange.getBoundingClientRect();
        } while (rangeRect.left

    These two piece of code have been tested under :

    • MSIE 7, MSIE 9
    • Firefox 5, Firefox 10
    • Chrome 9
    • Safari 5

    The following situations were not tested:

    • zooming factor issues
    • HTML elements with more than one text line

提交回复
热议问题