Giter Club home page Giter Club logo

priority-navigation's Introduction

PriorityNavigation.js

PriorityNav is a pure javascript plugin that will move your menu items if they don't fit its parent.

Vue.js version here.


Priority Navigation demo

Take a look at the Demo site.


Features

  • Accessible
    Adds appropriate aria attributes and set focus to links when needed.
  • No dependencies
    The plugin is written in pure javascript making it fast and lean.
  • Breakpoint
    When the breakpoint has been reached the plugin will automaticly move all items to the dropdown & change the toggle label to navDropdownBreakpointLabel.
  • Smart calculation of available space
    It automatically looks for the main navigation's siblings and calculates remaining space.
  • Flexible
    Because of the point above you can have multiple inline-block/flexbox items on the same level.
  • Non obstructive menu dropdown
    The dropdown menu can be closed by clicking outside and pressing escape.
  • Callbacks
    Callbacks are fired when an item is moved or moved back from the main navigation.

Usage

Load plugin files

<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="priority-nav-core.css">
</head>

<body>
    <script async src="priority-nav.js"></script>
</body>

Call plugin without any options.

var nav = priorityNav.init();

Ideal html structure

<nav>
    <ul> <- needs to be inline-block
        <li>menu item</li>
        <li>menu item</li>
        <li>menu item</li>
        <li>menu item</li>
    </ul>
</nav>

Options

initClass:                  "js-priorityNav", // Class that will be printed on html element to allow conditional css styling.
mainNavWrapper:             "nav", // mainnav wrapper selector (must be direct parent from mainNav)
mainNav:                    "ul", // mainnav selector. (must be inline-block)
navDropdownClassName:       "nav__dropdown", // class used for the dropdown - this is a class name, not a selector.
navDropdownToggleClassName: "nav__dropdown-toggle", // class used for the dropdown toggle - this is a class name, not a selector.
navDropdownLabel:           "more", // Text that is used for the dropdown toggle.
navDropdownBreakpointLabel: "menu", //button label for navDropdownToggle when the breakPoint is reached.
breakPoint:                 500, //amount of pixels when all menu items should be moved to dropdown to simulate a mobile menu
throttleDelay:              50, // this will throttle the calculating logic on resize because i'm a responsible dev.
offsetPixels:               0, // increase to decrease the time it takes to move an item.
count:                      true, // prints the amount of items are moved to the attribute data-count to style with css counter.

//Callbacks
moved: function () {}, // executed when item is moved to dropdown
movedBack: function () {} // executed when item is moved back to main menu

Package managers

  • npm: npm install --save priority-nav
  • bower: bower install priority-nav.js

Building the source files

#cloning repository
git clone https://github.com/gijsroge/priority-navigation.git
cd priority-navigation

#dependencies
npm install

#build files to dist folder
grunt build

IE9 Support

To support Internet Explorer 9 and lower classList.js must be added your page.

<!--[if lt IE 9]><script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/2014.01.31/classList.min.js"></script><![endif]-->

IE8 Support

To support Internet Explorer 8, es5-shim and classList.js from above must be added your page.

<!--[if lt IE 9]><script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/2.0.8/es5-shim.min.js"></script><![endif]-->

Alternatives

priority-navigation's People

Contributors

bfred-it avatar bryant1410 avatar chrisgherbert avatar craigsimps avatar dependabot[bot] avatar gijsroge avatar glennongithub avatar jaradlight avatar pedronorte 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

priority-navigation's Issues

support for collapsing drop downs

Hello - I've had a hard time finding a Priority+ navigation that handles drop down menus well. The use case is a "level 1" set of menu choices with some but not all of the items being dropdowns.

Before I start using your framework, can you let me know how priority-navigation handles dropdown menus when they are in the "more" menu. Does the expanded menu push other items in the more list down or does it appear as an overlay on the initial "more" list of menu items (level 1). An example would be great.

Also what's the preferred way to handle a fixed item at the left and/or right of the collapsible part of the menu?

Thanks!

The whole navbar collapsed

Hi,

When I checked out the demo, I thought this is the perfect plugin for me. However, when I applied it to my project, it happened that the entire navbar was collapsed when it shrinked the break-point width. I want my navbar items collapsed one by one like the demo you put on. I don't know what is going wrong.

                                                                                                                                Thank you !

Accessibility: add aria-expanded attribute to menu button(s)

Request:

Priority navigation should add aria-expanded to the <button> tag(s)—for both "More" and the breakpoint mobile menu:

What is aria-expanded?

aria-expanded indicates whether the element, or another grouping element it controls, is currently expanded or collapsed.

W3 aria-expanded spec

Current markup:

<button aria-controls="menu" class="nav__dropdown-toggle priority-nav__dropdown-toggle priority-nav-is-visible" prioritynav-count="2">more</button>

Proposed markup:

<button aria-expanded="false" aria-controls="menu" class="nav__dropdown-toggle priority-nav__dropdown-toggle priority-nav-is-visible" prioritynav-count="2">more</button>

aria-expanded is a boolean attribute. When the menu is open, it should toggle to true.

Here's a demo that shows aria-expanded in action in a similar context.

Destroy on mobile screens

I was wondering if you plan to add an destroy/disable priority navigation from a breakpoint. For example, need to use priority navigation only for desktop sizes and disable it on mobile, because i use custom navigation on mobile screens. Is ther any solution for this problem yet? Thx

Add orientationchange event to listeners

Hi I just came across this (bug, idk) looks like phones are not reacting to resize event when the phone changes orientation so I added these lines:

window.addEventListener("orientationchange", function() {
    if(priorityNav.doesItFit)priorityNav.doesItFit(_this);
}, true);

Sorry I am not creating a pull request for this, but for 3 lines it would be overkill for me and probably for you too. :)

'navDropdownToggleClassName' is causing overflow

Is there a reason for using 'visibilty' instead of 'display' for hiding '.nav__dropdown-toggle'? as when positioning 'mainNavWrapper' far right (with 'text-align: right' as 'float: right' doesn't work) it naturally causes overflow.

I fixed it with

.priority-nav-is-hidden {
    display: none;
}

.priority-nav-is-visible {
    display: inline-block;
}

Tab order not preserved

♿ This is an accessibility issue for sites that comply with WCAG 2.0 Level A. Specifically referencing Success Criterion 2.4.3 - Focus Order.

Steps to reproduce:

  1. Focus on "More" link
  2. Press Spacebar to activate the link and open the menu.
  3. Press Tab

Result: Next focusable item after the menu receives focus

Expected result: First link/focusable item in the expanded dropdown receives focus

How to install with bower?

How to install this script with bower? on your doc: bower --install priority-nav.js seems like an incorrect syntax, trying to use bower search priority-nav to find your package but return no results. Any ideas?

Handle multiple init calls.

Hi,

I just used the priorityNav plugin inside an AngularJS directive.
The directive would run priorityNav.init() after defining the settings.

But when I have 2 instances of the AngularJS directive on the page, the priorityNav.init() gets called twice, and on the 2nd call, it actually breaks all instances on the page because the wrapper element is duplicated and what happens is that the first copy has the 'hidden' links, while the second copy of the wrapper has the button event!

I have currently fixed this issue by allowing my directive to run only once. But I think a fix on your end is a lot safer.

Cheers,
Maikel

Minor issues

Great script, i think it is the most complete i found, I already implemented it. Some minor issues:

I found class setting restrictive, it could allow for multiple class entry favoring css code reuse when you do bring your own, without going:

.main-nav,
.main-nav-dropdown{}

For instance:

var nav = priorityNav.init({
                mainNavWrapper: "main-nav-wrapper",
                mainNav: "main-nav",
                navDropdownClassName: '.main-nav.dropdown',
                navDropdownToggleClassName: 'main-nav-toggle',
                navDropdownLabel: '<i class="fa fa-caret-down"></i> más',
            });

Can none of the parent containters of 'mainNav' can be floated nor absolute, but only fixed? I had to change the layout to comply to that requirement. Why is it so?

It would be nice if you specify in REAME that options are default values, and some are required. Somewhat obvious but at first when I read var nav = priorityNav.init(); was all there was needed to initialize, It didn't work.

Disable more

If possible disable link more or hidden link more ?

Button element should have type="button" attribute

Many ASP.net sites have a form element wrapping the entire body (I'm looking at you Kentico).

The button element used to show overflow navigation triggers a page refresh on these sites without a type attribute set to 'button'.

navDropdownToggle.setAttribute("type", "button");

I'd put this on line 192 to fix the issue.

IE always collapsed

Internet Explorer v11 always show Menu Collapsed.
So i guess breakPoint is not working.

Outdated class name options in readme

The following options have been modified in the source, but are not reflected in the readme:

  • navDropdown
    • Should be navDropdownClassName
  • navDropdownToggle
    • Should be navDropdownToggleClassName

Option values not working

The starting problem is with async Attribute which not execute the function at all.
When removing async Attribute, the function works fine outputing the right html with default classes while all options values are not being effective.

var wrapper = document.querySelector("nav");
var nav = priorityNav.init({
  mainNavWrapper: "nav",
  mainNav: ".navigation",
  navDropdown: "goold",
  navDropdownLabel: "googl",
  breakPoint:800
});

Any help with this issue?

Enhancement/accessibility: Keep priority nav dropdown <ul> inside of main <ul>

The Current Markup:

<nav>
  <ul>
    <li><a href="#">menu item 1</a></li>
    <li><a href="#">menu item 2</a></li>
    <li><a href="#">menu item 3</a></li>
    <li><a href="#">menu item 4</a></li>
  </ul>

  <span class="nav__dropdown-wrapper priority-nav__wrapper" aria-haspopup="true">
    <button aria-controls="menu" class="nav__dropdown-toggle priority-nav__dropdown-toggle priority-nav-is-visible" prioritynav-count="2">
      more
    </button>
    <ul aria-hidden="true" class="nav__dropdown priority-nav__dropdown">
      <li><a href="#">menu item 5</a></li>
      <li><a href="#">menu item 6</a></li>
    </ul>
  </span>
</nav>

Proposed markup:

<nav>
  <ul>
    <li><a href="#">menu item 1</a></li>
    <li><a href="#">menu item 2</a></li>
    <li><a href="#">menu item 3</a></li>
    <li><a href="#">menu item 4</a></li>

    <li class="nav__dropdown-wrapper priority-nav__wrapper" aria-haspopup="true"> <!-- Keep new <ul> inside the current <ul> -->
      <button aria-controls="menu" class="nav__dropdown-toggle priority-nav__dropdown-toggle priority-nav-is-visible" prioritynav-count="2">
        more
      </button>
      <ul aria-hidden="true" class="nav__dropdown priority-nav__dropdown"> <!-- Needs id="menu" -->
        <li><a href="#">menu item 5</a></li>
        <li><a href="#">menu item 6</a></li>
      </ul>
    </li>
  </ul>
</nav>

Reasoning:

The Priority+ <ul> is directly related to the parent <ul>. The Priority+ <ul> is effectively a dropdown menu within the parent menu. Because of this, the markup should represent the parent/child relationship. I think this would help accessibility and be a benefit for assistive technology users.

Doesn't work in IE9

It says in the documentation if i include classList.js it will work in IE9.

Tried this and it's broken. Can you help?

Accessibility: aria-controls references an ID that doesn't exist

Steps to reproduce the issue

  1. View the demo.
  2. Shrink the Priority+ navigation so that "More" is displayed.
  3. Right click "More" > Inspect Element.

Results

  1. The <button> tag has aria-controls="menu", like so:
<button aria-controls="menu" class="nav__dropdown-toggle priority-nav__dropdown-toggle priority-nav-is-visible" prioritynav-count="1">more</button>

Expected results

The <ul> below the <button> should have id="menu". Currently, it does not.

<ul aria-hidden="true" class="nav__dropdown priority-nav__dropdown">
  ...
</ul>

aria-controls documentation/references:

Dropdown overflows screen on mobile

Here’s a screenshot of the demo exhibiting this behaviour:

screenshot from 2017-02-22 19-40-21

The issue affects at least the latest versions of FireFox and Chromium on Linux, and the iPhone 7.

not maintaining space between list elements when removed/added

i have styled li elements so they look more like buttons. I've noticed when more then one element is moved to the "more" dropdown and back it removes the spacing that was added during creation. I tested this on the demo page by adding a background color to these elements to make sure it wasn't my code. I've added a video to show what i'm seeing.

I'm not sure why this is happening or if there might be a way to set spacing of the elements manually so they always match? I would appreciate any help/feedback.

2020-09-09_13-51-56.zip

Can the button element be customised/changed ?

I'd like to be able to use, say, a burger menu like SVG icon in place of the button element.

Is this possible or are there any future plans to accommodate customisation of this element?

Regards
Chris

Having some trouble getting this setup and working

Can you show the starting html setup for the demo page? I can't seem to make this plugin work out of the box like your example shows.

I'm trying to develop a mobile app type of website that has a fixed menu bar at the bottom that I want the priority nav to attach to. This app is built in ember.js and the resulting output from ember without trying to init priority-nav looks like this

<nav id="primary-navigation" role="navigation">
    <ul class="primary-navigation-items">
        <li id="ember645" class="ember-view nav-button"><a id="ember646" href="/items" class="ember-view active">   <i id="ember656" aria-hidden="true" class="ember-view fa fa-credit-card"><!----></i>
</a></li>
        <li id="ember665" class="ember-view nav-button"><a id="ember666" href="/items" class="ember-view active">   <i id="ember667" aria-hidden="true" class="ember-view fa fa-shopping-cart"><!----></i>
</a></li>
        <li id="ember668" class="ember-view nav-button"><a id="ember669" href="/items" class="ember-view active">   <i id="ember670" aria-hidden="true" class="ember-view fa fa-credit-card"><!----></i>
</a></li>
        <li id="ember671" class="ember-view nav-button"><a id="ember672" href="/items" class="ember-view active">   <i id="ember673" aria-hidden="true" class="ember-view fa fa-shopping-cart"><!----></i>
</a></li>
        <li id="ember674" class="ember-view nav-button"><a id="ember675" href="/items" class="ember-view active">   <i id="ember676" aria-hidden="true" class="ember-view fa fa-credit-card"><!----></i>
</a></li>
    </ul>
</nav>

And when I initialize the plugin the initial ul element has no items in it and they have all moved into the dropdown I presume it is, but the demo site shows they should still be in the main ul before priority-nav attempts to move them. So I'm not sure what's happening here.

The html after priority nav is initialized looks like this

<nav id="primary-navigation" role="navigation" instance="0" class="priority-nav priority-nav-has-dropdown">
    <ul class="primary-navigation-items">





    </ul><span class="nav__dropdown-wrapper priority-nav__wrapper"><ul class="nav__dropdown priority-nav__dropdown"><li id="ember645" class="ember-view nav-button"><a id="ember646" href="/items" class="ember-view active">   <i id="ember656" aria-hidden="true" class="ember-view fa fa-credit-card"><!----></i>
</a></li><li id="ember665" class="ember-view nav-button"><a id="ember666" href="/items" class="ember-view active">  <i id="ember667" aria-hidden="true" class="ember-view fa fa-shopping-cart"><!----></i>
</a></li><li id="ember668" class="ember-view nav-button"><a id="ember669" href="/items" class="ember-view active">  <i id="ember670" aria-hidden="true" class="ember-view fa fa-credit-card"><!----></i>
</a></li><li id="ember671" class="ember-view nav-button"><a id="ember672" href="/items" class="ember-view active">  <i id="ember673" aria-hidden="true" class="ember-view fa fa-shopping-cart"><!----></i>
</a></li><li id="ember674" class="ember-view nav-button"><a id="ember675" href="/items" class="ember-view active">  <i id="ember676" aria-hidden="true" class="ember-view fa fa-credit-card"><!----></i>
</a></li></ul><button class="nav__dropdown-toggle priority-nav__dropdown-toggle priority-nav-is-visible" prioritynav-count="4">menu</button></span>
</nav>

About forcing to move item to dropdown although there is enough space

Hi there!
THank you very much for so cool plugin. I really liked it. But I am having something buggily working menu. Here I have top menu which is being initialized the priority menu. But despite of enough space on view-1 and view4 menu for placing in the row menu item "Контакты" and "Акции" are being moved to dropdown. Why this is happening and how to make this plugin to work as I expect? Thank you very much.

Failed to execute 'insertBefore' on 'Node'

I got an error :
Uncaught NotFoundError: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.

What should I do?

nav-menu flashing

4gyf7uw5dz

Whenever i have refresh the page, more tab is flashing. how can i stop this flashing.

Below is the code which i have put in my code in document.ready function.

var wrapper = document.querySelector(".nav-wrapper");
var nav = priorityNav.init({
	    mainNavWrapper: ".nav-wrapper", // mainnav wrapper selector (must be direct parent from mainNav)
	    mainNav: ".nav-ul", // mainnav selector. (must be inline-block)
	    navDropdownLabel: 'More',
	    navDropdownClassName: "nav__dropdown", // class used for the dropdown.
	    navDropdownToggleClassName: "nav__dropdown-toggle", // class used for the dropdown toggle.
	    breakPoint: 1,
	});

how can i resolved this issue.

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.