Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove jQuery in the frontend for Twenty Twelve. #1683

Open
wants to merge 5 commits into
base: trunk
Choose a base branch
from
Next Next commit
Remove jQuery in the frontend for Twenty Twelve.
  • Loading branch information
felixarntz committed Sep 16, 2021
commit 8e262a783bf03d24bbf1724469b6d33bec4be0bc
2 changes: 1 addition & 1 deletion src/wp-content/themes/twentytwelve/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ function twentytwelve_scripts_styles() {
}

// Adds JavaScript for handling the navigation menu hide-and-show behavior.
wp_enqueue_script( 'twentytwelve-navigation', get_template_directory_uri() . '/js/navigation.js', array( 'jquery' ), '20141205', true );
wp_enqueue_script( 'twentytwelve-navigation', get_template_directory_uri() . '/js/navigation.js', array(), '20210916', true );

$font_url = twentytwelve_get_font_url();
if ( ! empty( $font_url ) ) {
Expand Down
85 changes: 61 additions & 24 deletions src/wp-content/themes/twentytwelve/js/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,40 @@
* accessibility for submenu items.
*/
( function() {
function getParentElements( element, selector ) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these useful enough to be moved into a package for re-use? thinking if we are encouraging the community to transition away from jQuery, covering the top use cases in packages (either distinct - or perhaps bundled into a single wp-dom package for efficiency - would make sense vs repeating the same boilerplate code in each theme.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, it would be great to have a core-provided script with useful utility functions.

Most of what jQuery offers is nowadays not necessary, but it still has a few nice functions which replicating all the time is painful. Yet, loading jQuery for those is overkill. @mtias Is a simple DOM utility functions package (e.g. wp-dom) something we could consider moving forward through Gutenberg?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The risk of a DOM utility functions package is that it ends up growing large itself, which is a concern when the current library approach isn't modular.

In the case of themes, given that generally only one of them is ever in use for a single page view, I'd argue that we should keep these functions inline, as currently done in this PR.

var parentElements = [];

while ( element.parentElement !== null ) {
if ( ! selector || element.parentElement.matches( selector ) ) {
parentElements.push( element.parentElement );
}

element = element.parentElement;
}

return parentElements;
}

function getSiblingElements( element, selector ) {
var siblingElements = [];

Array.from( element.parentElement.children ).forEach( function( sibling ) {
if ( sibling !== element && ( ! selector || sibling.matches( selector ) ) ) {
siblingElements.push( sibling );
}
} );

return siblingElements;
}

function toggleClass( element, className ) {
felixarntz marked this conversation as resolved.
Show resolved Hide resolved
if ( -1 !== element.className.indexOf( className ) ) {
element.className = element.className.replace( ' ' + className, '' );
} else {
element.className += ' ' + className;
}
}

var nav = document.getElementById( 'site-navigation' ), button, menu;
if ( ! nav ) {
return;
Expand All @@ -25,31 +59,34 @@
menu.className = 'nav-menu';
felixarntz marked this conversation as resolved.
Show resolved Hide resolved
}

if ( -1 !== button.className.indexOf( 'toggled-on' ) ) {
button.className = button.className.replace( ' toggled-on', '' );
menu.className = menu.className.replace( ' toggled-on', '' );
} else {
button.className += ' toggled-on';
menu.className += ' toggled-on';
}
toggleClass( button, 'toggled-on' );
toggleClass( menu, 'toggled-on' );
felixarntz marked this conversation as resolved.
Show resolved Hide resolved
};
} )();

// 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' );
// Better focus for hidden submenu items for accessibility.
function toggleParentsFocusClass() {
getParentElements( this, '.menu-item, .page_item' ).forEach( function( parentElement ) {
toggleClass( parentElement, 'focus' );
felixarntz marked this conversation as resolved.
Show resolved Hide resolved
} );
}
Array.from( document.querySelector( '.main-navigation' ).getElementsByTagName( 'a' ) ).forEach( function( menuLink ) {
menuLink.addEventListener( 'focus', toggleParentsFocusClass );
menuLink.addEventListener( 'blur', toggleParentsFocusClass );
} );

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 );
if ( 'ontouchstart' in window ) {
Array.from( document.querySelectorAll( '.menu-item-has-children > a, .page_item_has_children > a' ) ).forEach( function( menuLink ) {
felixarntz marked this conversation as resolved.
Show resolved Hide resolved
felixarntz marked this conversation as resolved.
Show resolved Hide resolved
menuLink.addEventListener( 'touchstart', function( e ) {
var el = getParentElements( this, 'li' )[0];

if ( -1 === el.className.indexOf( 'focus' ) ) {
felixarntz marked this conversation as resolved.
Show resolved Hide resolved
e.preventDefault();
el.className += ' focus';
getSiblingElements( el, '.focus' ).forEach( function( siblingElement ) {
siblingElement.className.replace( ' focus', '' );
felixarntz marked this conversation as resolved.
Show resolved Hide resolved
} );
}
} );
} );
}
} )();