pulling

Flexible slideout menu for mobile webapps

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
pulling
712.0.13 years ago7 years agoMinified + gzip package size for pulling in KB

Readme

Pulling
Flexible slideout menu for mobile webapps
const panel = document.querySelector('#panel');
const toggle = document.querySelectorAll('#toggle');
const menu = document.querySelector('#menu');

const pullin = Pulling.create({
  menu,
  panel,
});

toggle.addEventListener('click', () => pullin.toggle());

Installation

Pulling is available on npm.
- npm install pulling - yarn add pulling

Features

  • Flicking gesture support
  • Supports multiple slideout menus
  • Standalone, dependency-free
  • Simple markup
  • Native scrolling
  • Easy customization
  • CSS transforms & transitions
  • Two different display modes
  • Just 10 Kb!

Usage

You just need a panel for your main content and a menu element:
<nav id="menu">
  <header>
    <h2>Menu</h2>
  </header>
</nav>

<main id="panel">
  <header>
    <h2>Panel</h2>
  </header>
</main>

Styling is simple, too. The library handles most things for you, so just add a background on your panel and menu, and add a min-height on the panel if you're using the reveal mode.
Then include Pulling and set up the menu.
const panel = document.querySelector('#panel');
const menu = document.querySelector('#menu');

const pullin = Pulling.create({
  menu,
  panel,
});

See test.html for a full example.

Browser Support

  • Chrome (IOS, Android, desktop)
  • Firefox (Android, desktop)
  • Safari (IOS, Android, desktop)
  • Opera (desktop)
  • IE 10+ (desktop and mobile)
API

Pulling.create(options)

Creates a new Pulling instance

options

  • menu - Element

DOM element of menu
  • panel - Element

DOM element of panel
  • side - "left" | "right" (default: left)

side menu should display on
  • mode - "drawer" | "reveal" (default: drawer)

whether the menu slide over the panel (drawer) or the panel should slide to reveal the menu (reveal)
  • margin - number (default: 25)

the number of pixels from the edge of the viewport in which a touch event will be accepted
  • timing - number (default: 200)

milliseconds of the transition animation for opening and closing, in the case where it isn't pulled out manually
  • timingFunction - string (default: ease)

CSS3 transition timing function
  • width - number (default: 256)

width of menu in pixels
  • sensitivity - number (default: 0.25)

the speed needed to activate a flick
  • slope - number (default: 0.5)

maximum ratio of vertical touch movement to horizontal touch movement that should be accepted
  • touch - boolean (default: true)

Enable touch functionality
  • ignoreScrollables - boolean (default: true)

Ignore horizontally scrollable elements

Instance Methods

All methods are chainable

#open()

Opens the menu. Emits beforeopen and opened events.

#close()

Closes the menu. Emits beforeclose and closed events.

#toggle(condition?: boolean)

Toggles the state of the menu (closed -> open, open -> closed).
+ If condition === true, it opens the menu + If condition === false, it closes the menu

#on(eventName: string, handler: Function)

Add an event handler for the event

#off(eventName: string, handler?: Function)

Remove an event handler for the event, or remove all handlers for the event

#ignore(selector: string)

Ignore touch events from a specific selector

#unignore(selector: string)

Remove selector from ignore list. Will not override ignored selectors.

#disable()

Disable all functionality of the menu

#enable()

Enable the menu's functionality

#disableTouch()

Disable touch event functionality for this menu

#enableTouch()

Enable touch event functionality for this menu

Events

  • beforeclose
Emitted before close begins, including when dragging closed with touch
  • closed
Emitted after close completes
  • beforeopen
Emitted before open begins, including when dragging open with touch
  • opened
Emitted after open completes
  • touchstart
Emitted when a touch movement begins
  • touchmove
Emitted on every movement due to touch
  • touchend
Emitted when a touch movement ends
You can use these to support multiple menus by disabling one when the other opens:
pullinLeft.on('beforeopen', () => pullinRight.disableTouch());
pullinLeft.on('closed', () => pullinRight.enableTouch());
pullinRight.on('beforeopen', () => pullinLeft.disableTouch());
pullinRight.on('closed', () => pullinLeft.enableTouch());

State

  • .state.closed - boolean
  • .state.closing - boolean
  • .state.open - boolean
  • .state.opening - boolean

FAQ

How do I prevent it from opening when scrolling through a carousel?

You can either use .ignore(selector) to add the specific element selector to the ignore list, or you can do .ignore('[data-pullin-ignore]') to add that selector the the list and then just add the data-pullin-ignore attribute to every element you want ignored.

How do I add a toggle button?

// vanilla js
document.querySelector('.toggle-menu').addEventListener('click', () => pullin.toggle());

// jQuery
$('.toggle-menu').on('click', () => pullin.toggle());

How do I use two menus, one on each side?

You'll want to use events to keep one menu disabled while the other is open.
pullinLeft.on('beforeopen', () => {
  pullinRight.close().disableTouch();
});
pullinLeft.on('closed', () => pullinRight.enableTouch());
pullinRight.on('beforeopen', () => {
  pullinLeft.close().disableTouch();
});
pullinRight.on('closed', () => pullinLeft.enableTouch());