Make WordPress Core

Opened 6 years ago

Last modified 5 years ago

#41822 new defect (bug)

Twenty Twelve: Submenus not working on touch screen devices

Reported by: kokkieh's profile kokkieh Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.8.1
Component: Bundled Theme Keywords:
Focuses: Cc:

Description

Appears identical to #24767

When tapping on a menu item with a submenu, the submenu briefly appears but then the browser loads the link at the top menu item. Site should be viewed in Landscape orientation for the regular menu to be visible.

Confirmed on ​http://wp-themes.com/twentytwelve/ in Chrome 60 on Android 7.1.2 (Nexus 5X)

The user who reported it suspects it might be related to https://www.chromestatus.com/feature/5093566007214080

From http://en.forums.wordpress.com/topic/submenu-links-broken-on-touch-devices-chrome-56

Change History (2)

#1 @nderevj
6 years ago

I created the following workaround (it might not be the safest or most elegant):

/* Workaround for: "Twenty Twelve: Submenus not working on touch screen devices"
 * See: https://core.trac.wordpress.org/ticket/41822#ticket
 *
 * This workaround disables the click event on parent menu items (items that
 * have children) when viewed on a large screen touch device (600px+ width).
 * This allows the submenu to be displayed. Once displayed either the parent or
 * children can be clicked.
 */
jQuery(document).ready(function( $ ){
    $("#site-navigation .page_item_has_children > a").on("click", function(event){
      menuItem = $(event.target).parent();
      menuButton = $("#site-navigation button.menu-toggle");
      if(!menuItem.hasClass("focus") && menuButton.is(":hidden")){
        menuItem.addClass("focus");
      	event.preventDefault();
      }
    });
});

I added this as custom JS in WordPress.

#2 @superpoincare
5 years ago

I edited the quote slightly and this works:

Original code:

// Better focus for hidden submenu items for accessibility.
( function( $ ) {
	$( '.main-navigation' ).find( 'a' ).on( 'focus.twentytwelve blur.twentytwelve', function() {
		$( this ).parents( '.menu-item, .page_item' ).toggleClass( 'focus' );
	} );

  if ( 'ontouchstart' in window ) {
    $('body').on( 'touchstart.twentytwelve',  '.menu-item-has-children > a, .page_item_has_children > a', function( e ) {
      var el = $( this ).parent( 'li' );

      if ( ! el.hasClass( 'focus' ) ) {
        e.preventDefault();
        el.toggleClass( 'focus' );
        el.siblings( '.focus').removeClass( 'focus' );
      }
    } );
  }
} )( jQuery );

Improved code:

// Better focus for hidden submenu items for accessibility.
( function( $ ) {
	$( '.main-navigation' ).find( 'a' ).on( 'focus.twentytwelve blur.twentytwelve', function() {
		$( this ).parents( '.menu-item, .page_item' ).toggleClass( 'focus' );
	} );

	if ( 'ontouchstart' in window ) {
		$('body').find( '.menu-item-has-children > a, .page_item_has_children > a').on(  'touchstart.twentytwelve', function( e ) {
			var el = $( this ).parent( 'li' );

			if ( ! el.hasClass( 'focus' ) ) {
				e.preventDefault();
				el.toggleClass( 'focus' );
				el.siblings( '.focus' ).find( '.focus' ).addBack('.focus' ).removeClass( 'focus' );
			}
		} );
	}
} )( jQuery );

This is related the change in browsers as described here on "passive mode": https://developer.mozilla.org/en-US/docs/Web/Events/touchstart

ie instead of on-touchstart-find, I do find-on-touch. Twenty Thirteen uses the correct approach.

Also changed classes of various siblings' descendents, since a user can touch a submenu and their children and then another submenu and come back and see everything expanded, in the previous touched sub-menu. But this addition is not important. The line with $.body is important.

Note: See TracTickets for help on using tickets.