【问题标题】:Split html string into multiple pages将html字符串拆分为多个页面
【发布时间】:2023-04-01 23:08:02
【问题描述】:

我正在尝试开发电子书阅读器类型的 android 应用程序。我需要根据可用的屏幕空间将长 html 字符串(由服务器在运行时发送)动态拆分为页面。 Html 内容是一篇文章,可以包含文本、图像、视频等。我使用 WebView 来显示 html。

谁能告诉我如何实现这一目标。

提前致谢。

【问题讨论】:

  • 您能分享一下您是如何解决这个问题的吗?谢谢。

标签: android-webview


【解决方案1】:

我认为,进行任何类型的 HTML/DOM 解析都会让你陷入困境,这意味着你正在有效地开始开发自己的 HTML 布局引擎。

最好使用 CSS3 列函数。基本上,让您的内容在固定的宽度和高度列中呈现。这将成为您的页面。然后将您的内容位置向左移动以在页面之间移动,并将其包装在将隐藏溢出元素的容器中。

我们的 HTML 基本上是:

<body>
    <div id="container">
        <div id="content">

            CONTENT GOES HERE

            <span id="endMarker"></span>
        </div>
    </div>
    <div>
        <button id="previous">Previous</button>
        <span id="page">Page N of M</span>
        <button id="next">Next</button>
    </div>
</body>

我们的基本 CSS 是:

#container {
    width: 240px;
    overflow: hidden;
    background-color: yellow;
}
#content {
    position: relative;
    height: 30em;

    -moz-column-width: 240px;
    -webkit-column-width: 240px;
    column-width: 240px;

    -moz-column-gap: 10px;
    -webkit-column-gap: 10px;
    column-gap: 10px;
}

现在我们将为#content 设置left CSS 属性以在页面之间切换,以-250px 的倍数为单位。

我们只需要计算出我们的内容占用了多少列,我们就可以进行分页。 How to get css3 multi-column count in Javascript 给出提示:我们将从#endMarker 的左侧位置找到它。

这是一个工作示例http://lateral.co.za/pages.html,其中包含 Moby Dick 的第一章。它适用于 Chrome 和 Android,但不适用于 Firefox - 我认为是因为 CSS 列实现的差异。由于我们这里对Android感兴趣,所以代码很好。

重要的部分是:

  1. CSS 设置如上。
  2. 在内容后添加&lt;span id="endMarker"&gt;&lt;/span&gt;(但在#content div 内)
  3. #container 之外添加了#previous#next 按钮以及#page 范围。
  4. jQuery 加载后的这个 javascript:

    var _column = 0;
    var _columnCount = 0;
    var _columnWidth = 240;
    var _columnGap = 10;
    $(function() {
        _columnCount = Math.floor($('#endMarker').position().left/(_columnWidth + _columnGap));
    
        setColumn = function(i) {
            _column = i;
            document.getElementById('content').style.left = -1 * _column * (_columnWidth + _columnGap);
            $('#page').html('Page ' + (_column+1) + ' of ' + (_columnCount+1));
        }
        $('#next').click(function() {
            if (_column==_columnCount) return;
            setColumn(_column+1);
        });
        $('#previous').click(function() {
            if (0==_column) return;
            setColumn(_column-1);
        });
        setColumn(0);
    });
    

就是这样。

还有工作空间。有人可能想考虑一下列数的计算,我有点从引用的 SO 帖子中吸取了它,但实际上并没有考虑过......容器的宽度似乎会影响内容的列宽,这对我来说并不完全有意义。

但至少在无需进行任何 HTML 解析和自己的布局的情况下,一切似乎都可以正常工作,至少在 Chrome 和 Android 中是这样。

【讨论】:

  • 这真的很好,但是如何设置宽度和高度来填充窗口?使用width:$( window ).width(); 而不是width: 240px; 和其他列宽不起作用。
  • 应该足以让容器填满窗口。或使用width: 100%;width: 100vw;
  • 好的,但是如果我将它们设置为 100%,那么 -moz-column-width: 240px; -webkit-column-width: 240px; column-width: 240px; 只显示第一列。 height 怎么样,我想同时填写 heightwidth
【解决方案2】:

你必须解析 HTML,最好是使用一些库,你可以像在 JavaScript 中那样访问 DOM。然后,您可以为解析的内容创建自定义布局。 WebView 是否支持 JavaScript?这将是一个很好的尝试。

显然你不能在 HTML 文件的任意位置分割,你必须考虑 HTML-Tags。修改 DOM 或拆分 html 后,您可以为内容提供自定义 CSS 文件,以您喜欢的方式显示它,并使用您的库或 JavaScript 添加一些分页。

使用&lt;span style="display:none"&gt;&lt;/span&gt; 可以帮助您隐藏网站中的内容。那你就不用物理拆分了(反正加载页面后就在内存中了)。

希望能有所帮助。你不会在这里得到一个完整的解决方案,但也许你有一些想法。如果您发现更具体的问题,提出更具体的问题会更容易。

【讨论】:

  • 感谢您的回复。使用 Jericho html 解析器,我解析了 html 并提取了文本内容和图像,然后我设置了一个自定义布局,顶部是 imageview,下面是 textview。如果有图像,我将其设置为图像视图,否则我的文本视图适合屏幕。
  • 使用 textview.getPaint().measureText(txt) 我正在获取要显示的文本的宽度。我们如何计算字符数或适合屏幕的文本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多