【问题标题】:measure rendered html in javascript without affecting the measurement在不影响测量的情况下测量 javascript 中呈现的 html
【发布时间】:2011-03-02 22:44:11
【问题描述】:

我正在用 javascript 进行分页。这是排版分页,而不是分割数据库结果。在大多数情况下它可以工作,但我遇到了 Heisenberg 问题,我无法在不影响文本的情况下完全测量文本。

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

问题是应用 span 时抗锯齿的亚像素文本布局不同。在极少数情况下,这会导致我测量文本时以不同方式换行。我只在用连字符换行时看到了这种情况,并且我认为在空白处换行时不会发生这种情况。

作为一个具体的例子,“prepared-he”是我遇到问题的字符串。当我达到“准备”时,它按预期显示在当前页面内。当我测量“已准备好”时,整个短语会转至下一行,将其移至下一页,因此看起来“d”是要中断的字符。我打破了“准备”和“d-he”之间的文字,这是错误的。试图评估单个字符会打开一整罐我宁愿避免的蠕虫。换行发生了变化,因为有了新的跨度,线宽了 1 个像素。

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

我已经尝试为要创建的跨度类设置margin-right:-1px 以换行文本。这没有明显的效果。

我在 iPhone 上的 UIWebView 中执行此操作。普通 WebKit 中提供了一些与测量相关的调用,但此处不可用。例如 Range 不具备 getBoundingClientRect 或不支持在 setStart 或 setEnd 中设置非 0 的偏移量。

谢谢

编辑:

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

我尝试向后迭代而不是向前遍历文本。包装错误出现在不同的地方,但总体问题仍然存在。

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

我尝试减小跨度的字体大小。换行规则似乎允许在一个范围内换行,即使它在一个单词内,以便用另一组错误替换一组错误。

【问题讨论】:

    标签: javascript css uiwebview pagination ios


    【解决方案1】:

    这有点逃避,但你真的想删掉一段吗?
    在第一个离开视口的<p> 处中断会不会提高可读性?

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

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

    我想在做太多其他事情之前,我们确定我们不能让这个跨度真正无量纲吗?

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

    【讨论】:

    • 或第一个<br>。不清楚文本有什么格式。
    • 这就是我们要替换的方法。我认为这很好,但这不取决于我。文本主要是段落。
    • @drawnonward:没有更严重的问题要先做? ;-) 如果你知道: (1) 最后一个屏幕元素的总偏移量; (2) 对于第一个屏幕外元素也是如此; (3) Font-size, line-height, padding and margin... 那你应该能猜的够近了。通过从已知的屏幕外开始进行精炼并一次精炼一个单词。
    • 或者也许...在屏幕上的最后一个段落中,将每一个最后的母爱'n 空格包裹在一个跨度中,并使用这些偏移量进行细化。
    • @Brock 基于文本的问题是空格不是唯一可以换行的合法字符,我必须至少支持一些 unicode。我会尝试向后而不是向前搜索。
    【解决方案2】:

    我没有找到理想的解决方案。这是我想出的解决方案。

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

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

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

    这些问题的出现似乎是因为格式改变了字符之间的字距。当我使用跨度来测量字符的位置时,它的位置略有不同,因为它从像素边界开始并忽略了前一个字符的字距调整。

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

    【讨论】:

    • 所以你是在一个单词中间换页? Even if it 正确地连字符,这将是最不利于用户的。我会很生气。 ;)
    • 不,目标是匹配网络浏览器使用的自然换行。问题是使用跨度测量文本会改变单词大小和换行规则,因此在测量时可能会在单词中间中断。最好的解决方案是测量不改变换行规则或在中间打断单词的文本的方法。上述解决方案解决了测量改变测量的事实。
    猜你喜欢
    • 2019-09-06
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    • 2019-09-07
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多