Issues when reading Xaringan presentations on mobile
JavaScript to the rescue!
By Lucio Cornejo in rmarkdown
December 27, 2021
Perhaps it’s just bad luck, but I’ve encountered a couple of issues on mobile when reading Xaringan slides.
Here I’ll describe how I have dealt with those issues, mainly using JavaScript.
Quickly alternating between slides
During a mobile Xaringan presentation, if you tap the screen, the next or previous slide will show up.
However, if you tap many times, and fast, the screen usually activates a zoom.
Here is a way to disable such screen zoom when double tapping, using CSS
:
/* Disable double-tap zoom */
html { touch-action: manipulation; }
Unintended slide change due to tap
The following has occurred during a mobile Xaringan presentation:
- When I’ve scrolled through a vertically long slide, the tap to activate the scrolling activates an unintended slide change.
- When tapping an image with a link, the slide changes and the link is not opened.
The following JavaScript
code has fixed those problems in my presentations:
// Code to fix the change of slide when scrolling and when clicking some elements
let touchmoved;
$('div.remark-slide-container').on('touchend', function(event){
if(touchmoved === true) {
// Do not change slide if scrolling took place
event.preventDefault();
event.stopPropagation();
} else {
// Fix for issue when clicking an image with an anchor
if(event.target.tagName === "IMG") {
if (event.target.parentNode.getAttribute("href").includes("https:")) {
// If there was no scrolling and the user clicked on an image
// which has an anchor, then do not change slide and open
// in a next window the site linked to image touched
event.preventDefault();
event.stopPropagation();
window.open(event.target.parentNode.getAttribute("href"));
}
}
// Fix for issue when clicking the symbol of a <details><summary> ...
if (event.target.tagName === "SUMMARY") {
if(event.target.parentNode.tagName === "DETAILS") {
event.preventDefault();
event.stopPropagation();
// Manually toggle between open or closed <details>
if(event.target.parentNode.open === true) {
event.target.parentNode.open = false;
} else {
event.target.parentNode.open = true;
}
}
}
}
}).on('touchmove', function(){
touchmoved = true;
}).on('touchstart', function(){
touchmoved = false;
});
Swipe to go to previous or next slide, not working
Such functionality is available via Remark.js
, therefore, it would be expected to work with Xaringan. However, despite it being included in Xaringan presentations I’ve found online, it hasn’t worked for mine.
I’ve implemented such functionality a little bit different, because my code allows for any swipe slide change to be cancelled if the user on mobile lifts up his or her finger which triggered the tap event, near enough to where the tap initially took place.
The Xaringan presentations I’ve read on mobile do not have such swipe slide change cancel functionality.
Here is the JavaScript
code:
// Code to change between slides depending on user screen swipe
let touchstartX = 0;
let touchendX = 0;
let swiped = false;
function conditional_swipe() {
// Swiped left
if (touchendX < touchstartX) {
if ( (touchstartX - touchendX) > (screen.availWidth)*0.25 ) slideshow.gotoNextSlide();
} else {
// Swiped right, because swiped equals true
if ( (touchendX - touchstartX) > (screen.availWidth)*0.25 ) slideshow.gotoPreviousSlide();
}
}
$('div.remark-slide-container').on('touchstart', event => {
touchstartX = event.changedTouches[0].screenX;
swiped = false;
});
$('div.remark-slide-container').on('touchmove', function() { swiped = true; });
$('div.remark-slide-container').on('touchend', event => {
touchendX = event.changedTouches[0].screenX;
if (swiped === true) conditional_swipe();
});
Did you know?
Lastly, just a brief mention that many functions related to
the slides in Xaringan (for example, go to previous slide, go to next slide, get the slide’s current number, etc)
are already defined in Remark.js, so you can use them with JavaScript.
In order to see those functions, open a Xaringan presentation on
Desktop, go to the Console (ctrl+shift+i in Chrome) and type
slideshow.
, then the available functions should pop up.