InDesign FXLs: prevent UI from displaying with touches
If you’ve been playing around with InDesign’s FXL export, you know it allows for a huge amount of interactivity with almost no hand coding.
There’s just one thing they missed in the export option. When you tap on an element to trigger an interactive in iBooks on iOS and Kobo tablets, it often triggers the reader Chrome.
You could argue that’s expected behavior, but it creates a sub-optimal reader experience. The great news is that it’s super easy to fix. Let’s dig in.
Setup
The first thing you’ll want to do is unzip your EPUB file. Yes, we’ll need to write some code, but I promise to make it quick and painless.
Next, navigate to your EPUB folder, then navigate to “OEBPS,” then “script,” and finally the file named “idGeneratedScript.js.” Open this file in a text editor like Dreamweaver or BBEdit.
Javascript
If you’ve never written Javascript before, don’t freak out! Javascript controls all of the interactivity in ebooks, and while it looks like a crazy jumble of code the lines we’ll be adding will be very, very easy to add.
Adobe’s export actually creates Javascript that—even for a seasoned script writer like myself—is a bit murky. But the magic happens here:
function onMouseUp(element, event) { var is_touch_device = 'ontouchstart' in document.documentElement; if (is_touch_device) return; removeClass(element, '_idGenStateClick'); var actions = element.getAttribute("data-releaseactions"); if(actions) { eval(actions); } event.stopPropagation(); }
I won’t go into too much detail here, but this function handles all the code for when a mouse or finger move “up” on an element in your ebook. All we need to do is add one line of code to this function to fix the UI Chrome issue.
function onMouseUp(element, event) { event.preventDefault(); var is_touch_device = 'ontouchstart' in document.documentElement; if (is_touch_device) return; removeClass(element, '_idGenStateClick'); var actions = element.getAttribute("data-releaseactions"); if(actions) { eval(actions); } event.stopPropagation(); }
We added event.preventDefault();
right below the first line of the function. This tells the device “don’t do anything you would normally do when a screen is touched!” Really, that’s all it says. (For the more technical folks out there, you can read this for more info.)
To be safe, we should add this to every function in that js file.
Do a search for:
, event) {
and replace that with:
, event) { event.preventDefault();
(Thanks to Anne-Marie for the better find/replace code than I had previously included here)
Note: this find and replace may not be perfect—I haven’t looked at enough InDesign script files to be sure this will work 100% of the time. If you run into issues, it may be safe to just search for “event” and make sure any function that uses an event paramater (i.e. is inside the parentheses) includes event.preventDefault();
Finally, save the file and zip your EPUB back up and test on your devices. You should no longer have the Chrome appear when you interact.
Caveats and Warnings
I’d like to note that this post is about fixing this particular issue, but care should be taken to overusing this—or using it in the wrong place on a page. As Naomi Kennedy and Anne-Marie point out, overusing these features or using them too close to page margins can have negative affects.
@ePubSecrets Add a warning not to apply it to things near the edge of the page or cover the whole page? could prevent page turns #eprdctn
— Naomi Kennedy (@naomikennedy) December 2, 2014
@naomikennedy @ePubSecrets best practice would be to limit touch-areas in ebooks to a safe zone (away from page turn margins) #eprdctn — AnneMarie Concepcion (@amarie) December 2, 2014
The above code samples and images come from Anne-Marie’s excellent InDesign CC Fixed Layout video series on Lynda.com. Check it out to learn even more about Fixed Layout from InDesign.
Hi Derrick,
As I say on Twitter, Very GREAT and clever solution. Now ePub fixed layout interactivities look very amazing!
Hopefully, this’ll soon be a feature that Adobe will let us switch on or off when exporting an FXL. That’s what makes CC so great.
There’s also a market here for someone clever enough to write an app that’d edit these files from a easy UI. Create one that knows out to go inside that ZIP and alter the appropriate code for any of several features we might like to change and then re-ZIP the file for us. It could stay one step ahead of Adobe with its patches.
Hi Derrick,
This is fantastic. I started the initial request on twitter yesterday. I am so glad you were able to post a solution in less than a day. Thank you!
Alon
Mike, you can open and edit the EPUB package without unzipping using BBEdit. Does not by any means give an easy UI, if ‘easy’ means no code. I’m sure Oxygen and other applications will do the same.
Hi Lindsey,
You’re right! I use and it’s very easy to do using Grep: 30 seconds! [open the .epub file, open idGeneratedScript.js file, launch the grep research, save the file, close all].
Only simply put the hands in the mud! Good luck!
Sorry! … I use oxygen XML Editor!
So… we ran some tests. We found that on the page with the animation, we can indeed prevent the chrome from showing when we tap the animation. We can turn to the next page. However, we cannot get the chrome to show again on that page, no matter where we tap (and the animation is confined to one area.)
This makes this solution less than ideal. Here are some detailed notes from our coding person who ran tests changing various parts of the script file.
Be interested in a solution where the chrome does not show when animation is tapped, but you can get it to show when you tap elsewhere on the page.
CODING NOTES BEGIN HERE
#1 Sample on a two page doc with animation on page 1 and static art on page 2.
event.preventDefault(); added to single onMouseUp Function:
function onMouseUp(element, event) {
event.preventDefault();
Result: Chrome still shows on tapping animation. Can turn to next page.
#2 Sample on a two page doc with animation on page 1 and static art on page 2 (same file).
event.preventDefault(); added to all 3 MouseUp functions:
function onPageMouseUpForAnimations(element, event) {
event.preventDefault();
function onMouseUpForAnimations(element, event) {
event.preventDefault();
function onMouseUp(element, event) {
event.preventDefault();
Result: Chrome still shows on tapping animation. Can turn to next page.
#3 Sample on a two page doc with animation on page 1 and static art on page 2.
event.preventDefault(); added to all , event) { functions:
Result: Chrome does not show up on tapping animation (yay!).
HOWEVER, the chrome does not appear when tapping anywhere on that page (boo).
Can turn to next page.
Chrome appears on page two (because it contains no animation?)
Hey Diane,
I noticed this as well. I’m going to look into a solution for it, but quickly looking at the code this may be a bigger re-write than I’d like. Hold tight as I dig in a bit more.
Thanks for your meticulous notes.
Hello Derrick et al.,
Nice post!
I put the following code into a publication that just had an InDesign rectangle converted to a button, and it successfully prevented the iPad chrome from showing ONLY for that button; the rest of the pages behaved normally.
Since I’m looking for a specific class name, I suspect it would have the same effect for all buttons. Maybe this will help?
function onTouchStart(element, event) {
if (element.className == '_idGenButton') {
event.preventDefault();
}
...
Regards,
Chuck
Hi Chuck!
Not a Javascript person, just dangerous. 🙂 So I do have a question about this.
Is all this code you added, or was the
if (element.className == ‘_idGenButton’)
already in your file and you just added the
event.preventDefault();
to it?
Our file uses animation where the event is “On Click (Self)” so I’m not sure where to put the
event.preventDefault();
code. We don’t have any buttons.
The “tip” needs to be such that a non-Javascript person like myself can figure out where to put the necessary code, I think.
Thanks much.
Hi Diane,
I added those three (four if you count the closing brace) lines of code myself.
If your code looks like this:
onClick(self) { …
Then it might work to put in the same code I used, i.e.:
function onClick(self) {
if (element.className == '[some classname you care about]') {
event.preventDefault();
}
. . .
It depends (I think) on where the onClick is and what it’s doing, but it wouldn’t hurt to try.
By the way, I second Lindsey’s suggestion to use BBEdit to directly open and edit the epub package; it’s much easier than unzipping and fiddling around.
If there were some way of carrying through identifiers from InDesign to the generated HTML, this stuff would be a lot easier. As it is, a button just gets wrapped in an arbitrarily-named , like “_idContainer008” — it would be nicer if I could attach a script label or use the Layers panel to name the interactive object; then I could find it in the code (or better yet write an app to search automatically).
-Chuck
Thanks, Chuck. To be continued…
I consider this a big problem. Giving FXL demos with interactivity makes me want to avoid including anything where the user touches the screen, as I find the sudden and unexpected appearance of the chrome to be really jolting.
While I’d like a resolution for this issue, now, I see a feature request brewing.
Would folks agree the necessary code should be written out automatically as a default? So that any interactive element where the user touches the screen does not enable the chrome? I see no reason to have exceptions. But I may be missing something and am curious what folks think, before I put in the request.
Thanks,
–db
hey derrick!
first of all thank you soooo much for this great tip! finally i even got it work that only if i tap my buttons and animations the ui won’t appear. if i tap somewhere else the ui will pop up as usually. for me the solution was just to put your lane here:
function onTouchStart(element, event) {
event.preventDefault();
and nowhere else! so great! this saved lot lot lot hours of work to convert an indesing document in ibook author. thank you!!
best,
ivo
Hi all,
I was just about to post a similar solution to what Ivo wrote. I have added the event.preventDefault(); to two elements – onTouchStart and onTouchEnd:
function onTouchStart(element, event) {
event.preventDefault();
function onTouchEnd(element, event) {
event.preventDefault();
And I can also confirm my button does not trigger the chrome but tapping anywhere else on the iPad screen brings the chrome as usual. I think we have a great solution now!
Thank you,
Alon
Diane: I would certainly consider it a feature request for InDesign! Heading over to that form now. And for any others who want to join in:
https://www.adobe.com/cfusion/mmform/index.cfm?name=wishform&loc=en
Hi guys,
The code indeed works for buttons, great. One small issue, however, is that after you tap the button, then tap to get the chrome, the chrome never goes away again. It should, I think, disappear after a few seconds.
But this does not solve our problem. There is another case where you tap the screen for animations, namely, when the event is set to “On Click (Self)” This is what we were trying to solve in reporting earlier.
Any of you big javascript heads have a solution for this one?
Thanks,
–Diane
Hi, once the NAV has been disabled is there code or a way to introduce an EXIT to ibooks library button in epub 3??
Folks might want to read Nous avons cassé le fixed-layout for a case study of Type on Screen by Ellen Lupton (Princeton Architectural Press). The pub. has, among other infelicities, semi-functional pop-ups that magnify the text but are persistent.
Is there now a preferred method for the above? I have tried them all with varying amounts of success. I have MSOs that change with touch buttons, as I move along the buttons (showing different steps) on the iPad sometimes the Chrome shows, sometimes it doesn’t. Also looking at the same EPUB on an iPhone just can’t get anything to work, very annoyingly the Chrome shows on every tap and you can’t move to the next button (step) until the Chrome goes away. At the moment this is making my FXL EPUB not great. Any solution would be appreciated. As someone commented this appears to be real problem.
Hi Pete,
With the solution I posted above I have no issues controlling the chrome. It does not appear when I tap on buttons, on any iOS device. Make sure you edit the javascript and zip up your EPUB, then test again. I am not sure why it doesn’t work for you, perhaps your button code is different and it doesn’t exactly apply.
Good luck,
Alon
Hi Alon
Yes yours is the solution I have gone for, it is working but just not as perfectly as I would like. I suspect that coming over from DPS SE to FXL I am expecting a bit too much! Hopefully if Adobe want to promote the use of FXL this is the type of issue they will sort out.
Thanks
Pete
Hi Pete & Alon,
I’d be curious to know exactly what version of iOS each of you are on. I think there have been Javascript changes/updates to iBooks with each version. We had something squirrelly go on with our iOS8 device that was fine on our iOS7 device, though I can’t reproduce it at the moment. But was just wondering if that could explain the uneven results that Pete is experiencing.
I also suspect the complexity of pages may come into play, our tests thus far have been fairly simple.
Thanks,
–Diane
For those interested, this seems to work to suppress the chrome with On Click (Self) animations, where the if statement is added. (Courtesy of Chuck Weger) Be curious if this works for folks, it would be nice to find a solution for this, and buttons, that can be used across all cases:
}
function onTouchEndForAnimations(element, event) {
if (element.className.indexOf(‘_idGenAnimation’) >= 0) { // one of our OnClickSelf objects
event.preventDefault();
}
Hi Diane,
I have been testing on a few iPads and an iPhone – all using iOS 8. My first iBook using Indesign FXL is out and works perfectly after using the JS script changes. It’s here if you are curious: https://itunes.apple.com/us/book/continuum/id950929159?ls=1&mt=11
All the best,
Alon
Hi Alon and Diane
I also published the project I was working on to the iBooks Store , given that Alon’s button solution was the best I could find. Please note that this was a successful DPS SE project that I quickly converted to a FXL EPUB, if I was starting from scratch I would probably design the button, step-by-step sequences differently. I am working on IOS 8. The EPUB can be found by searching the iBooks Store for ‘Fishing Knots’ and is titled ‘The eBook Guide to Fishing Knots’. Test the step-by-step buttons and see how they work for you.
Hi Lindsey, I wonder if you can help please? I’ve downloaded a trial of BBEdit to save on un-zipping and zipping the ePub. Looks perfect initially – but when I go to save the newly created .js file it wants me to navigate to a folder. So, as I’ve not unzipped the ePub I don’t have a folder to save back to. Are you able to advise on how I can save the new .js file please?
Thank you! Catherine – also looking at how to disable the Chrome. Sadly I’ve tried Alon’s and Diane’s code, and I haven’t had any joy yet. But I am new to this coming from DPS SE. I really hope Adobe can build this in to the export function!
Any feedback at all from Adobe, whether this will become a feature in Indesign?
Tim,
I believe this has been fixed in InDesign CC 2014.2 release.
Thanks to this forum for helping make it happen.
–db
Hi!
I do not understand how to utilize your tips given above. I end up with the same issue you had, the UI appears.
Maybe I use buttons the wrong way? I place the sound and then create a separate button. I get html-player for the sound but used the button to hide it. Is there another way to fix this?
So thankful for any help!
any news ofor this? thanks
[…] ad Anne-Marie ed al sito ePUbSecrets da cui abbiamo preso questo […]