显示动态html内容(如epub/ebook),而不将html转换为epub格式? [英] Display dynamic html content like an epub/ebook, without converting html to epub format?

查看:134
本文介绍了显示动态html内容(如epub/ebook),而不将html转换为epub格式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用动态html作为源,创建类似于epub/ebook阅读器(如Kindle应用程序或iBooks)的响应式,移动优化的阅读体验.

I want to create a responsive, mobile optimized reading experience similar to an epub/ebook reader, like the Kindle app, or iBooks, using dynamic html as the source.

想象一下一篇长篇文章或博客文章,需要大量垂直滚动才能阅读,尤其是在小型移动设备上.我想做的是将长页面分成多个全屏部分,从而允许用户使用向左/向右导航箭头和/或滑动手势来翻阅"文章.

Imagine a long article or blog post that requires a lot of vertical scrolling to read, especially on a small mobile device. What I would like to do is break the long page into multiple full-screen sections, allowing the user to use left/right navigation arrows and/or the swipe gesture to "page" through the article.

有许多可用的JS库可以创建预定义幻灯片(使用div或其他容器元素)的幻灯片放映"或转盘".但是我希望文本和html内容能够动态重排以适合任何设备视口,并且仍然可读...就像epub/ebook用户界面一样,例如Kindle应用程序或iBooks.因此,对于同一篇文章,手机上的页面"会比平板电脑或台式机的视口多得多,并且如果/当视口大小发生变化时,需要动态创建/调整这些页面"(例如在移动设备上从纵向切换为横向).

There are many JS libraries available that can create a "slide show" or "carrousel" of pre-defined slides (using divs or other container elements). But I want the text and html content to dynamically re-flow to fit any device viewport and still be readable... just like an epub/ebook user interface, like the Kindle app or iBooks. So, for the same article, there would be many more "pages" on a phone than there would be on a tablet or desktop viewport, and those "pages" would need to be dynamically created/adjusted if/when the viewport size changes (like switching from portrait to landscape on a mobile device).

以下是javascript .epub阅读器的示例:

Here is an example of a javascript .epub reader: epub.js

...请注意响应行为.调整视口大小时,所有文本都会重排以适合可用空间,从而增加或减少页面"的总数.问题在于epub.js需要一个.epub文件作为其源.

... notice the responsive behavior. When you resize your viewport, all the text re-flows to fit the available space, increasing or decreasing the total number of "pages". The problem is that epub.js requires an .epub file as its source.

我想要的是与html页面相同的用户界面和功能.

What I want is the same user interface and functionality for an html page.

我已经搜索并搜索了某种可以立即执行此操作的库,但是找不到任何东西.

I have searched and searched for some kind of library that can do this out of the box, but haven't been able to find anything.

我意识到我可以使用转换脚本将html页面转换为.epub文件,然后使用epub.js在浏览器中呈现该文件,但这看起来非常麻烦.模仿或模拟以html为直接来源的.epub阅读器用户体验会更好,呈现/模仿客户端响应式电子书用户体验.

I realize that I could use a conversion script to convert my html page into an .epub file, and then use epub.js to render that file within the browser, but that seems very round-about and clunky. It would be so much better to mimic or simulate the .epub reader user experience with html as the direct source, rendering/mimicking a client side responsive ebook user experience.

有人知道这样的东西是否已经存在,或者我该如何自己构建吗?

Does anyone know if something like this already exists, or how I could go about building it myself?

关键功能是动态/响应文本重排.当缩小视口尺寸时,文本/内容需要重排到下一个页面",以避免任何垂直滚动的需要.我不知道如何有效地做到这一点.如果我要自己编写代码,则可以使用jQuery Columnize插件之类的东西,将所有列设置为width: 100vw; height: 100vh,使每一列都像一个页面",然后弄清楚如何在这些页".

The crucial functionality is the dynamic/responsive text-reflow. When the viewport dimensions are reduced, the text/content needs to reflow to the next "page" to avoid any need for vertical scrolling. I don't know how to do this efficiently. If I were to code it myself, I might use something like the jQuery Columnize plugin, setting all columns to width: 100vw; height: 100vh, so that each column is like a "page", and then figuring out how to create a swipe UI between those "pages".

非常感谢您的帮助!

推荐答案

如果html页面很复杂,例如具有精确定位的元素或图像,这将变得非常困难.但是,如果内容(如epub.js示例中)仅由标题和段落组成,则可以实现.

This becomes very difficult if the html page is complex, eg with precisely positioned elements or images. However if (as in the epub.js example) the content consists only of headings and paragraphs, it is achievable.

基本思想是逐步添加内容,直到页面溢出之前.通过跟踪我们开始和停止添加内容的位置,单击到下一页就是将页面开始更改为上一页结束的情况(反之亦然).

The basic idea is to progressively add content until just before the page overflows. By keeping track of where we start and stop adding content, clicking to the next page is a case of changing the page start to the previous page end (or vice versa if you're going back).

假设您将所有内容都放在一个长字符串中.首先将所有内容拆分为单词和标签的数组.它不像按空格分割那样容易,因为应该忽略<>之间的空格(您希望在每个标签中保留类名等).另外,即使标签和单词之间没有空格,标签也应分开.

Let's assume you have all your content in one long string. Begin by splitting all the content into an array of words and tags. It's not as easy as splitting by whitespace as whitespace between < and > should be ignored (you want to keep classnames etc within each tag). Also tags should be separated as well, even if there is no whitespace between the tag and a word.

接下来,您需要一个函数来检查元素的内容是否溢出该元素. 此问题具有复制粘贴解决方案.

Next you need a function that checks if an element's contents overflow the element. This question has a copy-paste solution.

您需要两个变量pageStartpageEnd来跟踪数组中哪些索引是当前页面的开始和结束.

You need two variables, pageStart and pageEnd, to keep track of what indexes in the array are the beginning and end of the current page.

pageStart中的索引开始,将数组中的元素作为内容添加到页面,在每次添加后检查内容是否溢出.当它们确实溢出时,您将等于1的最大索引作为pageEnd的索引.

Beginning at the index in pageStart you add elements from the array as content to the page, checking after each add whether or not the contents overflow. When they do overflow you take the index you're up to, minus 1, as the index for pageEnd.

现在,如果所有的话都很好,那么这应该可以很好地填满页面.当您想转到下一页时,将新的pageStart设置为pageEnd + 1并重复该过程.但是,您可能需要修复一些问题.

Now if all's ticketyboo then this should fill the page pretty well. When you want to go to the next page set your new pageStart as pageEnd + 1 and repeat the process. However there are some issues that you may want to fix.

首先,如果页面在段落中间溢出,会发生什么?严格来说,HTML中不需要结束标记</p>,因此我们不必担心.但是下一页的开始呢?它将缺少一个开始标签,这是一个主要问题.因此,请确保我们检查页面的内容是否以标签开头,如果不是,则在当前pageStart之前获取最接近的开始标签(只需从pageStart沿数组后退)并添加放在其余内容之前.

Firstly, what happens if the page overflows in the middle of a paragraph? Strictly speaking the closing tag, </p>, is not required in HTML, so we don't need to worry about it. But what about the start of the next page? It will be missing an opening tag and that is a major problem. So we have make sure we check if the page's content begins with a tag, and if it doesn't then we get the closest opening tag prior to the current pageStart (just step back along the array from pageStart) and add it in before the rest of the content.

第二,如示例中所示,如果段落继续到下一页,则当前页面的最后一行仍然是合理的.您需要检查pageEnd是否在段落的中间,如果是,则在该段落的开头标记中添加syle="text-align-last:justify;".

Secondly, as shown in the example, if a paragraph continues onto the next page, the last line of the current page is still justified. You need to check if pageEnd is in the middle of a paragraph and if so add syle="text-align-last:justify;" to the opening tag of that paragraph.

显示所有实际操作的笔位于 https://codepen.io/anon/pen/ZMJMZZ

A pen showing all this in action is at https://codepen.io/anon/pen/ZMJMZZ

HTML页面将所有内容包含在一个长元素中.内容直接从容器#page中获取,并根据#page的大小重新划分为页面.如果段落内发生分页符,我还没有实现最后一行的对齐.在CSS中调整#page元素的大小,并查看内容如何自动调整大小-请注意,由于页面大小是固定的,因此您必须使用向前和向后单击来触发重新计算.将页面大小绑定到窗口大小后,即时重新计算页面仅涉及向调用fillPage的窗口添加一个resize事件侦听器.

The HTML page contains all content in one long element. The content is taken directly from the container #page and reformed into pages, depending on the size of #page. I have't implemented justifying the last line if a page break occurs within a paragraph. Resize the #page element in the css and see how the content resizes itself - note that since the page size is fixed you'll have to use click forward and back to trigger a recalculation. Once you bind the page size to the window size, recalculating pages on the fly simply involves adding a resize event listener to the window that calls fillPage.

毫无疑问,这里有许多错误,确实有时会显示错误的内容(例如,在页面的开头或结尾处跳过或重复单词),但这应该使您对从何处开始有了一个认识.

No doubt there are numerous bugs, indeed it will sometimes display things incorrectly (eg skipping or repeating words at the beginning or end of a page), but this should give you an idea of where to start.

这篇关于显示动态html内容(如epub/ebook),而不将html转换为epub格式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆