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

前端 未结 5 1836
青春惊慌失措
青春惊慌失措 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:49

    The situation has changed since this question and most of the answers were posted: all major browsers now have at least one of the methods that make this relatively simple:

    • The standards-based approach from the CSSOM View spec: document.caretPositionFromPoint()
    • WebKit's proprietary version of the same: document.caretRangeFromPoint()
    • IE's proprietary TextRange object, which has a moveToPoint() method that takes pixel coordinates. However, it seems that moveToPoint() can be buggy (see here and here, for example); I've simply been lucky that has worked in all the documents I've used it in.

    Note that in IE up to and including version 11, the object produced is a TextRange rather than a DOM Range. In versions of IE that support Range, there is no easy way to convert between the two, although if you're willing to mess with the selection you can do something like the following, assuming you have a TextRange stored in a variable called textRange:

    textRange.select();
    var range = window.getSelection().getRangeAt(0);
    

    Here's some example code. It works in IE 5+, Edge, Safari and Chrome from around 2010 onwards, Firefox >= 20 and Opera >= 15.

    Live demo: http://jsfiddle.net/timdown/rhgyw2dg/

    Code:

    function createCollapsedRangeFromPoint(x, y) {
        var doc = document;
        var position, range = null;
        if (typeof doc.caretPositionFromPoint != "undefined") {
            position = doc.caretPositionFromPoint(x, y);
            range = doc.createRange();
            range.setStart(position.offsetNode, position.offset);
            range.collapse(true);
        } else if (typeof doc.caretRangeFromPoint != "undefined") {
            range = doc.caretRangeFromPoint(x, y);
        } else if (typeof doc.body.createTextRange != "undefined") {
            range = doc.body.createTextRange();
            range.moveToPoint(x, y);
        }
        return range;
    }
    

提交回复
热议问题