Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <title>KSL Assets Menu Demo</title>
  <meta name="description" content="KSL Assets Menu Demo" />
  <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
  <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" type="text/css" />
  <script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
  <link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
  <div class="ksl-assets container">
    <div class="inner">
      <div class="header">
        <div class="inner">
          <i class="fa fa-bars fa-2x menu-left-toggle"></i>
          <h1>Menu Demo</h1>
          <i class="fa fa-bars fa-2x menu-right-toggle"></i>
        </div>
      </div>
      <div class="content">
        <div class="header">
          <div class="reserved"></div>
        </div>
        <div class="ksl-assets menu menu-left">
          <div class="head">
            Menu
          </div>
          <div class="body">
            <ul>
              <li>Item 1</li>
              <li>Item 2</li>
              <li>Item 3</li>
              <li>Item 4</li>
              <li>Item 5</li>
              <li>Item 6</li>
              <li>Item 7</li>
              <li>Item 8</li>
              <li>Item 9</li>
              <li>Item 10</li>
              <li>Item 11</li>
              <li>Item 12</li>
              <li>Item 13</li>
              <li>Item 14</li>
              <li>Item 15</li>
              <li>Item 16</li>
              <li>Item 17</li>
              <li>Item 18</li>
              <li>Item 19</li>
              <li>Item 20</li>
            </ul>
          </div>
        </div>
        <div class="ksl-assets menu menu-right">
          <div class="inner">
            <div class="head">
              Right Menu
            </div>
            <div class="body">
              <ul>
                <li>Item 1</li>
                <li>Item 2</li>
                <li>Item 3</li>
                <li>Item 4</li>
                <li>Item 5</li>
                <li>Item 6</li>
                <li>Item 7</li>
                <li>Item 8</li>
                <li>Item 9</li>
                <li>Item 10</li>
                <li>Item 11</li>
                <li>Item 12</li>
                <li>Item 13</li>
                <li>Item 14</li>
                <li>Item 15</li>
                <li>Item 16</li>
                <li>Item 17</li>
                <li>Item 18</li>
                <li>Item 19</li>
                <li>Item 20</li>
              </ul>
            </div>
          </div>
        </div>
        <h3>Requirements</h3>
        <ul class="fa-ul issues">
          <li x><i class="fa-li fa"></i>Push the page over.</li>
          <li x><i class="fa-li fa"></i>Smooth animation.</li>
          <li x><i class="fa-li fa"></i>Disable vertical page scrolling when menu open.</li>
          <li x><i class="fa-li fa"></i>Disable horizontal page scrolling when menu open.</li>
          <li x><i class="fa-li fa"></i>Maintain page scroll position through opening and closing.</li>
          <li x><i class="fa-li fa"></i>Must play well with fixed position elements on screen.</li>
          <li x><i class="fa-li fa"></i>Reset scroll within the menu to top when opening a second time.</li>
          <li x><i class="fa-li fa"></i>Click outside to close (clicks should not trigger anything on the page, just close the menu).</li>
          <li x><i class="fa-li fa"></i>Menu scrolls independent of page.</li>
          <li x><i class="fa-li fa"></i>Smooth scrolling.</li>
          <li x><i class="fa-li fa"></i>Needs to be easy to pop back into page layout.</li>
          <li x><i class="fa-li fa"></i>Content should not get smooshed when menu is open.</li>
          <li x><i class="fa-li fa"></i>Right menu using modifier class.</li>
          <li x="?"><i class="fa-li fa"></i>Must meet requirements in Firefox, Chrome, Safari, Mobile Safari, IE10, IE11, Android.</li>
        </ul>
        <h3>Issues</h3>
        <ul class="fa-ul issues">
          <li x><i class="fa-li fa"></i>Mobile Safari: Address and tool bar in the way.</li>
          <li x><i class="fa-li fa"></i>Mobile Safari: Landscape pushes page up.</li>
          <li x><i class="fa-li fa"></i>IE8: Cannot scroll page after menu close.</li>
          <li x><i class="fa-li fa"></i>IE10, IE8: Click outside to close not working.</li>
          <li x><i class="fa-li fa"></i>Mobile Safari: Minor flicker. Verdict was "Good enough".</li>
          <li x><i class="fa-li fa"></i>Mobile Safari: Elements disappear when scrolling. Caused by `-webkit-overflow-scrolling: auto`.</li>
          <li x><i class="fa-li fa"></i>IE10, IE11: Reserved space for menu scroll bar between menu inner and rest of page rather than under the actual scroll bar.</li>
          <li x><i class="fa-li fa"></i>Mobile Safari: White background showing when you scroll past top or bottom of menu.</li>
          <li x><i class="fa-li fa"></i>Firefox: Css transition on page not working, while others on menu and header are. Odd.</li>
          <li><i class="fa-li fa"></i>Android 2.3 (released in 2010): Unable to scroll menu.</li>
        </ul>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus congue porta felis non fringilla. Etiam nisl turpis, volutpat ut ipsum id, semper ornare velit. Aliquam non lectus rhoncus, laoreet nisl eget, elementum nisi. Nullam diam ligula, faucibus quis orci rhoncus, blandit facilisis odio. Curabitur iaculis convallis felis ut iaculis. Etiam ut orci ullamcorper ligula elementum elementum vel at odio. Pellentesque feugiat lorem leo, non interdum nisl tristique nec. Suspendisse iaculis urna non convallis
        </p>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus congue porta felis non fringilla. Etiam nisl turpis, volutpat ut ipsum id, semper ornare velit. Aliquam non lectus rhoncus, laoreet nisl eget, elementum nisi. Nullam diam ligula, faucibus quis orci rhoncus, blandit facilisis odio. Curabitur iaculis convallis felis ut iaculis. Etiam ut orci ullamcorper ligula elementum elementum vel at odio. Pellentesque feugiat lorem leo, non interdum nisl tristique nec. Suspendisse iaculis urna non convallis
        </p>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus congue porta felis non fringilla. Etiam nisl turpis, volutpat ut ipsum id, semper ornare velit. Aliquam non lectus rhoncus, laoreet nisl eget, elementum nisi. Nullam diam ligula, faucibus quis orci rhoncus, blandit facilisis odio. Curabitur iaculis convallis felis ut iaculis. Etiam ut orci ullamcorper ligula elementum elementum vel at odio. Pellentesque feugiat lorem leo, non interdum nisl tristique nec. Suspendisse iaculis urna non convallis
        </p>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus congue porta felis non fringilla. Etiam nisl turpis, volutpat ut ipsum id, semper ornare velit. Aliquam non lectus rhoncus, laoreet nisl eget, elementum nisi. Nullam diam ligula, faucibus quis orci rhoncus, blandit facilisis odio. Curabitur iaculis convallis felis ut iaculis. Etiam ut orci ullamcorper ligula elementum elementum vel at odio. Pellentesque feugiat lorem leo, non interdum nisl tristique nec. Suspendisse iaculis urna non convallis
        </p>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus congue porta felis non fringilla. Etiam nisl turpis, volutpat ut ipsum id, semper ornare velit. Aliquam non lectus rhoncus, laoreet nisl eget, elementum nisi. Nullam diam ligula, faucibus quis orci rhoncus, blandit facilisis odio. Curabitur iaculis convallis felis ut iaculis. Etiam ut orci ullamcorper ligula elementum elementum vel at odio. Pellentesque feugiat lorem leo, non interdum nisl tristique nec. Suspendisse iaculis urna non convallis
        </p>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus congue porta felis non fringilla. Etiam nisl turpis, volutpat ut ipsum id, semper ornare velit. Aliquam non lectus rhoncus, laoreet nisl eget, elementum nisi. Nullam diam ligula, faucibus quis orci rhoncus, blandit facilisis odio. Curabitur iaculis convallis felis ut iaculis. Etiam ut orci ullamcorper ligula elementum elementum vel at odio. Pellentesque feugiat lorem leo, non interdum nisl tristique nec. Suspendisse iaculis urna non convallis
        </p>
        <p><a href="http://cdn.ebaumsworld.com/mediaFiles/picture/664379/80470643.gif">Fin</a></p>
      </div><!-- /.content -->
    </div><!-- /.inner -->
  </div><!-- /.container -->
  <script>
  $(function () {
    ksl.assets.menu($('.menu-left')).addToggles(
      $('.menu-left .head'),
      $('.header .menu-left-toggle')
    );
    ksl.assets.menu($('.menu-right')).addToggles(
      $('.menu-right .head'),
      $('.header .menu-right-toggle')
    );
  });
  </script>
  <style>
    /* decorative styles, irrelevant to menu */
    *, *:before, *:after {
      -webkit-box-sizing: inherit;
      -moz-box-sizing: inherit;
      box-sizing: inherit;
    }
    html {
      -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
      box-sizing: border-box;
    }
    body {
      margin: 0;
      padding: 0;
    }
    body > .container {
      padding: 0;
    }
    body > .container > .inner > .content {
      padding: 0 15px;
    }
    .header > .inner {
      position: absolute;
      top: 0;
      left: 0;
      z-index: 100;
      background-color: #0b162f;
      color: #fff;
      width: 100%;
      padding: 0 20px;
      height: 40px;
    }
    .header > .reserved {
      height: 40px;
    }
    .header h1 {
      display: inline-block;
      font-size: 2em;
      margin: 0;
      margin-left: 15px;
      line-height: 40px;
      white-space: nowrap;
    }
    .menu {
      background-color: #333;
      color: #fff;
    }
    .menu .head {
      background-color: #0b162f;
      padding: 0 20px;
      line-height: 40px;
      font-size: 2em;
    }
    .menu .body {
      padding-bottom: 20px;
    }
    .menu ul {
      list-style-type: none;
      padding: 0;
      margin: 0;
    }
    .menu li {
      padding: 10px 20px;
      font-size: 1.5em;
      border-bottom: 1px solid rgba(0,0,0,0.2);
    }
    .fa-ul {
      position: relative;
    }
    .issues li i {
      color: red;
    }
    .issues li i:before {
      content: "\f00d"; /* .fa-times */
      visibility: visible;
    }
    .issues li[x] {
      text-decoration: line-through;
    }
    .issues li[x] i {
      color: green;
    }
 
    .issues li[x] i:before {
      content: "\f00c"; /* .fa-check */
    }
    .issues li[x='?'] {
      text-decoration: none;
    }
    
    .issues li[x='?'] i:before {
      content: "\f128"; /* fa-question */
      color: blue;
    }
    .menu-right-toggle {
      position: absolute;
      right: 20px;
      top: 7px;
    }
    
    .ksl-assets.container > .inner > .overlay {
      background-color: rgba(0,0,0,.2);
    }
  </style>
</body>
</html>
 
var ksl = ksl || {};
ksl.assets = ksl.assets || {};
ksl.assets.menu = (function ($) {
  /* fix minimal-ui landscape problem */
  (function minimalUiFix() {
    var fix = function () {
      window.scrollTo(0,0);
    };
    $(fix);
    $(window).on('resize.minimal-ui-fix', fix);
  })();
  
  /*= helpers =*/
  var helpers = {};
  helpers.scrollCap = function ($element) {
    var getMinScrollTop = function () {
      return 1;
    };
    var getMaxScrollTop = function () {
      return $element.get(0).scrollHeight - $element.height() - 1;
    };
    
    var cap = function () {
      var scrollTop = $element.scrollTop();
      var minScrollTop = getMinScrollTop();
      var maxScrollTop = getMaxScrollTop();
      if (scrollTop < minScrollTop) {
        $element.scrollTop(minScrollTop);
      } else if (scrollTop > maxScrollTop) {
        $element.scrollTop(maxScrollTop);
      }
    };
    $element.on('touchstart.scroll-cap', cap);
    cap();
  };
  helpers.transitionEnd = function (namespace) {
    return $.map([
      'webkitTransitionEnd',
      'otransitionend',
      'oTransitionEnd',
      'msTransitionEnd',
      'transitionend'
    ], function (event) {
      return event + '.namespace';
    }).join(' ');
  };
  helpers.styleSupported = (function () {
    var supported = [];
    var check = function (property) {
      var body = document.body || document.documentElement;
      var style = body.style;
      // check for standard
      if (typeof style[property] == 'string') { return true; }
      // check for vendor specific
      var vendors = ['Moz', 'webkit', 'Webkit', 'Khtml', 'O', 'ms'];
      property = property.charAt(0).toUpperCase() + property.substr(1);
      for (var i = 0; i < vendors.length; i++) {
        var vendorProperty = vendors[i];
        if (typeof style[vendorProperty] == 'string') { return true; }
      }
      return false;
    };
    return function (property) {
      if (supported[property] === undefined) {
        supported[property] = check(property);
      }
      return supported[property];
    };
  })();
  /* Container constructor =*/
  var Container = function ($element) {
    /* private */
    var container = this;
    $element.addClass('ksl-assets container');
    helpers.scrollCap($element.find('> .inner > .content'));
    (function ensureOverlay($element) {
      var $inner = $element.find('> .inner');
      var $overlay = $inner.find('> .overlay');
      if ($overlay.length !== 0) { return; }
      $overlay = $('<div class="overlay"></div>');
      $overlay.prependTo($inner);
      $overlay.on('click', function (event) {
        $('.ksl-assets.menu.menu-open').trigger('close');
      });
    })($element);
    var lockScroll = function () {
      $element.addClass('scroll-lock');
    };
    var unlockScroll = (function () {
      var unlock = function () {
        $element.removeClass('scroll-lock');
      };
      if (!helpers.styleSupported('transition')) { return unlock; }
      var transitionEnd = helpers.transitionEnd('menu.container');
      return function () {
        $element.on(transitionEnd, function (event) {
          unlock();
          $element.off(transitionEnd);
        });
      };
    })();
    /* public */
    this.open = function (openClass) {
      $element.addClass(openClass);
      lockScroll();
    };
    this.close = function (openClass) {
      $element.removeClass(openClass);
      unlockScroll();
    };
  };
  /*= Menu constructor =*/
  var Menu = function ($element, $container) {
    /* private */
    $element.addClass('ksl-assets menu');
    var container = new Container($container);
    var menu = this;
    var containerClass = $element.hasClass('menu-right') ? 'menu-right-open' : 'menu-open';
    /* public */
    this.isOpen = function () {
      return $element.hasClass('menu-open');
    };
    this.open = function () {
      $element.trigger('open');
    };
    this.close = function () {
      $element.trigger('close');
    };
    this.toggle = function () {
      $element.trigger('toggle');
    };
    this.addToggles = function ($toggle1, $toggle2, $toggle3) {
      var toggles = Array.prototype.slice.apply(arguments);
      $.each(toggles, function (index, $toggle) {
        $toggle.on('click', function () {
          menu.toggle();
        });
      });
    };
    /*= events =*/
    $element.on('open', function () {
      $element.scrollTop(0);
      $element.addClass('menu-open');
      container.open(containerClass);
    });
    $element.on('close', function () {
      $element.removeClass('menu-open');
      container.close(containerClass);
    });
    $element.on('toggle', function () {
      if (menu.isOpen()) {
        $element.trigger('close');
      } else {
        $element.trigger('open');
      }
    });
    $element.on('click', function (event) {
      if (event.target === $element.get(0)) {
        $element.trigger('close');
      }
    });
    var transitionEnd = (helpers.styleSupported('transition')) ? helpers.transitionEnd('menu') : 'open close';
    $element.on(transitionEnd, function (event) {
      if (menu.isOpen()) {
        $element.trigger('opened');
      } else {
        $element.trigger('closed');
      }
    });
    helpers.scrollCap($element);
  };
  /*= menu function =*/
  var menu = function ($element, $toggles) {
    $element = $element.eq(0); // only handles one menu at a time
    var api = $element.data('menu-api');
    if (!api) {
      var $container = $('body > .container');
      api = new Menu($element, $container);
      $element.data('menu-api');
    }
    return api;
  };
  /*= jquery plugin =*/
  if (!$.fn.menu) {
    $.fn.menu = function () { return menu(this); };
  }
  return menu;
})(jQuery);
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
jehoshua02pro
0viewers