Preventing touch gestures on a web page

Why Prevent Gestures

By default, a touch-enabled device allows a user to pan and zoom a web app. But sometimes this is not something that’s appropriate for an app.

Here’s how to prevent these gestures from messing up your web app:

Prevent Panning and Zooming

1
2
3
html, body {
touch-action: none;
}

This will prevent single-finger panning, and two-finger pinch zooming on all elements. This does not, however, disable the double-tap to zoom feature. Disabling double-tap zoom requires a different method.

Prevent Double-Tap Zoom

This zoom effect can be annoying, as clicking a button twice can invoke it.

In order to prevent it, place a listener for dblclick on the element being clicked:

1
2
3
4
5
6
7
8
// gobble up the 'dblclick' event
function gobbleDblclick (ev) {
ev.preventDefault();
ev.stopPropagation();
}

// add listener to element
myelement.addEventListener('dblclick', gobbleDblclick);

Another option to disable double-tap to zoom is with CSS:

1
2
3
4
/* disable double-tap to zoom */
.no-double-tap-zoom {
touch-action: manipulation;
}

This disables double-tap to zoom, but it enables panning and pinch zoom.

Watching Web Services Using Crontab

A bare bones way to monitor your web services and restart them when necessary

There are many web hosting services that provide ways to monitor your running server and restart it when necessary. But not all of them do, and if you’re stuck like I was on a shared server with no such fancy pants watcher, you may find this simple method using common tools useful.

Step 1: Write a Watcher Script

The watcher script simply runs one time and checks if a server process is running, and if it isn’t, starts it.

In my case, I needed to manually set my $PATH variable, otherwise the cron job wouldn’t be able to run node:

1
2
3
4
# set PATH so cron job can find and execute 'node'
#
PATH="/home/ss_server/.nvm/versions/node/v14.15.0/bin:/usr/local/bin:/usr/bin:/bin:"
echo " which node: $(which node)"

The next part of the script uses the ps aux command to see if my server processes are running. If all are running, the script exits early.

In my case, I am looking for two processes: index.js and encrypt.js:

1
2
3
4
5
6
7
8
9
10
11
#
# find out if services are already running
#
echo " checking if services are already running..."
HAS_INDEX=$(ps aux|grep "index.js"|grep -v "grep"|wc -l)
HAS_ENCRYPT=$(ps aux|grep "encrypt.js"|grep -v "grep"|wc -l)
(( HAS_BOTH = $HAS_INDEX + $HAS_ENCRYPT ))
if [[ $HAS_BOTH == 2 ]]; then
echo " both services are already running, bye."
exit 0
fi

This one liner bears some explanation:

1
$(ps aux|grep "index.js"|grep -v "grep"|wc -l)

It evaluates to 1 if “index.js” is running, 0 if it’s not. (the grep -v "grep" bit is needed, because the prior grep "index.js" often shows up as a process in ps aux).

The remainder of the script simply restarts my server processes:

1
2
3
4
# using pm2, delete then restart my server processes
/home/ss_server/ss-server.terrymorse.com/pm2 delete all
/home/ss_server/ss-server.terrymorse.com/pm2 start \
/home/ss_server/ss-server.terrymorse.com/pm2-simple-server.config.js

Step 2: Add a cron job using crontab

Use crontab -e to add a cron job single line that will run my script every minute, logging stdout and stderr:

1
2
3
4
5
#
# watch the ss-server services once per minute
* * * * * /home/ss_server/watch-services.sh \
>> /home/ss_server/logs/watch-services.log \
2>>/home/ss_server/logs/watch-services.error.log

Bottom Line

With just a simple script and one cron job line, I now have a watcher that restarts my web services whenever necessary. Which is pretty important, because the shared server I’m using reboots often, but it doesn’t restart my services.

Recursively Copying Folders with Gulp

How to use Gulp to copy a directory and all of its contents

When building a site or app with Gulp, you often simply need to copy a folder and all of its contents recursively.

Doing it simply is tricky, unless you know this simple incantation:

  • put a * after the folder name (myfolder*)
  • follow that with a /**/* for recursive copy
  • total string is myfolder*/**/*
  • all done

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// recursively copy 'css', 'imgs', and 'fonts' to `dist` directory:

const gulp = require('gulp');

const SRC = 'src/';
const DIST = 'dist/';

function copyFolders () {
return gulp.src([
SRC + 'css*/**/*',
SRC + 'imgs*/**/*',
SRC + 'fonts*/**/*',
])
.pipe(gulp.dest(DIST));
}

exports.default = gulp.series(copyFolders);

The results, displayed here using tree command (another nifty tool):

1
2
3
4
5
6
7
8
9
10
11
dist
├── css
│   ├── overpass-latin.css
│   └── whereami.css
├── fonts
│   └── overpass-latin.woff
├── imgs
│   ├── california-highway-1200x1200.png
│   ├── interstate-sign-1600x1200.png
│   ├── speed-limit-1600x2000.png
│   └── us-highway-sign-1200x1200.png