如何将HTML文件的内容以屏幕大小的块分割为WebKit浏览器中的“分页”?HTML书样分页
每个“页面”应显示完整的文本量。这意味着在屏幕的顶部或底部边框中不得将一行文本切成两半。
编辑
这个问题最初是标记的“Android”作为我的意图是建立一个Android的ePub阅读器。然而,似乎该解决方案只能通过JavaScript和CSS实现,因此我扩大了问题的范围,使其与平台无关。
如何将HTML文件的内容以屏幕大小的块分割为WebKit浏览器中的“分页”?HTML书样分页
每个“页面”应显示完整的文本量。这意味着在屏幕的顶部或底部边框中不得将一行文本切成两半。
编辑
这个问题最初是标记的“Android”作为我的意图是建立一个Android的ePub阅读器。然而,似乎该解决方案只能通过JavaScript和CSS实现,因此我扩大了问题的范围,使其与平台无关。
建立在丹的答案在这里是我对这个问题的解决方案,我一直在努力,直到现在。 (这个JS iOS上的Webkit的作品,为Android没有保证,但请让我知道结果)
var desiredHeight;
var desiredWidth;
var bodyID = document.getElementsByTagName('body')[0];
totalHeight = bodyID.offsetHeight;
pageCount = Math.floor(totalHeight/desiredHeight) + 1;
bodyID.style.padding = 10; //(optional) prevents clipped letters around the edges
bodyID.style.width = desiredWidth * pageCount;
bodyID.style.height = desiredHeight;
bodyID.style.WebkitColumnCount = pageCount;
希望这有助于...
你能指导我如何在webview中实现这个吗?或者你可以发布整个代码吗?提前致谢。 – 2012-08-28 11:19:53
您可以将页面拆分为单独的XHTML文件并将它们存储在一个文件夹中。例如:page01,page02。然后,您可以将这些页面逐一呈现在彼此之下。
我怎么知道在哪里分割屏幕和字体大小? – hpique 2010-09-03 13:25:56
从经验来看,即使对于一个准系统的观察者,也期望能够投入大量时间。 ePub读者实际上是我开始学习C#时首先承担的大型项目,但ePub标准肯定非常复杂。
您可以找到最新版规范对于EPUB这里: http://www.idpf.org/specs.htm 其中包括OPS(开放出版物结构),OPF(开放包装格式),以及OCF(OEBPS容器格式)。
而且,如果它可以帮助你在所有的,这里是该项目的C#源代码的链接,我开始上:
https://www.dropbox.com/sh/50kxcr29831t854/MDITIklW3I/ePub%20Test.zip
它不充实可言;我几个月都没有玩过这个游戏,但是如果我没有记错的话,只需将ePub粘贴到调试目录中,然后在运行程序时只需输入部分名称即可(例如,在圆顶下,只需键入“dome”)并会显示该书的详细信息。
我曾经为几本书正确工作,但Google Books的任何电子书都完全破坏了它。与其他来源的书相比,他们对ePub的完全离奇实施(对我来说至少)。
无论如何,希望有一些在那里的结构代码可以帮助你!
+1分享你的经验和代码 – hpique 2010-09-03 15:59:49
我最近尝试了类似的东西,并添加了一些CSS样式来将布局更改为水平而不是垂直。这给了我想要的效果,而无需以任何方式修改Epub的内容。
此代码应该工作。
mWebView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// Column Count is just the number of 'screens' of text. Add one for partial 'screens'
int columnCount = Math.floor(view.getHeight()/view.getWidth())+1;
// Must be expressed as a percentage. If not set then the WebView will not stretch to give the desired effect.
int columnWidth = columnCount * 100;
String js = "var d = document.getElementsByTagName('body')[0];" +
"d.style.WebkitColumnCount=" + columnCount + ";" +
"d.style.WebkitColumnWidth='" + columnWidth + "%';";
mWebView.loadUrl("javascript:(function(){" + js + "})()");
}
});
mWebView.loadUrl("file:///android_asset/chapter.xml");
所以,基本上你是注入JavaScript来改变加载章节后的body元素的样式(非常重要)。这种方法唯一的缺点是当内容中的图像计算列数歪斜时。尽管如此,修复应该不会太难。我的尝试是注入一些JavaScript来将宽度和高度属性添加到DOM中没有任何图像的所有图像。
希望它有帮助。
-Dan
也许它会工作使用XSL-FO。这对于移动设备来说似乎很沉重,也许它太过分了,但它应该可以工作,而且你不必执行好分页的复杂性(例如,你如何确保每个屏幕不会将文本减半) 。
的基本思路是:
我不知道是否有一款适用于Android的XSL-FO处理器。你可以试试Apache FOP。 RenderX(XSL-FO处理器)具有paged-HTML output option的优势,但我不知道它是否可以在Android上运行。
你可以看一下http://www.litres.ru/static/OR/or.html?data=/static/trials/00/42/47/00424722.gur.html&art=424722&user=0&trial=1但代码可以大量混淆,所以只需使用Firebug来检查DOM。
如果链接不工作,评论 - 会给你修复。
有几种方法可以完成。如果每行都在自己的元素中,您只需检查其中一条边是否超出视图(浏览器或“书页”)。
如果您想知道将会提前多少个“页面”,只需暂时将它们移动到视图中并获取页面结束的内容。这可能会很慢,因为浏览器需要重新排列页面才能知道任何内容。
否则,我认为您可以使用HTML5 canvas元素来测量文本和/或绘制文本。
在这里的一些信息: https://developer.mozilla.org/en/Drawing_text_using_a_canvas http://uupaa-js-spinoff.googlecode.com/svn/trunk/uupaa-excanvas.js/demo/8_2_canvas_measureText.html
我已经过编写这样的事情,我的(工作)的解决方案是这样的:
你必须将这些线将webview ...
webView_.getSettings().setUseWideViewPort(true);
webView_.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
此外,你必须注入一些JavaScript。我的活动规模和webview中呈现的内容有很多问题,所以我的解决方案不会从“外部”获取任何价值。
webView_.setWebViewClient(new WebViewClient(){
public void onPageFinished(WebView view, String url) {
injectJavascript();
}
});
[...]
public void injectJavascript() {
String js = "javascript:function initialize() { " +
"var d = document.getElementsByTagName('body')[0];" +
"var ourH = window.innerHeight; " +
"var ourW = window.innerWidth; " +
"var fullH = d.offsetHeight; " +
"var pageCount = Math.floor(fullH/ourH)+1;" +
"var currentPage = 0; " +
"var newW = pageCount*ourW; " +
"d.style.height = ourH+'px';" +
"d.style.width = newW+'px';" +
"d.style.webkitColumnGap = '2px'; " +
"d.style.margin = 0; " +
"d.style.webkitColumnCount = pageCount;" +
"}";
webView_.loadUrl(js);
webView_.loadUrl("javascript:initialize()");
}
享受:)
最近有同样的问题和答案的启发发现使用CSS3的栏柱*属性的纯CSS解决方案:
/* CSS */
.chapter {
width: 600px;
padding: 60px 10px;
-webkit-column-gap: 40px;
-webkit-column-width: 150px;
-webkit-column-count: 2;
height:400px;
}
/* HTML */
<div class="chapter">
your long lorem ipsum arbitrary HTML
</div>
上面的例子给出了很大的成绩在视网膜iPhone上。使用不同的属性来产生页面之间的不同间距等。
如果您需要支持,例如多个章节这就需要开始新的页面,有一个Xcode 5例子在github:https://github.com/dmrschmidt/ios_uiwebview_pagination
我是能够提高Nacho's解决方案,使用的WebView水平刷卡分页效果。您可以找到解决方案here和示例code。
编辑:
解决方案的代码。
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
wv = (HorizontalWebView) findViewById(R.id.web_view);
wv.getSettings().setJavaScriptEnabled(true);
wv.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
injectJavascript();
}
});
wv.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
int pageCount = Integer.parseInt(message);
wv.setPageCount(pageCount);
result.confirm();
return true;
}
});
wv.loadUrl("file:///android_asset/ch03.html"); // now it will not fail here
}
private void injectJavascript() {
String js = "function initialize(){\n" +
" var d = document.getElementsByTagName('body')[0];\n" +
" var ourH = window.innerHeight;\n" +
" var ourW = window.innerWidth;\n" +
" var fullH = d.offsetHeight;\n" +
" var pageCount = Math.floor(fullH/ourH)+1;\n" +
" var currentPage = 0;\n" +
" var newW = pageCount*ourW;\n" +
" d.style.height = ourH+'px';\n" +
" d.style.width = newW+'px';\n" +
" d.style.margin = 0;\n" +
" d.style.webkitColumnCount = pageCount;\n" +
" return pageCount;\n" +
"}";
wv.loadUrl("javascript:" + js);
wv.loadUrl("javascript:alert(initialize())");
}
在我WebChromeClient的onJsAlert让我传递给定制HorizontalWebView实现分页效果水平的页数
HorizontalWebView.java
public class HorizontalWebView extends WebView {
private float x1 = -1;
private int pageCount = 0;
public HorizontalWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x1 = event.getX();
break;
case MotionEvent.ACTION_UP:
float x2 = event.getX();
float deltaX = x2 - x1;
if (Math.abs(deltaX) > 100) {
// Left to Right swipe action
if (x2 > x1) {
turnPageLeft();
return true;
}
// Right to left swipe action
else {
turnPageRight();
return true;
}
}
break;
}
return true;
}
private int current_x = 0;
private void turnPageLeft() {
if (getCurrentPage() > 0) {
int scrollX = getPrevPagePosition();
loadAnimation(scrollX);
current_x = scrollX;
scrollTo(scrollX, 0);
}
}
private int getPrevPagePosition() {
int prevPage = getCurrentPage() - 1;
return (int) Math.ceil(prevPage * this.getMeasuredWidth());
}
private void turnPageRight() {
if (getCurrentPage() < pageCount - 1) {
int scrollX = getNextPagePosition();
loadAnimation(scrollX);
current_x = scrollX;
scrollTo(scrollX, 0);
}
}
private void loadAnimation(int scrollX) {
ObjectAnimator anim = ObjectAnimator.ofInt(this, "scrollX",
current_x, scrollX);
anim.setDuration(500);
anim.setInterpolator(new LinearInterpolator());
anim.start();
}
private int getNextPagePosition() {
int nextPage = getCurrentPage() + 1;
return (int) Math.ceil(nextPage * this.getMeasuredWidth());
}
public int getCurrentPage() {
return (int) (Math.ceil((double) getScrollX()/this.getMeasuredWidth()));
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
}
“我如何在屏幕上划分XHTML文件的内容大块“分页”这本书。“ - 为什么这样做? – CommonsWare 2010-09-03 14:02:47
因为它是一种类似书本和广泛使用的方式(即:Aldiko)来呈现文本,而且这也是一个有趣的问题。 :) – hpique 2010-09-03 14:45:18
嗨,下面的解决方案之一为你工作。现在我面临像你一样的问题 - :( – DroidBot 2011-04-11 12:33:50