Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Measure bounding box of text node in Javascript

Tags:

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?

like image 722
ccleve Avatar asked Aug 05 '11 18:08

ccleve


People also ask

What is getBoundingClientRect() in JavaScript?

The getBoundingClientRect() method returns the size of an element and its position relative to the viewport. The getBoundingClientRect() method returns a DOMRect object with eight properties: left, top, right, bottom, x, y, width, height.

How do you find the text node of an element?

text(); This gets the contents of the selected element, and applies a filter function to it. The filter function returns only text nodes (i.e. those nodes with nodeType == Node. TEXT_NODE ).

Does getBoundingClientRect include margin?

Border, padding and margin are not included. This means when you set a width, That width is set to the content only then you add the padding and border. border-box: includes content, padding and border.

What is text node in Javascript?

TextNode objects contain only text content without any HTML or XML markup. TextNode objects make it possible to insert texts into the document as nodes (appendChild, insertBefore).


1 Answers

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;
}
like image 123
Tim Down Avatar answered Sep 22 '22 14:09

Tim Down