Skip to content

Impossible to handle page turn events #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
martinhbramwell opened this issue Dec 22, 2020 · 10 comments
Open

Impossible to handle page turn events #10

martinhbramwell opened this issue Dec 22, 2020 · 10 comments
Assignees

Comments

@martinhbramwell
Copy link

I have place the following JS code on each page, from the cover page through to page 13, with incrementing numbers for each respective page:

window.addEventListener('load', (event) => {
  console.log('Page 1 loaded');
});

window.addEventListener('pagehide', (event) => {
  console.log('Page 1 gone');
});

If I click on Edit Draft of my book, the Cover page opens and the browser console shows:

Page 3 loaded
Page 5 loaded
Page 6 loaded
Page 2 loaded
Page 4 loaded
Page 1 loaded

When I turn to pgs 2 & 3, the console shows:

Page 2 loaded

to pgs 4 & 5

Page 7 loaded
Page 1 gone
Page 4 loaded

to pgs 6 & 7

Page 8 loaded
Page 2 gone
Page 3 gone
Page 6 loaded
Page 9 loaded

to pgs 8 & 9

Page 11 loaded
Page 4 gone
Page 5 gone
Page 10 loaded
Page 8 loaded

to pgs 10 & 11

Page 13 loaded
Page 12 loaded
Page 6 gone
Page 7 gone
Page 10 loaded

Question:
How can my JS code know that it's page is open so that it can run and closed so that it should stop?

@martinhbramwell
Copy link
Author

I also tried using IntersectionObserver on page 2 and on page 4

  <!-- Draggable DIV -->
  <div id="draggable2">
    <div id="mydivheader"/>
    <button class="button">Go</button>
  </div> 
var observer = new IntersectionObserver(function(entries) {
	if(entries[0].isIntersecting === true) {
		console.log('Page 2 is visible');
  } else {
		console.log('Page 2 is not visible');
  }
}, { threshold: [1] });

observer.observe(document.querySelector("#draggable2"));

... and ...

  <div id="draggable4">
    <div id="mydivheader"/>
    <button class="button">Go</button>
  </div> 
var observer = new IntersectionObserver(function(entries) {
	if(entries[0].isIntersecting === true) {
		console.log('Page 4 is visible');
  } else {
		console.log('Page 4 is not visible');
  }
}, { threshold: [1] });

observer.observe(document.querySelector("#draggable4"));

When opening to page 1, I see in the console:

Page 2 is not visible
Page 4 is not visible

Turning to page 2, 3:

Page 2 is visible
Page 2 is not visible
Page 2 is not visible

Turning to page 4,5:

Page 4 is visible
Page 4 is not visible
Page 4 is not visible
Page 2 is visible

@marvindanig
Copy link
Collaborator

marvindanig commented Dec 22, 2020

Intersection observer wouldn’t be able to keep track of the incoming or outgoing pages on the DOM. That’s useful only when the elements are scrolling and begin to intersect with the viewport when they appear above the fold.

In case of a Superbook all the pages and their sub-resources always live (and die) above the fold. So it’s always intersecting per se.

What is it that you want to do inside of a page? Does DOMContentLoaded not suffice?

@martinhbramwell
Copy link
Author

martinhbramwell commented Dec 22, 2020

Does DOMContentLoaded not suffice?

No.

I placed code like this on pages 2 through 7 of a newly created 8 page book

window.addEventListener('DOMContentLoaded', (event) => {
  console.log('Page 5 loaded');
});

When initially opening the book all six handlers fire.

When stepping forward through the book only the even numbered pages fire, except that the second to last page also fires when turning to the 4th page.

When stepping backward through the book only the odd numbered pages fire, except that the second page also fires when turning to the 5th page.

What I really need is two custom events available to both exposed pages: PageTurningBegun and PageTurningComplete.

The events should carry a detail object like this :

{
  "details":
  {
    "leftPageTitle": "The cabbage patch",
    "rightPageTitle": "The farmer"
  }
}

or some other mechanism that ensures script on each page can determine whether or not the event is pertinent, that will be unaffected by deletion or insertion of other pages.

@marvindanig
Copy link
Collaborator

How can my JS code know that its page is open so that it can run and closed so that it should stop?

The instance of bookiza.js on Bubblin will render a maximum of only six pages on the DOM at any given time. This is in landscape mode. In portrait mode, it manages with just five pages on screen.

Your page-level javascript will execute as soon as a subsequent page frame is attached into the DOM and it reifies successfully. Even when the reader cannot view the newly added pages because they are under the currentView.

What exact moment are you wanting to have the page-level custom-events fired? When the page under the current one becomes visible to the reader? if yes, then what would define differentiation between a peel-to-peek action vs. actual turn over to the left?

What are your thoughts?

@martinhbramwell
Copy link
Author

martinhbramwell commented Dec 24, 2020

My intention was to start playing a media file through an HTML5 <video> or <audio> control as soon as a user releases a turning page and to pause it as soon as they initiate a new page turn.

@marvindanig
Copy link
Collaborator

marvindanig commented Dec 24, 2020

Oh you mean autoplaying the video? I am not sure you wanna do that but I'll consider this requirement in the next build of Bookiza / Bubblin. I have used an <audio> embed on an experimental greeting card before: https://bubblin.io/book/i-love-you-by-marvin-danig/1 that autoplays, but you probably want the switch to be tied to the turned event of the incoming view.

If such an event was available, how would you have handled firing the video/audio between portrait and landscape modes? The former shows only one page on a mobile whereas the latter will display two pages on the desktop simultaneously.

Merry Christmas.

@martinhbramwell
Copy link
Author

"how would you have handled firing the video/audio between portrait and landscape modes? "

Yeah, that's a complication. Would there be a way to have a global media controller that mediates the state of every page and every media element?

@marvindanig
Copy link
Collaborator

Yes. Any javascript that you put inside the Layout Templates section of the book will be available on all the pages. How this javascript ties-up events within the context of a page or above at the spine_url level after being reified on the DOM (or not) is left entirely to the author. Exposing the state of every page on the book sounds like an interesting proposition, but it also assumes that the entire tome is available in memory at all times.

@martinhbramwell
Copy link
Author

Are there events when pages are added/removed, unambiguously, from the DOM?

@marvindanig
Copy link
Collaborator

Cue MutationObserver!

No, events for the addition and removal of pages from the DOM aren't covered on the existing API of bookiza.js. While this discussion is really helpful in finding this type of requirement, I also feel that writing an observer to watch for DOM level changes on the spine_url isn't going to be a part of this polyfill's scope. I am undecided at this point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants