javascriptjquery

Measure bounding box of text node in Javascript


I'm having trouble getting the size, in pixels, of a text node using Javascript. Example:

<p>
  first text block
  <b>second text block</b>
</p>

I need to get the bounding box of the two text blocks independently. I could get the size of the second block just by measuring the <b> element, but the first one eludes me. It doesn't appear that textnodes in Javascript have a height or width, so far as I can tell.

Wrapping the first text block in a <span> and measuring that is not an option, because I've discovered that a span does not necessarily inherit all of the styles above it, and when I wrap the text it suddenly changes size. It's like the Heisenberg Uncertainty Principle of Javascript; my attempt to measure something changes it.

I'm building an app that breaks HTML into pages (EPUB HTML, actually), and I need to know the position, height, and width of each block of text on the page so I can know whether to put it on this page or the next page.

Any suggestions?


Solution

  • You can do this with a Range that supports CSSOM View extensions, which is most recent browsers (Firefox 4+, WebKit since early 2009, Opera 11, maybe earlier) and a TextRange in IE. The TextRange code is tedious, so I've omitted it here.

    jsFiddle: http://jsfiddle.net/gdn6C/1/

    Code:

    function getTextNodeHeight(textNode) {
        var height = 0;
        if (document.createRange) {
            var range = document.createRange();
            range.selectNodeContents(textNode);
            if (range.getBoundingClientRect) {
                var rect = range.getBoundingClientRect();
                if (rect) {
                    height = rect.bottom - rect.top;
                }
            }
        }
        return height;
    }