12% off of LTD using this coupon: TWELVEPERCENTOFF. Promo ends on 2 Dec midnight UTC.
Published on Feb 11, 2022

How to Close Modal After Clicking Hash Links in Oxygen Menu

Sridhar Katakam

Peter Bronski wrote about the improved version (to add accessibility support by being able to click the link, close the modal and jump to the section) of the code that Mike originally shared for closing the modal after a hash link in the Menu component is clicked in Oxygen.

I have refactored the code and further enhanced it to add smooth scrolling (w/o the hash part appearing in the URLs).

jQuery(document).ready(function ($) {
		// Check if the `oxyCloseModal` function is defined to make sure it's not a page without a modal
		if (typeof oxyCloseModal === "undefined") {
			return;
		}

		// Function to close the modal and set up smooth scrolling for the hash links
		const closeModal = (element, event) => {
			oxyCloseModal();

			// gets the part of the URL beginning with #
			let h = $(element.hash);

			// uncomment this if hash is to be retained
			// $("html, body").animate({ scrollTop: h.offset().top - 0 }, 1000);
			
			// comment this if hash is to be retained
			(h = h.length ? h : $("[name=" + this.hash.slice(1) + "]")).length && (event.preventDefault(), $("html, body").animate({ scrollTop: h.offset().top - 0 }, 1000));
		}


		// If the user clicks a hash link in the modal menu, close the modal
		$(".menu-item a").on("click", function (event) {
			closeModal(this, event);
		});


		// Also sweep through the modal menu links and watch for keyboard users
		const collection = document.getElementsByClassName(".menu-item a");
		
		// Loop through the menu links
		for (let i = 0; i < collection.length; i++) {
			$(collection[i]).addEventListener("keyup", function (event) {
				// watch for user pressing the "Enter" key on the keyboard to navigate the modal menu
				if (collection[i].keyCode === 13) {
					closeModal(this, event);
				}
			});
		}
});

This could be placed inside a Code Block.

Here’s how I set up the demo.

Step 1

At Appearance > Menus, create a new menu having hash links to your sections.

Step 2

In the Main sitewide Catch All Oxygen Template (or likely the single page you have for the entire site), add an Icon component. Since we are going to be setting its position to fixed, it does not matter where this is in the Structure. But for being able to locate it easily, later on, you may want to put it inside your site’s header.

Icon size: 36px

Icon Set: Linearicons
Icon: menu-circle

In Custom CSS, add

cursor: pointer;

Under Advanced > Layout, set z-index to 1 and Position to fixed @ 30px from the left and top each.

We need to account for the height of WP admin bar for when it is visible for admins and other logged-in users. Add this in a Stylesheet at Manage > Stylesheets:

.admin-bar #fancy_icon-86-10 {
	top: 62px;
}

Replace fancy_icon-86-10 with the ID of your icon.

Step 3

Add a Modal component. You may want to add this at the root level as the last element in the structure.

Trigger > User clicks element and select your menu icon.

Closing > Insert Close Button. Change the text to say, x.

Set the Modal’s padding to say 30px on all sides.

Add the “Navigation” Heading.

Add a Menu component and select your menu from Step 1.

Menu Layout: Vertical.

Mobile Responsive > Mobile Menu / Toggle Below: Never.

Step 4

Add a Code Block at the end of the structure.

PHP & HTML:

<?php
	//echo "hello world!";
?>

Paste the JS code from the beginning of this tutorial in the JavaScript area.

References

L143 of /wp-content/plugins/oxygen/component-framework/includes/scripts/scripts.php:

if ($show_script==="true") : ?><script>jQuery(document).on('click','a[href*="#"]',function(t){if(jQuery(t.target).closest('.wc-tabs').length>0){return}if(jQuery(this).is('[href="#"]')||jQuery(this).is('[href="#0"]')||jQuery(this).is('[href*="replytocom"]')){return};if(location.pathname.replace(/^\//,"")==this.pathname.replace(/^\//,"")&&location.hostname==this.hostname){var e=jQuery(this.hash);(e=e.length?e:jQuery("[name="+this.hash.slice(1)+"]")).length&&(t.preventDefault(),jQuery("html, body").animate({scrollTop:e.offset().top-<?php echo $offset; ?>},<?php echo $time; ?>))}});</script><?php endif;

Formatted and sample rendered version of the above:

jQuery(document).on("click", 'a[href*="#"]', function (t) {
  if (jQuery(t.target).closest(".wc-tabs").length > 0) {
    return;
  }
  if (
    jQuery(this).is('[href="#"]') ||
    jQuery(this).is('[href="#0"]') ||
    jQuery(this).is('[href*="replytocom"]')
  ) {
    return;
  }
  if (
    location.pathname.replace(/^\//, "") == this.pathname.replace(/^\//, "") &&
    location.hostname == this.hostname
  ) {
    var e = jQuery(this.hash);
    (e = e.length ? e : jQuery("[name=" + this.hash.slice(1) + "]")).length &&
      (t.preventDefault(),
      jQuery("html, body").animate({ scrollTop: e.offset().top - 0 }, 1000));
  }
});

https://stackoverflow.com/a/32772416

tagschevron-leftchevron-rightchainangle-rightangle-upangle-downfolder-omagnifiercrossmenuchevron-downarrow-right