文本内容元素内的空白处理不是很直观。虽然文本的实际布局会删除前导/尾随空白,但对
getSelection()
的 API 调用会计算所有空白字符。最好删除所有前导和尾随空格。
另外,你最好使用SVG自己的API来处理文本位置。这样,您可以确保考虑所有位置调整,并且
y
值代表基线。
选择一些文本以查看下划线。该代码不处理跨越多个
<text>
元素的选择,您将不得不为此做更多工作。
document.addEventListener('selectionchange', () => {
const {
startContainer: { parentElement }, // the text element
startOffset, // start index
endOffset // end index
} = window.getSelection().getRangeAt(0);
// start position
const p1 = parentElement.getStartPositionOfChar(startOffset);
// end position of endOffset - 1
const p2 = parentElement.getEndPositionOfChar(endOffset - 1);
// line element to emulate underlining
const line = document.querySelector('line');
line.setAttribute('x1', p1.x);
line.setAttribute('y1', p1.y + 3);
line.setAttribute('x2', p2.x);
line.setAttribute('y2', p2.y + 3);
});
<svg
width="784"
height="1015"
viewBox="0 0 612 792"
style="user-select: text"
data-page-number="2"
>
<text
data-page-number="2"
lengthAdjust="spacing"
fill="black"
x="472.229"
y="99.89499999999998"
textLength="5.25"
height="10.5"
style="font-size: 10.5px; font-family: serif"
>2</text>
<text
data-page-number="2"
lengthAdjust="spacing"
fill="black"
x="154.76799999999997"
y="134.765"
textLength="322.71100000000007"
height="10.5"
style="font-size: 10.5px; font-family: serif"
>A lot of people say to me: ”Ivaylo! You are so smart. Your newsletter</text>
<text
data-page-number="2"
lengthAdjust="spacing"
fill="black"
x="133.768"
y="151.14499999999998"
textLength="343.7105000000001"
height="10.5"
style="font-size: 10.5px; font-family: serif"
>is full of insights. The books you summarize are so elegantly presented
with</text>
<text
data-page-number="2"
lengthAdjust="spacing"
fill="black"
x="133.768"
y="167.52499999999998"
textLength="270.669"
height="10.5"
style="font-size: 10.5px; font-family: serif"
>so much attention and care. Your parents must be proud!”</text>
<line stroke="red" />
</svg>