Giter Club home page Giter Club logo

slide-menu's Introduction

Slide Menu

⚠️ This project is unmaintained. Feel free to fork it.

A library agnostic multilevel page menu with a smooth slide effect based on CSS transitions and various options.

Support: All current browsers and IE11+ (if using dist/slide-menu.ie.js).

Demo

Breaking changes

Version 1.0 has been released and includes breaking changes: SlideMenu no longer depends on jQuery and the library has been rewritten in TypeScript. See below instructions how to use the current version.

Install

npm install @grubersjoe/slide-menu

Now import dist/slide-menu.js and dist/slide-menu.css in your bundler or build system of choice or use a 1998 <script> and <link> tag. Afterwards SlideMenu will be available in the global namespace (window.SlideMenu).

To keep the bundle size small (17 kB vs. 22 kB) Internet Explorer 11 is not supported out of the box. If you need to support Internet Explorer 11 use dist/slide-menu.ie.js instead.

Usage

All you need is the traditional CSS menu HTML markup and a wrapper with the class slide-menu. Menus can be nested endlessly to create the desired hierarchy. If you wish to programmatically control the menu, you should also set an ID to be able to use the API (see below).

Example

<nav class="slide-menu" id="example-menu">
  <ul>
    <li>
      <a href="#">Home</a>
      <ul>
        <li><a href="#">Submenu entry 1</a></li>
        <li><a href="#">Submenu entry 2</a></li>
        <li><a href="#">Submenu entry 3</a></li>
      </ul>
    </li>
    <li>
      <a href="/blog">Blog</a>
    </li>
    <li>
      <a href="/about">About</a>
    </li>
  </ul>
</nav>

Create the menu then like this:

document.addEventListener("DOMContentLoaded", function () {
  const menuElement = document.getElementById('example-menu');
  const menu = new SlideMenu(menuElement);
});

Options

The SlideMenu() constructor takes an optional second parameter to pass in various options:

Option Description Valid values Default
backLinkAfter HTML to append to back link in submenus HTML code ''
backLinkBefore HTML to prepend to back link in submenus HTML code ''
keycodeClose Key used to close the menu Any valid KeyboardEvent key undefined
keycodeOpen Key used to open the menu Any valid KeyboardEvent key undefined
position Position of the menu 'left' or 'right' 'right'
showBackLink Add a link to navigate back in submenus (first entry) boolean true
submenuLinkBefore HTML to prepend to links with a submenu HTML code ''
submenuLinkAfter HTML to append to links with a submenu HTML code ''

Example:

document.addEventListener("DOMContentLoaded", function () {
 const menu = new SlideMenu(document.getElementById('example-menu'),{
     showBackLink: false,
     submenuLinkAfter: ' <strong>⇒</strong>'
 });
});

API

You can call the API in two different ways:

  • Reuse the reference to the SlideMenu instance:

    const menu = new SlideMenu(document.getElementById('example-menu'));
    
    // ... later
    menu.close();
  • The SlideMenu instance is also added as property of the menu DOM element (I'm still not sure if this might be a really bad idea). So if you need to control an existing menu without a reference to it, you can fetch it any time this way:

    const menu = document.getElementById('example-menu')._slideMenu;
    menu.open();

Methods

  • close(animate = true) - Close the menu
  • back() - Navigate on level back if possible
  • destroy() - revert all DOM changes made by SlideMenu. This includes inline styles, but not the slide-menu class name for the container element.
  • navigateTo(target) Open the menu level which contains specified menu element. target can either be a document.querySelector compatible string selector or the the DOM element (inside the menu). The first found element (if any) will be used.
  • open(animate = true) - Open the menu
  • toggle(animate = true) - Toggle the menu

Events

SlideMenu emits events for all kind of actions, which trigger as soon as the action is method is called. Plus, all events have also an <event>-after equivalent, which is fired after the step is complete (completely animated).

  • sm.back[-after] fires immediately when navigating backwards in the menu hierarchy or after the animation is complete respectively.
  • sm.close[-after] fires immediately when the close() method is called or after the animation is complete respectively.
  • sm.forward[-after]fires immediately when navigating forward in the menu hierarchy or after the animation is complete respectively.
  • sm.navigate[-after]fires immediately when calling the navigateTo() method or after the animation is complete respectively.
  • sm.open[-after] fires immediately when the open() method is called or after the animation is complete respectively.

Make sure to add the event listener to the HTML element, which contains the menu, since the events for this specific menu are dispatched there:

document.addEventListener("DOMContentLoaded", function () {
  const menuElement = document.getElementById('example-menu');
  const menu = new SlideMenu(menuElement);

  // Attach the event listener to the *DOM element*, not the SlideMenu instance
  menuElement.addEventListener('sm.open', function () {
    console.log('The menu opens');
  });

  menuElement.addEventListener('sm.open-after', function () {
    console.log('The menu has opened');
  });
});

Control buttons

Buttons to control the menu can be created easily. Add the class slide-menu__control to anchors or buttons and set the data attributes target to the ID of the desired menu and action to the API method:

<button type="button" class="slide-menu__control" data-action="open">Open</button>
<button type="button" class="slide-menu__control" data-action="back">Back</button>

Inside the menu container the attribute data-target can be omitted or set to to the string this to control this menu.

<a class="slide-menu-control" data-action="close">Close this menu</a>
<a class="slide-menu-control" data-target="this" data-action="close">Close this menu</a>

Development

yarn install
yarn start:dev

Open http://localhost:9000/.

To create a production build:

yarn build

slide-menu's People

Contributors

grubersjoe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

slide-menu's Issues

Cant build

I've installed the package via npm as per the documentation. I then include it in my gulp build script and run my compile command. The script fails with the following message, this only occurs when I include the dist/slide-menu.js.

events.js:173
      throw er; // Unhandled 'error' event
      ^
GulpUglifyError: unable to minify JavaScript
    at createError (/Users/myles/app/node_modules/gulp-uglify/lib/create-error.js:6:14)
    at apply (/Users/myles/app/node_modules/gulp-uglify/node_modules/lodash/_apply.js:16:25)
    at wrapper (/Users/myles/app/node_modules/gulp-uglify/node_modules/lodash/_createCurry.js:41:12)
    at /Users/myles/app/node_modules/gulp-uglify/lib/minify.js:55:15
    at DestroyableTransform._transform (/Users/myles/app/node_modules/gulp-uglify/composer.js:12:19)
    at DestroyableTransform.Transform._read (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:184:10)
    at DestroyableTransform.Transform._write (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:172:83)
    at doWrite (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:428:64)
    at writeOrBuffer (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:417:5)
    at DestroyableTransform.Writable.write (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:334:11)
Emitted 'error' event at:
    at DestroyableTransform.onerror (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:640:52)
    at DestroyableTransform.emit (events.js:197:13)
    at onwriteError (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:443:12)
    at onwrite (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:470:11)
    at WritableState.onwrite (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:180:5)
    at DestroyableTransform.afterTransform (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:93:3)
    at DestroyableTransform._transform (/Users/myles/app/node_modules/gulp-uglify/composer.js:16:7)
    at DestroyableTransform.Transform._read (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:184:10)
    at DestroyableTransform.Transform._write (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:172:83)
    at doWrite (/Users/myles/app/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:428:64)

Also on another note the version on npmjs.org is at 1.0.13 whereas this repo is at 1.0.12 which is very confusing.

https://www.npmjs.com/package/@grubersjoe/slide-menu/v/1.0.13

Reset menu on close

Hello! Great menu, thank you! By default, you have options to go back one menu level or to close the menu completely. Is it possible if, for example, you are four levels deep and you close the menu, it would be reset to the first level the next time you open it?

Slide Menu Control Buttons

I've just come across this and it's exactly what I was looking for.

I have set everything up as per the instructions and I can get it to work when I use the API to manually trigger the menu opening, however none of the buttons work by default.

I'm not getting any errors or anything from when I click the buttons, just nothing happening at all.

Any ideas what I could be missing?

Menu not working on Safari 7 (iOS 7+)

Hi @grubersjoe, is it possible for your fantastic menu to work on Safari 7 (on iPhone's iOS version number 7 and up)? I was thinking to some sort of code compilation to get to this result.

I've tried on BrowserStack the demo page you made available (in the readme of this repository) and also the website I'm working on (where I'm using your menu plugin) and they both fail, but in 2 different ways.

On the demo website

Here I get these 2 errors: Viewport argument key "shrink-to-fit" not recognizedand ignored. and SyntaxError: Unexpected token '>'. The second one is related to arrow functions, I'm thinking that maybe they're not supported on this browser, so not a big deal (presumably) once you compile the code, regarding the first error I don't know…
error-demo-page

On the website I'm working on

No errors at all on page load, but it happens that I get the menu visible by default and when I click the top right X to close it then I get logs about the registered event listeners emitted sm.open and sm.close, so I'm thinking this is a CSS problem (maybe).
behaviour-iphone

Any help and clarification will be much appreciated! 😉

SVG inside of button will cause js error

I'm trying to put a hamburger icon inside of the button that controls the open of the slide-menu, clicking on the icon causes the following js error.

slide-menu.ie.js:1060 Uncaught TypeError: e.className.includes is not a function
at HTMLDocument. (slide-menu.ie.js:1060)
(anonymous) @ slide-menu.ie.js:1060

Button HTML:
<button id="navMobBtn" class="mobile-menu__button--open slide-menu__control" type="button" data-target="mobile-nav-menu" data-action="open" aria-controls="mobile-nav-menu" aria-expanded="false" aria-label="Toggle navigation"> <span class="slide-menu__control hamburger-icon"></span> </button>

CSS:
.hamburger-icon { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5); height: 2.5rem; width: 2.5rem; }

EDIT: This also happens when you just wrap a HTML element around the button text.
<span class="myClass">Open Menu</span>

firefox vs chrome slider behaviour

Hi,
i've tested the slider on these two browsers and though the slider's behaviour is perfect on chrome, it's not the same at all on firefox, where the nav starts off to slide underneath the content of the page and eventually ends up on top like it should...
I don't seem to know where that comes from or if anyone else has had the same issue and maybe how i can fix this?
Thank a bunch

p.s. i'm using the ie version to be cross-browser compatible

Suggestion: Add rel attribute with nofollow value for the Back Link

This is just a suggestion because one of the scans/tests we run on our site reported an issue with the "Back" link. It gives us the following:

Links are not crawlable

Search engines may use href attributes on links to crawl websites. Ensure that the href attribute of anchor elements links to an appropriate destination, so more pages of the site can be discovered.

I think adding rel="nofollow" will help.

Thank you.

Switching between mobile and desktop layout

My site has a different layout for desktop and mobile, and I am only using slide-menu for the mobile layout. I am currently using a page width check on load to either initialize slide-menu or not, however it would be nice if I could dynamically enable and disable slide-menu on an element.

dynamically enabling the menu's isn't an issue, as I can just call the code to create the menus on page resize, the issue is disabling them. as far as I can tell, there is no native ability to undo the DOM changes that new SlideMenu() creates.

is this a function that could be added?

Menu Links with Children Not Clickable

Great plugin. I have one issue that's preventing me from utilizing it though. If a menu item is a parent, you can never actually navigate to that menu item link, since clicking on parent items always slides to their child menu, or slides back to the parent menu it was on before. Is there any way to have the parent item links clickable as they would be normally, and have the submenu link option, such as a span tag, appended -after- the actual menu item link tag so you can be able to click on just the span tag of the parent items to navigate forward/back, and when you click on the actual menu item links, they navigate to their pages?

Scroll inside menu not possible

Hey :)

Great plugin, but when the number of children excess the screenheight, it's not possible to scroll in the menu, to get to the last element :(

Not working without fixed height

I have set in menu in left column, but there are lost of list menu.
Because of fixed height I have not show other menu list.

Actual Result
Now 300 height set.

Accepted Result
Height as per list item

Back Link not working in IE11

As the title suggests, I am not able to get the back link to slide the menu back to its previous state in IE11. The slide forward works, however.

Breadcrumb and back

Just a pair of suggestions for enhancement :

  1. Disable the back button in the zero level.
  2. Breadcrumb is your best friend in multileves menu

The first is just a detail but the second is a big help.

Saludos!,

Breaking change after update 1.1.3

Hi,
I have updated from 1.0.13 to 1.1.3 and see that it breaks the code while using webpack(did not tested outside of webpack)

The following code is woring on 1.0.13 but giving error on 1.1.3:

import '@grubersjoe/slide-menu';
var win = window;

win.document.addEventListener('DOMContentLoaded', function () {
  var menu = new SlideMenu(win.document.getElementById('main-mobile-menu'), { 
    position: 'left',
    showBackLink: true,
    submenuLinkAfter: '<i class="menu-right-icon material-icons"> chevron_right </i>',
    backLinkBefore: '<i class="menu-right-icon material-icons"> chevron_left </i>'
  });


  menu.menu.addEventListener('sm.open-after', function () {
    win.document.getElementById('mobile-menu-overlay').classList.toggle('mobile-active');
    win.document.querySelector('body').classList.add('body-overflow');
  });
}

The error is on the word menu.menu menu.menu.addEventListener saying that menu.menu is null. This mean new SlideMenu is not initializing the menu.

in version 1.0.13 doing

import SlideMenu from '@grubersjoe/slide-menu';
window.SlideMenu = SlideMenu;
new window.SlideMenu()

is not working and saying window.SlideMenu is not a constructor. Not sure about 1.1.3

Questions:

  • Am I misusing this library or is it really breaking after the update?
  • Just wondering If it is a breaking change, shouldn't the version be changed to 2.x.x as it is a major update? I am not a pro at versioning by the way :)))

PS. Thank you for this nice library. It really helped us on a project.

back button text appended with every link name

this is an odd issue, that I fully admit is because im trying to do something strange.

basically, I have a horizontal nav bar that I am converting into the mobile navbar, which is formatted as such:

<ul>
<li><a>Link 1</a>
<ul>
     <li><a>Sub Link 1</a>
     </li>
     <li><a>Sub Link 2</a>
     </li>
</ul>
</li>
</ul>

etc.

For the mobile view, I am trying to make it so that the entire navbar is nested under a single link. (so I can have other content in the tray)

the way I am trying to do that is to use the jQuery wrapAll function before calling SlideMenu, like so:

$("#navigation-first > ul").wrapAll("<ul id='mobile-tray-anchor'><li><a>Site Links</a> </li></ul>");

and while this does technically work, in that I get a single menu item at the top level:

image

When navigating into the menu, the text for the "Back" Link has been appended with the name of every single link in the nav menu

image

This doesnt happen if I just alter the html to include the enclosing UL tag, but then that messes up my desktop navigation menu.

Any ideas what could be causing this? Also, if you have any ideas of a better way of accomplishing this, I would be happy to hear that as well.

Compatibility IE 11

Hello.

There seems to be an error with later versions of the library on IE 11.
The error shown is "SCRIPT 5022 : argument 'elem' must be a valid HTML node"

The file used is the right one labelled with ".ie.js" at the end and under the directory dist.

Any hint on what i might be doing wrong? Any help you could bring would be much appreciated.

Capture

Missing height calculation causes problems with elements below the menu

All child levels have absolute positioning, which means the height of the menu container always remains the same and equals first UL height. So if i have some extra elements below the menu, they appear on top of the menu, since the height doesn't change if i go deeper in levels. Solution would be re-calculating wrapper height that equals visible UL height on anchor click. Would be very nice to get this quick addition for such a great component.

Display: none when returning to parent

Hi!

Sometimes, when going back from viewing the children menu, to the main menu; the parent of the children I just visited gets display:none inlined.. Any tips?

Thanks for the package!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.