Different behaviors for the Click and Touch mouse - incorrect functionality with the touch screen, but using the mouse

Stackoverflow has helped me too much with the current version, but at present I am completely lost since I don’t know how to solve one problem. I will be very grateful for any advice.

I have a product container with options. They are displayed on the mouse: hover (performed using css). The problem is that if someone touches the mobile phone, it will trigger both events: click and mouseover. But I need different behavior for mobile devices. So I used a solution from stackoverflow where I can check if the browser knows the touchstart event. It works great until someone comes with a touch screen, but with the mouse. Thus, this user clicks on the container and the parameters appear without being redirected to the product details. But this is wrong for mouse behavior.

I need someone to click on the image, it will first display the parameters, and in the second it will redirect to the product part (another behavior is only when you click on the button that automatically redirects the user to the product part). But if someone uses a mouse, we have: a freezing effect, so even the first click on the image can redirect the user to the product details page.

The current javascript code is commented out, so there is a workaround that works great on desktop and mobile phones. But it does not work on hybrid devices with a touch screen with a mouse. The commented code is how I thought of the solution, as I added a workaround with mouseenter / mouseleave functions there. This does not work for mobile devices, as they also trigger these events. The same issue is related to touchstart / touchhend events.

Can someone help please?

/*var usedMouse = false; $('.products-grid .container:not(.over)').mouseenter(function() { usedMouse = true; });*/ $('.products-grid .container:not(.over)').tap(function(e) { if (!!('ontouchstart' in window)/* && !usedMouse*/) { // location change if already hovered or tap target is button if ($(this).hasClass('over') || $(e.target).hasClass('button')) { $(this).addClass('detail'); // add detail - disable hover effect on actual container return true; } e.preventDefault(); e.stopPropagation(); $('.products-grid .container').removeClass('over'); // remove all over effects $(this).addClass('over'); // add over effect to actual container return false; // do nothing because script made over effect } }); /*$('.products-grid .container:not(.over)').mouseleave(function() { usedMouse = false; });*/ 
 .products-grid { width: 100%; text-align: center; } .products-grid .row, .std .products-grid .row { margin: 0 0 0 -22px; text-align: left; } .products-grid .row > .leftcolumn { float: left; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; width: 33.33%; margin: 0; padding: 0 0 0 22px; } .products-grid .row .product-image { overflow: hidden; display: block; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; width: 100%; height: auto; border: 1px solid #c9d5d8; } .products-grid .row .product-image img { display: block; width: 100% !important; height: auto !important; margin: 0; } .products-grid .clear, .std .products-grid .clear { clear: both; margin: 0; } .products-grid .container { position: relative; margin: 0 0 50px; } .products-grid .options-wrapper { position: relative; overflow: hidden; width: 100%; margin: 0; padding-top: 5px; } .products-grid .parameters, .products-grid .container.detail > .options-wrapper > .parameters, .products-grid .container.detail:hover > .options-wrapper > .parameters { position: absolute; left: 0; right: 0; -webkit-transition: all 250ms linear; -moz-transition: all 250ms linear; -ms-transition: all 250ms linear; -o-transition: all 250ms linear; transition: all 250ms linear; -webkit-transform: translateX(-100%); -moz-transform: translateX(-100%); -ms-transform: translateX(-100%); -o-transform: translateX(-100%); transform: translateX(-100%); margin-top: -5px; padding-top: 66px; background: #eff9ff; } .products-grid .container:hover > .options-wrapper > .parameters, .products-grid .container.over > .options-wrapper > .parameters { -webkit-transform: translateX(0%); -moz-transform: translateX(0%); -ms-transform: translateX(0%); -o-transform: translateX(0%); transform: translateX(0%); } .products-grid .parameters .size-wrapper { height: auto; border-bottom: 0 none; } .products-grid .parameters span { overflow: hidden; float: left; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; width: 50%; height: 33px; border-bottom: 1px solid #bdccd4; padding-left: 10px; white-space: nowrap; font-size: 13px; color: #5f727c; line-height: 30px; } .products-grid .name-box, .std .products-grid .name-box { position: relative; margin: 0; } .products-grid h3, .std .products-grid h3 { overflow: hidden; height: 42px; margin: 15px 12px 18px; white-space: normal; font-size: 18px; font-weight: 700; color: #000; line-height: 21px; } .products-grid h3 a { text-decoration: none; font-weight: bold; color: #000; } .products-grid h3 a:hover { text-decoration: none; } .products-grid .description { overflow: hidden; height: 40px; margin: 0 12px 11px; font-size: 14px; font-weight: 400; color: #81929c; line-height: 20px; } .products-grid .description p { margin: 0; padding: 0; } .price_wrapper, .std .price_wrapper { margin: 0; border-top: 1px solid #bdccd4; border-bottom: 1px solid #bdccd4; padding: 9px 8px 10px; } .price_wrapper:after { content: ' '; clear: both; display: block; } .price_wrapper .addToCart { float: right; } .price_wrapper a.button { float: right; width: 136px; height: 39px; background-color: #a5c82d; text-align: center; text-decoration: none; font-size: 14px; font-weight: 700; color: #fff; line-height: 39px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js"></script> <div class="products-grid"> <div class="row"> <div class="leftcolumn"> <div class="container"> <a class="product-image" href="#"> <img src="http://dummyimage.com/316x210/eee/333333.png" alt="product name" title="Product Name"> </a> <div class="options-wrapper"> <div class="parameters"> <div class="size-wrapper"> <span class="height">Height 95.2 cm</span> <span class="width">Width 210.5 cm</span> <span class="length">Length 187.5 cm</span> <span class="color"></span> </div> </div> <div class="name-box"> <h3 class="product-name"><a href="#" title="Product Name">Product Name</a></h3> </div> <div class="description">Description</div> </div> <div class="price_wrapper"> <a class="button" href="#">Detail</a> </div> </div> </div> </div> </div> 
+6
source share
1 answer

This solution helped me solve my problem (thanks @booboos):

  // mark as mobile clicked $('.products-grid .container:not(.over)').touchstart(function() { this.mobileClick = true; }); // unmark mobile click $('.products-grid .container:not(.over)').touchmove(function() { this.mobileClick = false; }); // if mobile click is unmarked - delete mark property $('.products-grid .container:not(.over)').touchend(function() { if (this.mobileClick === false) delete this.mobileClick; }); // check if there was mobile click and create new behavior for screen taps $('.products-grid .container:not(.over)').tap(function(e) { if (typeof this.mobileClick === 'undefined') return true; e.preventDefault(); if (this.mobileClick === true) { if ($(this).hasClass('over') || $(e.target).hasClass('button')) { $(this).addClass('detail'); // add detail - disable hover effect on actual container window.location.href = $(this).find('.button').attr('href'); } $('.products-grid .container').removeClass('over'); // remove all over effects $(this).addClass('over'); // add over effect to actual container delete this.mobileClick; } }); 
  • touchstart creates the mobileClick property on the trojan element of the container.
  • touchmove will disable the property
  • touchhend event simply removes the property if the touchmove event before
  • The tap on the container checks if the mobileClick property is active on the element, and if there is one, the script will first add the class “on top” to the container element, and if the container has a class, then next time it will redirect the user to the details page. This event also removes the mobileClick property at the end. Therefore, I can be sure that next time the touch will be palpable.
0
source

All Articles