简体   繁体   中英

pure CSS mobile hamburger menu doesnt close for onClick of links

I've included a snippet of the jquery/html/css for the hamburger. the jquery is what I would like to use to make the mobile menu close upon clicking its links. Currently you must click the X again (css-transformed spans) to do so which is annoying and not nice at all. I've tried ids and classes in all the different html tags and nothing seems to work. Any ideas/tips in the right direction?

 $(document).ready(function() { //took this code below from another SO answer that got good upvotes, and while I understand it easily, I can't figure out where to place it in the html...I fear that the CSS transforming and rendering of the menu is what is preventing this from working... $('.menu').on('click', function() { $('.menu').addClass('open'); }); $('.menu a').on("click", function() { $('.menu').removeClass('open'); }); });
 .sticky-navMobile { margin: 0; width: max-content; position: -webkit-sticky; position: sticky; top: 0; } #menuToggle { display: block; position: relative; top: 10px; left: 10px; z-index: 1; -webkit-user-select: none; user-select: none; } #menuToggle a { text-decoration: none; color: #232323; transition: color 0.3s ease; } #menuToggle a:hover { color: plum; } #menuToggle input { display: block; width: 40px; height: 32px; position: absolute; top: -7px; left: -5px; cursor: pointer; opacity: 0; z-index: 2; -webkit-touch-callout: none; } #menuToggle span { display: block; width: 33px; height: 4px; margin-right: 0px; margin-left: 0px; margin-bottom: 5px; position: relative; background: #722f58; border-radius: 3px; z-index: 1; transform-origin: 4px 0px; transition: transform 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0), background 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0), opacity 0.55s ease; } #menuToggle span:first-child { transform-origin: 0% 0%; color: #232323; } #menuToggle span:nth-last-child(2) { transform-origin: 0% 100%; color: #232323; } /** Transform all the slices of hamburger into an X. */ #menuToggle input:checked~span { background: rgb(146, 102, 146); opacity: 1; transform: rotate(45deg) translate(-2px, -1px); } #menuToggle input:checked~span:nth-last-child(3) { opacity: 0; transform: rotate(0deg) scale(0.2, 0.2); background: rgb(146, 102, 146); } #menuToggle input:checked~span:nth-last-child(2) { transform: rotate(-45deg) translate(0, -1px); background: rgb(146, 102, 146); } #menu { position: absolute; width: 150px; margin: -37px 0 0 -10px; border-bottom-right-radius: 45px; padding-top: 40px; background: #722f58; list-style-type: none; -webkit-font-smoothing: antialiased; /* to stop flickering of text in safari */ transform-origin: 0% 0%; transform: translate(-100%, 0); transition: transform 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0); } #menu li { padding: 10px 0; font-size: 22px; } #menuToggle input:checked~ul { transform: none; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <nav class="sticky-navMobile"> <nav> <div id="menuToggle"> <,-- A fake / hidden checkbox is used as click receiver: so you can use the.checked selector on it.--> <input type="checkbox" /> <,-- Some spans to act as a hamburger. They are acting like a real hamburger, not that McDonalds stuff. --> <span></span> <span></span> <span></span> <!-- Too bad the menu has to be inside of the button but hey, it's pure CSS magic.--> <ul id="menu"> <a href="#projects"> <li>Projects</li> </a> <a href="#bio"> <li>Personal Info</li> </a> <a href="#footer"> <li>Contact</li> </a> </ul> </div> </nav> </nav>

Part of the problem, is that open and close don't mean anything in this context, since it's a checkbox that's causing the menu to open and close.

What you need to do, is traverse up the DOM when you click on the menu or the anchor within the menu, and get the checked state of the checkbox. If it's true (which it will be because the menu is open), you set the checked state to false and that will trigger the CSS for the menu.

 $(document).ready(function() { //took this code below from another SO answer that got good upvotes, and while I understand it easily, I can't figure out where to place it in the html...I fear that the CSS transforming and rendering of the menu is what is preventing this from working... $('#menu').on('click', function() { if ($(this).siblings('input').prop('checked')) { $(this).siblings('input').prop('checked', false); } }); $('#menu a').on("click", function() { if ($(this).parent('ul').siblings('input').prop('checked')) { $(this).siblings('input').prop('checked', false); } }); });
 .sticky-navMobile { margin: 0; width: max-content; position: -webkit-sticky; position: sticky; top: 0; } #menuToggle { display: block; position: relative; top: 10px; left: 10px; z-index: 1; -webkit-user-select: none; user-select: none; } #menuToggle a { text-decoration: none; color: #232323; transition: color 0.3s ease; } #menuToggle a:hover { color: plum; } #menuToggle input { display: block; width: 40px; height: 32px; position: absolute; top: -7px; left: -5px; cursor: pointer; opacity: 0; z-index: 2; -webkit-touch-callout: none; } #menuToggle span { display: block; width: 33px; height: 4px; margin-right: 0px; margin-left: 0px; margin-bottom: 5px; position: relative; background: #722f58; border-radius: 3px; z-index: 1; transform-origin: 4px 0px; transition: transform 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0), background 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0), opacity 0.55s ease; } #menuToggle span:first-child { transform-origin: 0% 0%; color: #232323; } #menuToggle span:nth-last-child(2) { transform-origin: 0% 100%; color: #232323; } /** Transform all the slices of hamburger into an X. */ #menuToggle input:checked~span { background: rgb(146, 102, 146); opacity: 1; transform: rotate(45deg) translate(-2px, -1px); } #menuToggle input:checked~span:nth-last-child(3) { opacity: 0; transform: rotate(0deg) scale(0.2, 0.2); background: rgb(146, 102, 146); } #menuToggle input:checked~span:nth-last-child(2) { transform: rotate(-45deg) translate(0, -1px); background: rgb(146, 102, 146); } #menu { position: absolute; width: 150px; margin: -37px 0 0 -10px; border-bottom-right-radius: 45px; padding-top: 40px; background: #722f58; list-style-type: none; -webkit-font-smoothing: antialiased; /* to stop flickering of text in safari */ transform-origin: 0% 0%; transform: translate(-100%, 0); transition: transform 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0); } #menu li { padding: 10px 0; font-size: 22px; } #menuToggle input:checked~ul { transform: none; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <nav class="sticky-navMobile"> <nav> <div id="menuToggle"> <,-- A fake / hidden checkbox is used as click receiver: so you can use the.checked selector on it.--> <input type="checkbox" /> <,-- Some spans to act as a hamburger. They are acting like a real hamburger, not that McDonalds stuff. --> <span></span> <span></span> <span></span> <!-- Too bad the menu has to be inside of the button but hey, it's pure CSS magic.--> <ul id="menu"> <a href="#projects"> <li>Projects</li> </a> <a href="#bio"> <li>Personal Info</li> </a> <a href="#footer"> <li>Contact</li> </a> </ul> </div> </nav> </nav>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM