gpt4 book ai didi

javascript - 为什么 Text.splitText() 会影响布局?

转载 作者:技术小花猫 更新时间:2023-10-29 12:08:29 24 4
gpt4 key购买 nike

假设我们的页面中有一个段落,只有一个文本 block 。

<p>laborum beatae est nihil, non hic ab, deserunt repellat quas. Est molestiae ipsum minus nesciunt tempore voluptate laboriosam</p>

在 DOM 方面,结构是:

HTMLParagraphElement
Text [laborum beatae est nihil...]

现在我们将其拆分(使用 Text.splitText())两次,以分离“deserunt repellat quas.Est” 片段。结构变为:

HTMLParagraphElement
Text [laborum beatae est nihil...]
Text [deserunt repellat quas. Est]
Text [ molestiae ipsum minus nesciunt...]

虽然此操作会影响 DOM,但它不会在元素级别(Text !== Element)上更改它,因此我预计不会有视觉上的变化。

然而 splitText() 也会影响布局,在所有经过测试的浏览器(Chrome 60、Firefox 55、Edge 14 - 均在 Windows 10 操作系统上)中触发重新布局和重新绘制。当我们调用 ParagraphElement.normalize() 时也会发生同样的情况,将 Text 节点的数量减少回 1;重新布局和重绘再次被触发。

这有一个令人讨厌的副作用,可以在 this demo 中看到。 .如果你检查'quas'附近的单词。 Est',你看他们居然换了位置!

它在 Firefox 中清晰可见,而在 Chrome 中要微妙得多(但也可以区分)。令我感到有趣的是,Edge 中并没有出现这样的“文字舞蹈”。

这很重要的原因显示在 this demo 中。的(某种)垫片选择引擎。此特定版本在 Firefox 中无法使用(尚不支持 caretRangeFromPoint - 啊!),但即使将“point2dom”重新连接到 caretPositionFromPoint 中,突出显示的文本也会重新定位 -在 Chrome 中一样多,甚至更糟。同样,它似乎在 Edge 中运行良好。

所以,事实上,我最感兴趣的是了解原因和找到解决方法。

这是显示第一个演示如何在 Chrome 中播放的动画 gif(我只是间歇性地触发一次点击)

when the words go marching in...

这里的颤抖很微妙,但仍然可以在所有单词上观察到。我特别困惑为什么 molestiae 中的 i 会抖动,因为周围的字母似乎停留在原处。

而且使用不常见的字体和更多的文本会变得更糟(更糟),就像在选择演示中一样。

切换到 font-family:monospace 并没有解决这个问题,反而让它看起来更糟:

enter image description here

font-kerning 切换为 none 也无济于事。

更新:问题is registered在 Blink 跟踪器上。

最佳答案

关于重新布局/重绘,这是意料之中的,因为文本节点也是 DOM 节点...不是 DOM 元素,但浏览器确实必须重新考虑布局,即使您希望它保持不变,它们可能要搬家了。可能是因为字距。

现在,为什么拆分文本会引起移动?我期望的是因为浏览器单独绘制文本部分。两个相邻的字母通常有一个空格,这个空格可能会根据字母的不同而被字体缩小,以“WA”为例,W的结尾在A的开头之上,称为kerning。 (谢谢伊斯梅尔米格尔)。当单独绘制文本节点时,每个节点都必须在下一个开始之前完成,因此它可能会在这些字母之间创建更大的空间,因为它可以防止任何字距调整。

抱歉,字母之间的空格确实有名字,但我忘记了...

.one {
background-color: #FF9999;
}

.two {
background-color: #99FF99;
}

body {
font-size: 40px;
}

div>span {
border: 1px solid black;
}
<div><span>AW</span> - in the same DOM node.</div>
<div><span><span>A</span><span>W</span></span> - in two different nodes</div>
<div><span><span class="one">A</span><span class="two">W</span></span> - in two different nodes, colored</div>

至于如何防止这种行为,最简单的解决方案是使用等宽字体。这在美学上可能并不总是可行的。字距调整是嵌入在字体文件中的信息,从该信息中剥离字体似乎是防止字体闪烁的最可靠方法。此外,CSS 属性 font-kerning设置为 none 时会有帮助。

另一种方法是在文本后面或前面添加绝对元素,以模拟将一部分文本包围到一个元素中的事实,但这完全取决于最终目标。

看得更远一点 CSS-Tricks have a nice article about text-rendering它也有助于字体字距调整。

编辑:在写这个答案时,我忽略了文本是合理的这一事实。虽然我的回答解释了为什么将一个文本节点切割成多个时会出现一定的闪烁,但它绝不解释为什么浏览器似乎在计算对齐空格时出现问题。

关于javascript - 为什么 Text.splitText() 会影响布局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45818759/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com