获取文本选择的每一行

时间:2019-04-10 15:31:31

标签: javascript text selection highlight

我有一个固定宽度的文本块,我正在尝试获取文本的boundingClientRect的每一行。我想知道Selection api是否有一种方法可以使我丢失。有没有简单的方法来获取所选文本的每一行?

当前,我能想到的唯一解决方案是在所选内容中的每个字符周围创建跨度,然后如果它们在边界客户端rect中具有相同的y坐标,则将它们合并。这是非常低效的,所以我很好奇是否有更简单的方法。

下面是我要查找的图像的图像表示。选择API仅在整个框内给出一个矩形,包括未选择的文本。我正在尝试在每条选择线周围找到矩形。

What the selectino api bounding box gives you and what I'm trying to find

所选内容将始终是文本。因此,无需担心图像。但是,它们可能在不同的元素中,但是它们将是相同的标记类型(例如,没有链接或em / strong标记)。

返回所选文本块

const selection = window.getSelection().getRangeAt(0);

markjs提供了一种突出显示的解决方案,该解决方案将所有内容包装在一个标签中。

<mark><p>hello there</p></mark>

我的计划是使用类似的算法来获取内部html并遍历每个字符,并将其包装在具有类名的新标签中,然后可以找到该类名,然后计算边界框。编写起来很简单,但是计算量却比我想要的还要大。

有什么方法可以简单地获取每行的边界框吗?

1 个答案:

答案 0 :(得分:2)

您可以改用getClientRects

var selectionDivs = [];

document.addEventListener('selectionchange', function () {
  var range = window.getSelection().getRangeAt(0);
  var rects = range.getClientRects();
  selectionDivs.forEach(function (div) {
    div.remove();
  });
  selectionDivs = [];
  for (var i = 0; i < rects.length; i++) {
    var div = document.createElement('div');
    div.className = 'rect';
    div.style.left = (window.scrollX + rects[i].left) + 'px';
    div.style.top = (window.scrollY + rects[i].top) + 'px';
    div.style.width = rects[i].width + 'px';
    div.style.height = rects[i].height + 'px';
    document.body.appendChild(div);
    selectionDivs.push(div);
  }
});
.rect {
  position: absolute;
  pointer-events: none;
  border: 1px solid black;
}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc sed velit dignissim sodales ut eu. Imperdiet sed euismod nisi porta lorem mollis. Nisl suscipit adipiscing bibendum est. Elit eget gravida cum sociis natoque penatibus et. Mauris in aliquam sem fringilla. In arcu cursus euismod quis viverra. Imperdiet sed euismod nisi porta lorem mollis. Eget gravida cum sociis natoque penatibus et. Sed libero enim sed faucibus turpis in eu mi bibendum. Varius duis at consectetur lorem donec massa. Facilisi nullam vehicula ipsum a arcu. Libero justo laoreet sit amet cursus sit. At in tellus integer feugiat scelerisque varius morbi. Est ullamcorper eget nulla facilisi etiam. Semper eget duis at tellus at urna condimentum mattis.