Search code examples
javascriptiosclickaddeventlistenertouchstart

<body> only clickable where child elements fill it


Please see my JS Fiddle on both Desktop and iPhone:

https://jsfiddle.net/5jb3x5cn/4/

I am using a click eventListener on document.body:

document.body.addEventListener('click', function(){
    alert(1);
})

I filled the background in blue, so that you can see the entire frame is being filled by the body and given it a height of 100vh.

I have inserted one child element for the iPhone.

On desktop, you will notice you get an alert regardless of where you click on the body. On the iPhone, the alert is only displayed when you click on the child element. I can only assume the child element 'fills' the body with some space, where you can click on - regardless of the height the body is set to.

Interestingly enough document.body.clientHeight returns a value which would suggest the body has a decent clickable size.

Now if you head over to: https://jsfiddle.net/5t8arze9/1/

You will notice that the entire body is clickable. Here I have used the touchstart eventListener.

Can anybody point me in the right direction?

Cheers, Dan


Solution

  • In the end, a colleague this was solved as follows:

    1. Detect iPhone via User-Agent
    2. If iPhone, then combine touchstart, touchmove and touchend eventListeners to determine whether the user just 'clicked' or actually 'swiped'/'scrolled' the screen
    3. If use clicked, open URL, if not - ignore
    4. Non iPhones get the normal click listener set

    Code:

    if (body.addEventListener) {
    
    if (navigator.userAgent.match(/iPad/i) != null) {
    
        var startX = 0;
        var startY = 0;
        var endX = 0;
        var endY = 0;
    
        body.addEventListener('touchstart', function(event) {
            startX = event.touches[0].pageX;
            startY = event.touches[0].pageY;
            endX = 0;
            endY = 0;
        }, false);
    
        body.addEventListener('touchmove', function(event) {
            endX = event.touches[0].pageX - startX;
            endY = event.touches[0].pageY - startY;
        }, false);
    
        body.addEventListener('touchend', function(event) {
            if (!endX && !endY) {
                wallpaperClick(event);
            }
            startX = 0;
            startY = 0;
        }, false);
    
    } else {
        body.addEventListener("click", function(event) {
            wallpaperClick(event);
        }, !1);
    }
    
    } else {
        body.attachEvent("onclick", function(event) {
            wallpaperClick(event);
        });
    }
    

    This however unfortunately does not quite answer why. This is somewhat vaguely explained here:

    https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile