Javascript/JQuery在epub中保存位置

meh*_*dok 10 html javascript css jquery

我正在尝试为android构建一个epub阅读器,每件事情都很好并按预期工作,我无法解决的问题是保存上次看到的页面(或保存书签的位置).

一点背景:

css multi column用来显示epub,columnWidth设置为windowWidthcolumnHeight设置为windowHeight. 确保每列都填满整个屏幕.

目前,为了保存位置,我预先处理 html并使用div包含id表示节号和标签位置的特定包装来包装每个元素.例如<p>,进程后的标记将是这样的:

<div id="id__1__8"><p>some text</p></div>
Run Code Online (Sandbox Code Playgroud)

id__1__8表示此文本属于部分1,它是在第八元件在该机构.

我有一个完整的这些ID列表,为了保存位置,我使用jQuery比较当前列的左边,每个左边id的最左边id都会找到,我知道这个页面属于epub中的位置.

下一步是找到偏移量(假设一个p标签填满7页).对于偏移量,我知道我必须加载第1节的第8个元素并转到第5页.

看看jQuery中的函数:(用于查找最近的元素和偏移量)

jqGetLastPosition = function(ids)
    {
        var tempColumn = _column; // _column is current page that is showing
        if(tempColumn < 0)
        {
            tempColumn = -1 * tempColumn;
        }
        var realIds = ids.split("|");
        var columnLeft = (tempColumn * (_windowWidth + _columnGap));
        var currentLeft;
        var currId = "#" + realIds[0];
        var nearestId = realIds[0] + "__0";
        var minDistance = 1000000;
        var tempDistance = 0;
        var exactColumn = 0;
        for(i=0; i<realIds.length; i++)
        {
            try
            {
                currId = "#" + realIds[i];
                currentLeft = $(currId).position().left;
                if(currentLeft < 0)
                {
                    currentLeft = -1 * currentLeft;
                }
                tempDistance = columnLeft - currentLeft;
                if(tempDistance < 0)
                {
                    //this id is after this page
                    continue;
                }
                else if(tempDistance < minDistance)
                {
                    minDistance = tempDistance;
                    exactColumn = Math.floor(minDistance/(_windowWidth + _columnGap)); //this must compute the offset pages after nearest element
                    nearestId = realIds[i] + "__" + exactColumn;
                }
            }
            catch(e)
            {
            }
        }

        jsSaveLastLocation(nearestId);
    };
Run Code Online (Sandbox Code Playgroud)

此代码适用于页面偏移为零的大多数情况,例如id__1__8__0.

当有偏移时出现问题,偏移页面无法正确计算,我可以看到有一个页面偏移,但是这个代码给了我0偏移,或者当有9页偏移时它给我4.

那么这段代码有什么问题呢?

或者我错误地这样做是为了保存位置?

有没有更好的方法?

更新:

如果我div在任何标签之前添加,例如<div id="id__1__8"></div><p>some text</p>结果将在90%的时间内准确.所以更新的问题将是如何以100%的准确度实现这一目标(在epub中保存位置)?

更新2:

我正在div为每个元素提供例如.head,p,link,img...

这是否有可能导致问题?

更新3:

我终于找到导致问题的原因了.考虑到当前页面的最近元素从上一页的中间开始的情况,我保存了这个元素的id,偏移量将是1.当我想加载保存的位置时,元素加载到顶部页面,所以文本会发生一点变化,在下面的图像中我会显示正在发生的事情.

任何想法将不胜感激

在此输入图像描述

更新4:

CSS:

#container {
    width: 100%;
    height: 98%;
    overflow: hidden;
    }
    #content {
    position: relative;
    height: 98%;
    -moz-column-width: 200px;
    -webkit-column-width: 200px;
    column-width: 200px;
    -moz-column-gap: 1px;
    -webkit-column-gap: 1px;
    column-gap: 1px;
    }
    img {
    max-width: 100%;
    max-height: 100%;
    display:inline-block;
    -webkit-column-break-inside : avoid;
    }
Run Code Online (Sandbox Code Playgroud)

<span id=\"endMarker\"></span>会加重身体的末端,所以我必须在HTML内容结束的标记.

jQuery的:

var _column = 0;
var _columnCount = 0;
var _windowWidth;
var _windowHeight;
var rtl = 0;

$(function() {
    _columnWidth = $('#container').width();
    _windowWidth = $('#container').width();
    _windowHeight = $('#container').height();
    $('#content').css('-webkit-column-width', _windowWidth);
    $('#content').css('-moz-column-width', _windowWidth);
    $('#content').css('column-width', _windowWidth);

    $(document).ready(function(){
    $(window).load(function(){
        _columnCount = Math.floor($('#endMarker').position().left/(_windowWidth + _columnGap));
        if(_columnCount < 0)
        {
            rtl = 1;
            _columnCount = (_columnCount * -1);// + 2;
            informRTL(rtl); //inform the java part that this doc is right to left
        }
        else
        {
            informRTL(rtl);
        }
        reportNumberOfPage(_columnCount); // this will report to java part
    });
    });

    setColumn = function(i) {
        if(rtl == 1)
        {
            _column = (i * -1);
        }
        else
        {
            _column = i;
        }

        $('#content').css({"-webkit-transform":"translate(" + (-1 * _column * (_windowWidth + _columnGap)) + "px,0px)"});
    }    

    setColumn(0); //set the showing column to first

    nextPage = function() {
        if (_column==_columnCount -1 || (-1*_column)==_columnCount -1)
            informEndPage();
        else
            {           
                if(rtl == 1)
                {
                    _column = _column-1;
                    $('#content').css({"-webkit-transform":"translate(" + (-1 * _column * (_windowWidth + _columnGap)) + "px,0px)"});                   
                }
                else
                {
                    _column = _column+1;
                    $('#content').css({"-webkit-transform":"translate(" + (-1 * _column * (_windowWidth + _columnGap)) + "px,0px)"});                                                   
                }           
            }           
    };

    prevPage = function() {
        if (0==_column) 
            informStartPage();
        else
            {           
                if(rtl == 1)
                {
                    _column = _column+1;                    
                    $('#content').css({"-webkit-transform":"translate(" + (-1 * _column * (_windowWidth + _columnGap)) + "px,0px)"});
                    updateCurrentPageText((_column * -1));
                }
                else
                {
                    _column = _column-1;                    
                    $('#content').css({"-webkit-transform":"translate(" + (-1 * _column * (_windowWidth + _columnGap)) + "px,0px)"});
                    updateCurrentPageText(_column);
                }                           
            }        
    };

    //this function add more html content to the end of current body
    addString = function(s)
    {
        $(s).insertBefore('#endMarker');
        $(window).load(addStringReport());
    };

    addStringReport = function()
    {
        _columnCount = Math.floor($('#endMarker').position().left/(_windowWidth + _columnGap));
        if(_columnCount == 0)
        {
            requestMorePage();
        }
        if(_columnCount < 0)
        {
            rtl = 1;
            _columnCount = (_columnCount * -1);
        }
        nextPage();
        reportNumberOfPage(_columnCount);
    }

    //this function add more html content to the first of body
    addStringToFirst = function(s)
    {
        $('#content').prepend(s);
        $(window).load(addStringToFirstReport());
    }

    addStringToFirstReport = function()
    {
        maxColumn = Math.floor($('#endMarker').position().left/(_windowWidth + _columnGap));
        if(maxColumn < 0)
        {
            rtl = 1;
            maxColumn = (maxColumn * -1);
            _column = (maxColumn - _columnCount + _column);
        }
        else
        {
            _column = maxColumn - _columnCount + _column;
        }

        _columnCount = maxColumn;
        setColumn(_column);
        reportNumberOfPage(_columnCount);
    }
Run Code Online (Sandbox Code Playgroud)

这几乎是我的所有代码,如果您需要更多,请告诉我.

Chr*_*uth 3

我想我明白你在问什么。您是否试图创建一堆都是同一个 HTML 文件的“假”页面?我创建了一个我认为你想要的工作示例。它的工作原理是location.hash在滚动时更新当前部分。当您重新加载时,它应该出现在同一部分(“假”页面)。您需要下载它才能正常运行,所以我将其放在要点中。

这是因为 Stackoverflow 和 JSFiddle 将代码放在沙箱中,location.hash无法更新。

每次您滚动到新页面时,这都会更新您的浏览器历史记录。我觉得这很烦人,所以我有 HTML5 推送状态设置。这仅适用于网络服务器,但每次您滚动到新页面时,它都会用视图中的“假”页面替换当前网址(和历史记录),因此您不会拥有无限的历史记录。我发布的代码将在您的计算机或网络服务器上本地运行,但在网络服务器上运行得更好。

要点: https://gist.github.com/Christianjuth/a4e6fad50da54818bbc3

代码:

$(document).scroll(function() {

  //get current section
  var $currentPage = $('.pages > section:onScreen').first();
  var $title = $('.pages > section:onScreen').first().find('h1').first();

  //update url
  if (history && history.pushState && location.protocol !== "file:") {
    history.pushState({}, $title.text(), "/#" + $currentPage.attr('id'));
  } else {
    location.hash = $currentPage.attr('id');
  }
});
Run Code Online (Sandbox Code Playgroud)
html,
body {
  margin: 0;
  padding: 0;
  height: 101%;
  width: 100%;
}
*,
*:before,
*:after {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
.pages {
  display: inline-block;
  width: 100%;
  height: 100%;
}
.pages > section {
  display: inline-block;
  min-height: 100%;
  padding: 10px;
  font-family: Georgia;
}
.pages > section:nth-child(even) {
  background-color: #000;
  color: #fff;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://benpickles.github.io/onScreen/jquery.onscreen.js"></script>

<div class="pages">
  <section id="html5">
    <h1>HTML5</h1>

    <p>HTML5 is a core technology markup language of the Internet used for structuring and presenting content for the World Wide Web. As of October 2014 this is the final and complete fifth revision of the HTML standard of the World Wide Web Consortium (W3C).[3]
      The previous version, HTML 4, was standardised in 1997.</p>
    <p>Its core aims have been to improve the language with support for the latest multimedia while keeping it easily readable by humans and consistently understood by computers and devices (web browsers, parsers, etc.). HTML5 is intended to subsume not
      only HTML 4, but also XHTML 1 and DOM Level 2 HTML.</p>
  </section>
  <section id="css3">
    <h1>CSS3</h1>

    <p>Cascading Style Sheets (CSS) is a style sheet language used for describing the look and formatting of a document written in a markup language. While most often used to change the style of web pages and user interfaces written in HTML and XHTML, the
      language can be applied to any kind of XML document, including plain XML, SVG and XUL. Along with HTML and JavaScript, CSS is a cornerstone technology used by most websites to create visually engaging webpages, user interfaces for web applications,
      and user interfaces for many mobile applications.</p>
  </section>
  <section id="bootstrap">
    <h1>Bootstrap</h1>

    <p>Bootstrap is a free and open-source collection of tools for creating websites and web applications. It contains HTML- and CSS-based design templates for typography, forms, buttons, navigation and other interface components, as well as optional JavaScript
      extensions. The bootstrap framework aims to ease web development.</p>
    <p>Bootstrap is a front end, that is an interface between the user and the server-side code which resides on the "back end" or server. And it is a web application framework, that is a software framework which is designed to support the development of
      dynamic websites and web applications.</p>
  </section>
</div>
Run Code Online (Sandbox Code Playgroud)