Reminder - Digital Publishing Suite (DPS) will End of Life on August 31st, 2019. 
Prerequisite knowledge
User level: Intermediate
Required products (retail)

Note: If you have questions about this article, use the DPS forum. Please don’t contact technical support with questions about Adobe Developer Connection articles.

While developing our app there were not a lot of ready made resources to help me with this new technology. I hope this article saves you the time I spent developing these habits to save time. I expect that you’ve already read through Introduction to Adobe Experience Manger Media Publisher and DPS. If not please check it out first as it provides some practical examples on how to make real world magazines with AEM.

Understanding how the DPS Viewer Shell handles HTML articles

For the purpose of this article, the DPS Viewer Shell is the native application that handles the library, downloads, and displays your Issue and corresponding articles inside it. This could either be the Adobe Content Viewer application, a custom branded Single-Folio application or a Multi-Folio application that you created. If this sounds confusing, you can head over to the DPS getting started guide [ ]
The Three Card Deck
When we created we had to think about how users would get from one article to another. Let’s say we have 6 articles in our first issue. Let’s just call these Articles 1 to 6 in numerical order from start to finish, to help describe what happens when you load an HTML ONLY article and the processes that kick off.
Step 1 – You launch the article for the first time.
Step 1 – You launch the article for the first time.
Figure 1.
Step 1.1 – As shown in the above diagram, Article 1 enclosed in the green box indicates the current article in view. This article loads, and, any functions that you have in this HTML setup to be dispatched on load get called (For example: body onload, jQuery ready functions, etc ).
Step 1.2 – Article 2 enclosed in the red box indicates the next up article. This article also gets loaded, moments (less than 50 milliseconds) after Article 1. This includes the same ready/loaded functions getting called. This is an important note: this code executes even though the article is not currently in view.
After several hours of searching, I came across an article with a small reference to two custom properties that are added to the window element; window.onAppear and window.onDisappear. These two properties get called when the article comes into view and out of view, respectively. These are immensely important for those things you want to prevent from triggering until the article loads, or even – an animation for example – you want to replay whenever the article comes into view.
Step 2 – You swipe horizontally from Article 1 to Article 2.
Step 2 – You swipe horizontally from Article 1 to Article 2.
Figure 2.
Step 2.1 – The DPS Viewer Shell moves Article 2 into view (indicated by the green box in the diagram). This article has already been loaded and any on load JavaScript has already been called as indicated in Step 1.2.
Step 2.2 - Article 1 moves out of view, but does not get unloaded. Article 1, enclosed in the blue box in the diagram, is still loaded in memory in the DPS Viewer Shell. If you have modified this article through JavaScript or have any code (a timer, setTimeout, setInterval, etc.) still running in this article it will continue to execute. If, for example, you have a timer on Article 1 that started when the article loaded and is expected to change the current article in view to Article 4, the code will execute (as long as it stays within one of the blue, green, or red box as described in the diagram). This can obviously start to cause some problems. Given the current situation where Article 1 is not the current article in view (in the green box in the diagrams) and the code to change the current article in view to Article 4 executes, you will find yourself in a strange position. The user could be looking at a different article and then immediately have their view change. The obvious question here is why not just check to see what is currently in view? – I will answer this later in Things that work, things that don’t work, and things that need work section of this article.
Step 2.3 – Article 3 gets loaded as the next up article (the red box in the diagram) following the same rules as described to Article 2 in Step 1.2.     
Step 3 – You swipe horizontally from Article 2 to Article 3
Step 3 – You swipe horizontally from Article 2 to Article 3
Figure 3.
Step 3.1 – Article 2 goes out of view and into the blue box where it is still in memory, but just out of view and Article 4 gets queued up as the next article. The same explanation of what happened in Steps 1 and 2, happens here.
Step 3.2 – Article 1 goes from the blue box and being still in memory but just out of view to being removed from memory. This, as you can imagine, means that any delayed code still pending or anything that had changed in the article is lost.
Step 4 – You swipe horizontally from Article 3 back to Article 2
Step 4 – You swipe horizontally from Article 3 back to Article 2
Figure 4.
Step 4.1 – Article 3 goes from being in view to being the next up article. However, in this case, the next up article has already been loaded, since it just came from being in view, it just remains in the current state that it was just in. Article 2 comes back into view in the same state it was left in, since it never left one of the three boxes of being in memory, but out of view or in view.
Step 4.2 - Article 4 now leaves one of the three boxes and is unloaded from memory.
Step 4.3 – Article 1 re-enters the blue box from being out of all the boxes, which causes it to be reloaded into memory. The same thing applies as if it was being loaded into the red box which means the article gets loaded in the same manner as the next up article. All the onload/ready functions get called, the article comes into view with a fresh state.
I covered most of the common things you are going to run into here. The navigation examples are quite simple, but I wanted to highlight what I call the Three Card Deck of the blue, green, and red boxes. At any given time in your magazine, you will pretty much just have these three as your options as to what state your articles are in. The two main takeaways are:
  1. Timer/Interval code will still execute if the article does not get unloaded.
  2. Once your article enters one of the boxes, anything that you have that is supposed to run once the article is loaded, will be run. It does not matter if this is in view or not.
Figure 5.

Figure 5.


Things that work, things that don’t work, and things that need work

I am going to cover my experiences through trial and error or by in some cases random coincidence with what works or does not. The BIG DISCLAIMER here is that I have tested most of these ONLY on iOS and subsequently the iOS web view. These are not guaranteed to be the same on Android.
CSS Transforms and Transitions, Canvas
For CSS Transforms and Transitions, most of the things I have tried do work and work rather well.
I use CSS transitions/transforms pretty much exclusively for any animations and have found that these work very well. The performance is what you would expect and you can follow  the same guidelines as developing for the web in terms of what works and what does not.
Also, webkitRequestAnimationFrame or whatever vendor prefixed version works as well and can really help to boost custom animation performance. You can combine this with the Canvas element, which I have tested by using the basic drawing API associated with it, to achieve some neat animations.
I have not tried WebGL, but if I had to take a guess I would say there is a chance it will work.
Video HTML Element
I have had mixed results using the HTML <video> tag. iOS supports it and videos can be played with it rather nicely, however, since this tag is originally designed to be used in the ‘Web’ world there are some security restrictions associated with it. On any cellular enabled device on iOS the <video> tag requires human interactions to play. You cannot just auto play it, which makes sense. When you bring this over to HTML powered applications, such as what we are dealing with in articles written in HTML, there is an option to override this forced human interaction if the video is locally included. However, the option to override this is set on the instance of the UIWebView (at least in the iOS), which is configured on the native application. At the time of this article I have not been able to confirm if this property is turned on, which results in a sub-optimal <video> tag support.
However that does not mean video does not work. The DPS Viewer Shell supports a multitude of playing videos locally or streaming videos. For more information, see URL schemes here:
HTML Body Resizing and Controlling the Scrollbar
One of the intersting things that I had to learn the hard way was some quirkyness of how the body element resizes. Let me explain this with a simple example:
Given the situation where you load an article that, when loaded, ends up 1000px in height. Now, in your article, you have a button that says Load More and an additional 500px of information is appended to body element when it is tapped. The body element should now have a total height of 1500px. Sounds simple, right?
I do not know where the quirkyness of this problem resides, but if you append anything that should adjust the body height, it will not work. The scroll bars will still only scroll to 1000px in height and you will be stuck with the additional 500px of information that you loaded being out of view.
The only solution I have found for this so far, is to identify articles that will be affected by this and wrap the article in a scroll-wrapper. A scroll-wrapper is a <div> element that has a static height/width that matches the resolution of the device and has the overflow-y set to scroll.
This approach also solves a problem with programmatically controlling the scrollbar. In our app we wanted a back to the top button at the end of the article. Again, sounds simple enough; animate the scrollbar back to the top. However, if you try to programmatically alter the scrollTop property of the body element it will scroll the content but not the actual bar. If you touched or tried to scroll after using the back to top button, it would reset the scrollbar to whatever the last position it was in, resulting in a really weird experience.
Programmatically altering the scrollTop of the scroll-wrapper results in the correct experience. Setting scrollTop to 0 and then scrolling normally works as expected.
Make your tap and swipes responsive and prevent the DPS native menu
There are three things here. First off, do not use click events for interaction. Out of the box, listening for click events in your JS/HTML will result in a slight delay between your touch and the action. This gives a really poor user experience and will result in your users getting frustrated and/or crying.
If you do not want to use an external library, then consider using the touchstart, touchend and so on set of events rather than click events.
If you do not already have a preferred touch library here are some that I have found to be pretty useful:
Secondly, the native DPS library overlay, the one that shows up when you tap on an article,  is a wonderful way to navigate throughout your magazine, but sometimes it comes up when it is not required.
The definite way to prevent this menu from appearing is to catch the event, then call both event.preventDefault() and return false. Something like following function on containers will disable the DPS library overlay from appearing:
$(‘.bottom-bar’).on(‘touchstart’, function(event) { event.preventDefault(); return false; });
If this was something I actually wanted to interact with (for example, a Load More button) then I would do something like:
$(‘#myButton’).on(‘touchstart’,function(event) { //do whatever here event.preventDefault(); return false; }
Third and finally, the navigation paradigm that the DPS Viewer Shell provides is that horizontal swipes navigate you from article to article. By using the same concepts above, you can prevent this from happening further. Please, be careful with this though, there has been a de facto standard for magazine navigation established with horizontal swipes for navigating between articles. Insert classic Spider-man quote here.
I am not 100% sure on the specifics, but I have had success in the past from simply adding listeners for the various touchstart, touchend, and click events onto the body element, then squelching these via the preventDefault/return false combination.
This approach comes in handy and you can start doing neat things with this approach, for example, you could build out a horizontal carousel component that is controlled by swiping horizontally. At the end of carousel, you could add logic to stop preventing default on the function and allow the DPS Viewer Shell to take over navigation to the next article.

Where to go from here

It is time to go out and start building your own magazines! If it isn’t mentioned here, that doesn’t mean it doesn’t work.

Comments are currently closed as we migrate to a new commenting system. In the interim, please provide any feedback using our feedback form. Thank you for your patience.