测量在javascript中呈现的html而不影响测量

时间:2010-06-12 06:25:33

标签: javascript css uiwebview pagination ios

我在javascript中做分页。这是排版分页,而不是砍掉数据库结果。在大多数情况下它都有效,但我遇到了海森堡问题,我无法在不影响文本的情况下测量文本。

我不是想measure text before it is rendered。我想要它在屏幕上显示的实际位置,所以我可以分页到它自然包裹的地方。我正在测量字符的垂直位置,而不是字符串的水平宽度。我这样做的方式类似于this answer,因为我将样式应用于文本块,然后测量新创建的跨度的位置。如果跨度未到达页面末尾,我会清除它并在线性搜索中创建新的跨度。

问题是当应用跨度时,消除锯齿的子像素文本布局是不同的。在极少数情况下,这会导致文本在测量时以不同方式换行。我只是在用连字符包裹时才看到这个,我认为在白色空间包裹时不会发生这种情况。

作为一个具体的例子,“准备他”是我遇到麻烦的字符串。当我测量到“准备”时,正如预期的那样,它出现在当前页面内。当我测量“准备好”时,整个短语包含到下一行,将其移动到下一页,所以看起来“d”是要打破的字符。我打破了“准备”和“d-he”之间的文本,这是错误的。试图评估个别角色打开了我宁愿避免的一整套蠕虫。包装会发生变化,因为使用新的跨度时,线宽会增加1个像素。

我的问题的解决方案可能是使用javascript测量文本的更好方法,或者是在不影响布局的情况下将文本包装在新元素中的方法。

我已尝试为正在创建的范围的类设置margin-right:-1px以包装文本。这没有明显的效果。

我在iPhone上的UIWebView中这样做。普通WebKit中有一些与测量无关的调用,这些调用在此处不可用。例如,Range没有getBoundingClientRect或支持在setStart或setEnd中设置0以外的偏移量。

谢谢

编辑:

我尝试了使得跨度无量纲的unomi的建议。它没有效果。我给出的跨度没有规则,只是用于快速删除。

我尝试向后迭代而不是通过文本转发。包装错误出现在不同的地方,但整体问题仍然存在。

文本主要是带有一些简单样式的段落。我不认为我使用的方法可以使用表或列表。在段落中,我一次将跨度应用于一个字符。

我尝试减少跨度的字体大小。包装规则似乎允许在一个范围内包装,即使它在一个单词内,因此将一组错误替换为另一组错误。

2 个答案:

答案 0 :(得分:1)

这有点像一个警察,但你真的想砍掉一个段落吗? 它不会提高可读性,只是在第一个离开视口的<p>处中断吗?

好的,所以为了清楚,听起来你正在测试一个字符的位置,这个字符是通过文字逐个字符移动的?如果这是正确的,并且您遇到的问题是分解单词,为什么不简单地从空格跳到空格(可选包括连字符)而不是从字符到字符?

保留1个先前的位置,并在当前位置离开视口时中断。

我想在做了太多其他事情之前,我们是否确定我们无法使该范围真正无量纲?

span.marker {
  border: 0px; padding: 0px; margin: 0px; 
  width:0px: overflow:hidden; height:0px;
}

答案 1 :(得分:0)

我找不到理想的解决方案。这是我提出的解决方案。

我一次将测量范围应用于一个字符。我发现有两个有问题的案例。有时一个单词最终会变长,并且在测量时单词会换行到下一行。有时,带有连字符或类似字符的单词在测量时会有不同的分裂。

对于整个单词换行的情况,我将测量跨度的类更改为具有较小的字体大小。如果使用较小的字体大小时相同的字符不会换行到下一行,我会将测量忽略为无效并继续搜索。

对于不同分词的情况,我使用前一个字符测量相同的字符。如果跨度没有包含两个字符,那么我假设下一个字符将在那里换行并打破。

似乎会出现这些问题,因为格式化会更改字符之间的字距。当我使用跨度来测量角色的位置时,它位于稍微不同的位置,因为它从像素边界开始并忽略对前一个角色的字距调整。

我没有尝试跨越整个文本块而不是单个字符。这会增加一些复杂性,我怀疑同样的问题会以稍微不同的方式出现。

相关问题