Javascript 如何在浏览器呈现的HTML文档中查找文本最底行的位置

Javascript 如何在浏览器呈现的HTML文档中查找文本最底行的位置,javascript,html,css,dom,Javascript,Html,Css,Dom,我在我的应用程序的web视图中显示了一些HTML(在iOS应用程序中是WKWebView,但这一部分是不相关的,因为在多个平台上使用相同的HTML/JavaScript)。在web视图之外,用户可以说“下一页”。作为响应,我想将文档滚动一个屏幕高度。这很简单,我可以很容易做到,而且效果很好 问题是,如果最后一行在一个“页面”和下一个“页面”之间分割,则会在一页上看到该行的上半部分,在下一页上看到该行的下半部分。这很难读。因此,理想情况下,我希望按呈现的行遍历HTML文档,找到完全可见的最后一行,

我在我的应用程序的web视图中显示了一些HTML(在iOS应用程序中是
WKWebView
,但这一部分是不相关的,因为在多个平台上使用相同的HTML/JavaScript)。在web视图之外,用户可以说“下一页”。作为响应,我想将文档滚动一个屏幕高度。这很简单,我可以很容易做到,而且效果很好

问题是,如果最后一行在一个“页面”和下一个“页面”之间分割,则会在一页上看到该行的上半部分,在下一页上看到该行的下半部分。这很难读。因此,理想情况下,我希望按呈现的行遍历HTML文档,找到完全可见的最后一行,然后滚动,使后面的行位于屏幕顶部。当然,这假设没有表格、图像、浮动元素等使“线”的定义复杂化,但如果我能先解决更简单的情况,我可以处理这个问题

我可以迭代DOM中的段落,并为这些段落找到边界矩形,但没有任何明显的方法可以将其进一步分解。我可以想象一个解决方案,我用
将每个单词包装在HTML中,然后迭代查看位置和高度以确定屏幕底部的位置,但这听起来效率很低

我可以控制所显示文档中的CSS和JavaScript(所有文档都使用相同的CSS和JavaScript,它们是在运行时添加的),如果有必要,我可以在运行时修改HTML,但性能显然是一个问题,所以我不想在没有必要的情况下对所显示的HTML做很多手脚


我强烈怀疑,如果不添加如上所述的
标记,这是不可能的。还有其他建议吗?

我会浏览所有段落(主要是
p
,但也可以考虑其他标记),获取它们的顶部偏移量,并找到最后一个顶部偏移量仍在可查看范围内的段落。这应该是执行受控“向下翻页”操作后的顶部段落

下面是一些依赖于
jQuery
返回该元素偏移量的代码:

function offsetForNextPage() {
    var bottom = $(window).scrollTop() + $(window).height();
    var result = $(window).scrollTop() + $(window).height() * 0.75; // minimum scroll amount
    $('p, span, div').each(function(idx) {
        if ($(this).offset().top >= bottom) {
            return false;
        }
        result = Math.max($(this).offset().top, result);
    });
    return result;
}
当然,您可以添加要包含在此计算中的标记。请注意,如果找不到合适的元素,或者它将导致被认为太小的偏移量,则返回最小偏移量。上述函数已将该最小值设置为当前偏移加上视口高度的75%

下面是空格键触发页面向下时的外观:

$(document).keydown(function (e) {
    if (e.which === 32) {
        e.preventDefault();
        $('html, body').animate({
            scrollTop: offsetForNextPage()
        }, 1000);
    }
});
这是一本书

注意:对于
$(window).height()
要给出正确的值,必须在
html
页面的开头有一个有效的文档类型声明,如:

<!doctype html>

我将浏览所有段落(主要是
p
,但也可以考虑其他标记),获取它们的顶部偏移量,并找到最后一个顶部偏移量仍在可查看范围内的段落。这应该是执行受控“向下翻页”操作后的顶部段落

下面是一些依赖于
jQuery
返回该元素偏移量的代码:

function offsetForNextPage() {
    var bottom = $(window).scrollTop() + $(window).height();
    var result = $(window).scrollTop() + $(window).height() * 0.75; // minimum scroll amount
    $('p, span, div').each(function(idx) {
        if ($(this).offset().top >= bottom) {
            return false;
        }
        result = Math.max($(this).offset().top, result);
    });
    return result;
}
当然,您可以添加要包含在此计算中的标记。请注意,如果找不到合适的元素,或者它将导致被认为太小的偏移量,则返回最小偏移量。上述函数已将该最小值设置为当前偏移加上视口高度的75%

下面是空格键触发页面向下时的外观:

$(document).keydown(function (e) {
    if (e.which === 32) {
        e.preventDefault();
        $('html, body').animate({
            scrollTop: offsetForNextPage()
        }, 1000);
    }
});
这是一本书

注意:对于
$(window).height()
要给出正确的值,必须在
html
页面的开头有一个有效的文档类型声明,如:

<!doctype html>


这可能是我能做的最好的了。如果当前页面顶部的段落跨越多个页面,我必须让它优雅地失败。我想知道我是否可以看看那一段中使用的字体的行高。我必须找出最适合的地方…我已经更新了代码并使用了最小的滚动距离。这将防止在涉及大量段落时出现不希望出现的行为。我已经将最小值设置为窗口高度的75%,但您可以根据自己的意愿进行设置。我最终使用了与此非常类似的方法。我碰巧把我所有的段落和类似段落的东西都包装在
标记中,因为我可以控制HTML。所以我对类似段落的元素的搜索很简单。一旦我找到了跨越屏幕底部的段落,我就使用
getComputedStyle()
获得
行高
,然后将其添加到div的
offsetTop
,直到我尽可能接近屏幕底部而不经过。我做了一个测试,以确保我的y坐标不是和现在一样,如果是的话,我会使用95%的屏幕高度。这可能是我能做的最好的了。如果当前页面顶部的段落跨越多个页面,我必须让它优雅地失败。我想知道我是否可以看看那一段中使用的字体的行高。我必须找出最适合的地方…我已经更新了代码并使用了最小的滚动距离。这将防止在涉及大量段落时出现不希望出现的行为。我已经将最小值设置为窗口高度的75%,但您可以根据自己的意愿进行设置。我最终使用了与此非常类似的方法。我碰巧把我所有的段落和类似段落的东西都包装在
标记中,因为我可以控制HTML。所以我对类似段落的元素的搜索很简单。找到跨越屏幕底部的段落后,我使用
getComputedStyle()
获取
行高
,然后将其添加到div的
offsetTop
,直到我尽可能接近屏幕底部