Javascript 如何在不更改DOM的情况下计算文本选择的高度

Javascript 如何在不更改DOM的情况下计算文本选择的高度,javascript,css,dom,height,range,Javascript,Css,Dom,Height,Range,我正在使用范围来操纵选定的文本。我想计算从某人开始选择文本到完成文本的高度 我尝试了一个跨度到所选范围的开始和结束,我可以准确地计算高度形式,但它改变了DOM,并阻止我做一些其他范围操作,如高亮显示以前选择的文本 我也尝试过收集mosedown和mosueup位置的位置,但我需要一个从所选文本顶部到释放所选文本底部的准确高度,但情况并非总是如此 因此,我想知道是否有一种方法可以在不改变DOM的情况下计算文本选择的高度?我会获取所选文本并将其放置到具有相同宽度和样式的隐藏div中,然后获取其高度。

我正在使用范围来操纵选定的文本。我想计算从某人开始选择文本到完成文本的高度

我尝试了一个跨度到所选范围的开始和结束,我可以准确地计算高度形式,但它改变了DOM,并阻止我做一些其他范围操作,如高亮显示以前选择的文本

我也尝试过收集mosedown和mosueup位置的位置,但我需要一个从所选文本顶部到释放所选文本底部的准确高度,但情况并非总是如此


因此,我想知道是否有一种方法可以在不改变DOM的情况下计算文本选择的高度?

我会获取所选文本并将其放置到具有相同宽度和样式的隐藏div中,然后获取其高度。

我认为隐藏div方法不起作用。许多浏览器要么没有高度,要么像这样隐藏的元素的高度为0

也许,如果您克隆了DOM的这一部分,并将其添加到文档中的某个疯狂位置(如左:-1000px),您就可以得到该值


无论如何,如果Range对象没有为您提供这些数据,我认为您在使用变通方法获得一致的结果时会遇到问题。

这取决于您需要处理的浏览器。这里有一个函数可以在IE>=4和支持
Range
中的
getClientRects()
的浏览器中使用(Firefox>=4,自2009年起的WebKit,Opera)。如果您需要对早期浏览器的支持,则需要修改DOM,只要您将DOM恢复到以前的状态,这实际上是很好的

jsFiddle:

代码:


隐藏div(通过
visibility:hidden
甚至
display:none
仍然可以通过javascript“看到”,试试看,我做到了:))问题是如何在不更改DOM的情况下做到这一点。一个隐藏的div正在改变DOM。如果要使用一个单独的文本副本来进行测量,我相信这样做的方法是将它放在一个可见的div中,但要设置位置:带左的绝对值:-10000px;这会告诉浏览器完全布局它,但它实际上永远不会显示或导致滚动条。@jfriend00为true,但我想OP的意思是在文本块上“更改”DOM;同时使用
display:none
不会显示任何滚动条,在这种情况下也适用。某些浏览器不会对显示为:none的内容设置高度。@jfriend00哪些浏览器?我刚刚用“老”浏览器做了一个测试,使用这个:与IE7+8、Safari 4、FF 3、Opera 10一起工作,所有这些都是相当老的,他们理解隐藏高度,虽然不那么有趣,但事实是隐藏时高度不同!(除了FF 3),我的测试得到了高度,隐藏了div,得到了高度,并添加了两段,这就是高度处缺少的,奇怪的。
function getSelectionHeight() {
    var selHeight = 0;
    if (document.selection && document.selection.type == "Text") {
        var textRange = document.selection.createRange();
        selHeight = textRange.boundingHeight;
    } else if (window.getSelection) {
        var sel = window.getSelection();
        if (sel.rangeCount > 0) {
            var range = sel.getRangeAt(0);
            if (!range.collapsed && range.getClientRects) {
                var startRange = range.cloneRange();
                startRange.collapse(true);
                var selTop = startRange.getClientRects()[0].top;
                startRange.detach();
                var endRange = range.cloneRange();
                endRange.collapse(false);
                selHeight = endRange.getClientRects()[0].bottom - selTop;
                endRange.detach();
            }
        }
    }
    return selHeight;
}