skip to Main Content

I have large paragraphs of text in <p> nodes in epub files and i’m displaying these on a mobile screen webview using an external library.

The library allows me to flip pages to see portions of these <p> node.

I can get the currently visible node from the DOM.

But i also need to get the offset of the first character that is currently visible in that node.

For Example:

enter image description here

In the above image the visible text is small portion of the actual <p> element. I want to get the character offset (not pixel offset) of first character which is "v" in this case

Is there a way to do that?

2

Answers


  1. Chosen as BEST ANSWER

    I figured it out, the solution is caretRangeFromPoint, i get the viewport from the Android Activity (Maybe you can use the DOM viewport in other browsers) and got a range using following code:

                let range = document.caretRangeFromPoint(viewportRect.x ,viewportRect.y)
    

    From range i could get an offset using by constructing an epubcfi using epub.js (There is maybe an another way to do this but for now i'm just using an external library, I have wasted too much time on this already)

    Note: This worked for me because this method is supported for Android Webview, It is not supported for all browsers, so check before using this.


  2. I don’t know much about EPUB files, maybe there is some way to get the offset of the current displayed text. They way I’m thinking you can do it would be base js and requires the whole text and the current displayed text. Since you wrote

    I can get the currently visible node from the DOM.

    I think it’s safe to assume you have access to the text that is displayed.

    They way I thought of how to do this is to use the String.prototype.indexOf() method to find the position of this textslice in the whole text. E.g.

    // get the whole text
    const fullText = "This is a very long text. I can read it for hours and it doesnt stop there."
    
    // get the text of the current displayed node
    const nodeText = "read it for hours and it doesnt stop there."
    
    console.log("The offset of the current displayed text is " + fullText.indexOf(nodeText));
    
    // output: The offset of the current displayed text is 32
    

    Remember that there may be some way to do this with EPUB files and it’s framework already built in, I don’t know much about EPUB files. But this would be a way to find the position of a textslice inside the whole text.

    EDIT

    Just looked more into epub js libraries and their built in methods. If you are using epubjs (https://www.npmjs.com/package/epubjs) there would be a way to do this (NOT TESTED):

    // Import the EPUB.js library
    import { Book } from 'epubjs';
    
    // Create a new Book object
    const book = new Book();
    
    // Load the ePub file
    book.open('path/to/your/book.epub')
      .then(() => {
    
        // Get the current displayed content
        const displayedContent = book.renderer.doc.body.textContent;
    
        // Get the start character offset of the displayed text
        const startOffset = book.renderer.current.location.start.characterOffset;
    
        // Get the end character offset of the displayed text
        const textOffset = startOffset + displayedContent.length;
    
        console.log('Start Offset:', startOffset);
        console.log('Text Offset:', textOffset);
      })
      .catch((error) => {
        console.error('Error loading ePub:', error);
      });
    

    Maybe you’ll even find a different way, check out their docs (http://epubjs.org/documentation/0.3) or generally the documentations of the library you are using.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search