measure rendered html in javascript without affecting the measurement

Posted by drawnonward on Stack Overflow See other posts from Stack Overflow or by drawnonward
Published on 2010-06-12T06:25:33Z Indexed on 2010/06/12 6:33 UTC
Read the original article Hit count: 250

Filed under:
|
|
|
|

I am doing pagination in javascript. This is typographic pagination, not chopping up database results. For the most part it works, but I have run into a heisenberg issue where I cannot quite measure text without affecting it.

I am not trying to measure text before it is rendered. I want the actual position it shows up at on screen, so I can paginate to where it is naturally wrapped. I am measuring the vertical position of characters, not the horizontal width of strings. The way I do this is similar to this answer in that I am applying a style to a block of text, then measuring the position of the newly created span. If the span does not reach the end of the page, I clear it and make a new span in a linear search.

The problem is that the anti-aliased sub-pixel text layout is different when the span is applied. In rare cases, this causes the text to wrap differently when I measure it. I have only seen this when wrapping at a hyphen, and I assume it would not happen when wrapping at white space.

As a concrete example, "prepared-he" is the string I am having trouble with. When I measure up to "prepare" it appears, as expected, to be within the current page. When I measure "prepared" the whole phrase wraps down to the next line, moving it to the next page, so it looks like the "d" is the character to break at. I break the text between "prepare" and "d-he" and that is wrong. Trying to evaluate individual characters opens a whole can of worms I would rather avoid. The wrapping changes because, with the new span, the line is 1 pixel wider.

A solution to my problem could either be a better way to measure text using javascript, or a way to wrap text in a new element without affecting layout.

I have tried setting margin-right:-1px for the class of the span being created to wrap the text. This had no noticeable effect.

I am doing this in a UIWebView on the iPhone. There are some measurement related calls that are available in normal WebKit that are not available here. For example, Range does not have getBoundingClientRect or support setting an offset other than 0 in setStart or setEnd.

Thank you

© Stack Overflow or respective owner

Related posts about JavaScript

Related posts about css