Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Misplaced clickable area due to class toggle / height change on touch event

There's a strange behavior on touch devices regarding the clickable area of a link, if you toggle the height of an element placed above. If you run the following snippet (e.g. save it locally and use chrome to emulate touch events), you will notice that the hash #mylink is added to the url in some cases you did not click on the red link area. And sometimes you clicked the red area, it won't be added.

E.g.

  • If you click the upper grey area (first 200px), the grey area toggles the height. => Ok.
  • If you click the enhanced, lower grey area (200px - 400px), #mylink is added to the url as if you had clicked on the red link area. => Why?
  • If you click the upper red area (first 200px, grey area minimized), #mylink is not added to the url. => Why?
  • If you click the lower red area (last 200px, grey area enhanced), #mylink is not added to the url. => Why?

<html>
<head>
	<style type="text/css">
		.test {
			background: grey;
			height: 200px;
		}

		.test.is-visible {
			height: 400px;
		}

		.link {
			height: 600px;
			display: block;
			background: red;
		}
	</style>
	<script type="text/javascript">
	  (function() {
	    window.addEventListener( 'touchstart' , function() {
	    	document.getElementsByClassName("test")[0].classList.toggle('is-visible');
	    });	
		})();
	</script>
</head>

<body>
	<div class="test">
		Click the grey area. Element enhances and minimizes itself. Now click on the lower half of the enhanced grey area (if grey = enhanced) or on the white area up to 200px below of the red area (if grey = minimized). #mylink is added to the url as if you had clicked on the red area. Why?
	</div>
	<a href="#mylink" class="link">The red area is the "normal" click area.</a>
</body>

</html>

I tried this on iOS, Android and emulated touch events in both Chrome and Firefox. They all behave the same.

If I listen to click instead of touchstart or touchend event, it works as expected.

What's the reason for this discrepancy? Why is the link area different / misplaced if I listen to touch events instead of click event?

like image 975
chaenu Avatar asked Dec 20 '16 15:12

chaenu


1 Answers

This is what happens when you enhanced the gray area and touch on the lower half:

  • When you touch the lower half of the gray area, your touchstart event is triggered
  • Your function runs and toggles (removes) the is-visible class on the gray element
  • The gray element's height becomes smaller
  • The red element moves 200px upwards
  • Your touch hasn't moved but the elements on the page have - you are now touching the red element
  • When you release your touch, the touchend event is triggered on the red element, which is the event that determines if a link was touched or not

The same thing happens when you click on the area 200px beneath the red element:

  • When you touch the area beneath the red element, your touchstart event is triggered
  • Your function runs and toggles (adds) the is-visible class on the gray element
  • The gray element's height becomes bigger
  • The red element moves 200px downwards
  • Your touch hasn't moved but the elements on the page have - you are now touching the red element
  • When you release your touch, the touchend event is triggered on the red element, which is the event that determines if a link was touched or not
like image 199
cangoektas Avatar answered Nov 03 '22 20:11

cangoektas