我想创建一个响应性的,移动优化的阅读体验,类似于epub/电子书阅读器,比如Kindle应用程序,或者iBooks,使用动态html作为源代码。
想象一下,一篇长篇文章或博客文章需要大量的垂直滚动才能阅读,特别是在小型移动设备上。我想要做的是将长页面分成多个全屏部分,允许用户使用左/右导航箭头和/或在文章中使用“页面”的滑动手势。
有许多JS库可以创建预定义的幻灯片的“幻灯片放映”或“旋转木马”(使用div或其他容器元素)。但是我希望文本和html内容能够动态地重新流,以适应任何设备视图,并且仍然是可读的.就像电子书用户界面一样,比如Kindle应用程序或iBooks。因此,对于同一篇文章,手机上的“页面”将比平板电脑或桌面视图上的“页面”多得多,如果/当视口大小发生变化时,需要动态创建/调整这些“页面”(比如在移动设备上从纵向切换到横向)。
下面是javascript .epub阅读器的一个示例:epub.js
..。注意你的反应行为。当您调整视图的大小时,所有的文本都会重新流以适应可用的空间,从而增加或减少“页面”的总数。问题是epub.js需要一个.epub文件作为它的源。
我想要的是相同的用户界面和html页面的功能。
我已经搜索和搜索了某种图书馆,可以做到这一点,但一直未能找到任何东西。
我意识到我可以使用一个转换脚本将我的html页面转换成一个.epub文件,然后使用epub.js在浏览器中呈现该文件,但是这看起来非常简单和笨重。用html作为直接源来模拟或模拟.epub阅读器的用户体验,呈现/模仿客户端响应性电子书用户体验会好得多。
有没有人知道这样的东西是否已经存在,或者我如何自己去建造它?
关键的功能是动态/响应的文本-再流。当视口尺寸减少时,文本/内容需要重新流到下一个“页面”,以避免任何垂直滚动的需要。我不知道如何有效地做这件事。如果我自己编写它,我可能会使用类似于jQuery列化插件的东西,将所有列设置为width: 100vw; height: 100vh,这样每一列就像一个“页面”,然后找出如何在这些“页面”之间创建一个滑动UI。
任何帮助都是非常感谢的!
发布于 2018-09-06 00:25:01
这变得非常困难,如果html页面是复杂的,如与精确定位的元素或图像。但是,如果(如epub.js示例中的)内容仅由标题和段落组成,则是可以实现的。
其基本思想是逐步添加内容,直到页面溢出。通过跟踪我们从何处开始并停止添加内容,单击下一页就是将页面开始更改为前一页结束的情况(如果要返回,则反之亦然)。
将内容重塑为页面的过程
让我们假设您的所有内容都在一个长字符串中。首先,将所有内容分割成一个单词和标签数组。<和>之间的空白应该被忽略(您希望在每个标记中保留类名等),这并不像按空格分割那样容易。标签也应该分开,即使标签和单词之间没有空格。
接下来,您需要一个函数来检查元素的内容是否溢出该元素。这个问题有一个复制粘贴解决方案.
您需要两个变量,pageStart和pageEnd,以跟踪数组中的哪些索引是当前页面的开始和结束。
从pageStart中的索引开始,将数组中的元素作为内容添加到页面中,在每个添加之后检查内容是否溢出。当它们溢出时,您可以使用您要达到的索引- 1作为pageEnd的索引。
保持跨分页标记
现在,如果所有的代码都是ticketyboo,那么这一页应该会很好地填充。当您想进入下一页时,将您的新pageStart设置为pageEnd + 1并重复该过程。但是,有一些问题您可能需要解决。
首先,如果页面在段落中间溢出会发生什么?严格地说,结束标记</p>在HTML中并不是必需的,所以我们不需要担心它。但是下一页的开头呢?这将是一个空缺标签,这是一个主要的问题。因此,我们必须确保检查页面的内容是否以标记开头,如果没有,则在当前pageStart之前得到最接近的开始标记(只需从pageStart后退一步),并在其余内容之前添加它。
第二,如示例所示,如果一个段落继续到下一页,则当前页的最后一行仍然是合理的。您需要检查pageEnd是否位于段落的中间,如果是,则将syle="text-align-last:justify;"添加到该段的开头标记中。
示例实现
一支显示这一切的钢笔在https://codepen.io/anon/pen/ZMJMZZ上。
HTML页面包含一个长元素中的所有内容。内容直接从容器#page中提取,并根据#page的大小重新转换为页面。如果在段落中出现分页符,我还没有实现为最后一行辩护的方法。调整css中的#page元素的大小,并查看内容是如何调整自身大小的--注意,由于页面大小是固定的,您必须使用单击“向前”和“后退”来触发重新计算。将页面大小绑定到窗口大小后,动态重新计算页面只需向调用fillPage的窗口添加一个调整大小的事件侦听器。
毫无疑问,有许多错误,的确,它有时会不正确地显示事物(例如在页面的开头或结尾跳过或重复单词),但这应该会让您知道从哪里开始。
发布于 2018-09-03 00:27:18
看看这在GitHub上的存储库。否则,您可以使用CSS (演示)创建一个包含多个部分的单页网站,每个部分都与视口一样高:
.section { height: 100vh; }或者通过使用JavaScript,在每个节中添加一个锚以在它们之间导航,并为每个节的文本应用一个响应单元(my 演示),以便在调整大小时对其进行适应 .就像这样:
var curr_el_index = 0;
var els_length = $(".container").length;
$(".next_section").on("click", function(e) {
curr_el_index++;
if (curr_el_index >= els_length) {
curr_el_index = 0;
}
$("html, body").animate({
scrollTop: $(".container").eq(curr_el_index).offset().top
}, 300);
return false;
});
$(".previous_section").on("click", function(e) {
curr_el_index--;
if (curr_el_index < 0) {
curr_el_index = els_length - 1;
}
$("html, body").animate({
scrollTop: $(".container").eq(curr_el_index).offset().top
}, 300);
return false;
}); * {
border: 0;
margin: 0;
padding: 0;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
body {
background-color: #1a1a1a;
}
section {
height: 100vh;
background-color: #eee;
border: 2px solid red;
font-size: 6vw;
}<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="container">Section 1 <a href="#" class="previous_section">Previous</a> <a href="#" class="next_section">Next</a></section>
<section class="container">Section 2 <a href="#" class="previous_section">Previous</a> <a href="#" class="next_section">Next</a></section>
<section class="container">Section 3 <a href="#" class="previous_section">Previous</a> <a href="#" class="next_section">Next</a></section>
<section class="container">Section 4 <a href="#" class="previous_section">Previous</a> <a href="#" class="next_section">Next</a></section>
<section class="container">Section 5 <a href="#" class="previous_section">Previous</a> <a href="#" class="next_section">Next</a></section>
编辑#1
来自我的代码的算法思想,使用相同的jQuery插件
Onscreen“标签的字符/单词数( 参考文献)list中分割整个文本,包含"Onscreen“标签中的字符/单词。section的每个元素创建一个list,用相对文本填充每个section;list的元素数给出整个文本的页数(sections)。您可以像上面那样在sections之间导航resize事件上,重做2-5算法步骤干杯
发布于 2018-09-04 16:05:42
这样做的目的是要有一个包含整个文本的div (让我们称之为div #epub_container)。然后,您将有一个具有相同大小的页面视图的div (让我们称之为#displayer),它将包含#epub_container。
#displayer将有css overflow:hidden。因此,当站点加载时,它将只显示第一个页面,因为#epub_container的其余部分将被隐藏。然后,您需要一个页面导航器来增加/减少页面编号。当页码发生变化时,我们将基于此移动#epub_container的顶部偏移量。
这是jQuery函数:
function move_to_page() {
var height = window.innerHeight;
var width = window.innerWidth;
var $displayer = $('#displayer');
var offset = $displayer.offset();
$displayer.height(height - offset.top - 5);
var $epub = $('#epub_container');
var offset_top = offset.top - $displayer.height() * m_page;
$epub.offset({top: offset_top, left: offset.left});
}编辑:在文本重新流之后调用move_to_page(),以便重新计算页面。

https://stackoverflow.com/questions/49330858
复制相似问题