js css实现垂直方向自适应的三角提示菜单

这是一个比较简单实用的菜单,最重要的是他不需要引用jQuery库。菜单在垂直方向上能做到自适应,当主菜单靠近顶部,子菜单将会在下面,当主菜单靠近底部,子菜单在上面。运用Modernizr的触摸检测功能,我们可以让子菜单的响应在pc上是hover,而在触摸设备上是点击。例子中还示范了如何在宽度比较窄的情况下如何调整布局。

html代码

<ul id="cbp-tm-menu" class="cbp-tm-menu">
  <li>
    <a href="#">Home</a>
  </li>
  <li>
    <a href="#">Veggie made</a>
    <ul class="cbp-tm-submenu">
      <li><a href="#" class="cbp-tm-icon-archive">Sorrel desert</a></li>
      <li><a href="#" class="cbp-tm-icon-cog">Raisin kakadu</a></li>
      <li><a href="#" class="cbp-tm-icon-location">Plum salsify</a></li>
      <li><a href="#" class="cbp-tm-icon-users">Bok choy celtuce</a></li>
      <li><a href="#" class="cbp-tm-icon-earth">Onion endive</a></li>
      <li><a href="#" class="cbp-tm-icon-location">Bitterleaf</a></li>
      <li><a href="#" class="cbp-tm-icon-mobile">Sea lettuce</a></li>
    </ul>
  </li>
  <li>
    <a href="#">Pepper tatsoi</a>
    <ul class="cbp-tm-submenu">
      <li><a href="#" class="cbp-tm-icon-archive">Brussels sprout</a></li>
      <li><a href="#" class="cbp-tm-icon-cog">Kakadu lemon</a></li>
      <li><a href="#" class="cbp-tm-icon-link">Juice green</a></li>
      <li><a href="#" class="cbp-tm-icon-users">Wine fruit</a></li>
      <li><a href="#" class="cbp-tm-icon-earth">Garlic mint</a></li>
      <li><a href="#" class="cbp-tm-icon-location">Zucchini garnish</a></li>
      <li><a href="#" class="cbp-tm-icon-mobile">Sea lettuce</a></li>
    </ul>
  </li>
  <li>
    <a href="#">Sweet melon</a>
    <ul class="cbp-tm-submenu">
      <li><a href="#" class="cbp-tm-icon-screen">Sorrel desert</a></li>
      <li><a href="#" class="cbp-tm-icon-mail">Raisin kakadu</a></li>
      <li><a href="#" class="cbp-tm-icon-contract">Plum salsify</a></li>
      <li><a href="#" class="cbp-tm-icon-pencil">Bok choy celtuce</a></li>
      <li><a href="#" class="cbp-tm-icon-article">Onion endive</a></li>
      <li><a href="#" class="cbp-tm-icon-clock">Bitterleaf</a></li>
    </ul>
  </li>
</ul>

css代码

/* Iconfont made with icomoon.com */
@font-face {
  font-family: 'cbp-tmicons';
  src:url('../fonts/tmicons/cbp-tmicons.eot');
  src:url('../fonts/tmicons/cbp-tmicons.eot?#iefix') format('embedded-opentype'),
    url('../fonts/tmicons/cbp-tmicons.woff') format('woff'),
    url('../fonts/tmicons/cbp-tmicons.ttf') format('truetype'),
    url('../fonts/tmicons/cbp-tmicons.svg#cbp-tmicons') format('svg');
  font-weight: normal;
  font-style: normal;
}

/* reset list style */
.cbp-tm-menu,
.cbp-tm-menu ul {
  list-style: none;
}

/* set menu position; change here to set to relative or float, etc. */
.cbp-tm-menu {
  display: block;
  position: absolute;
  z-index: 1000;
  bottom: 0;
  width: 100%;
  background: #47a3da;
  text-align: right;
  padding: 0 2em;
  margin: 0;
  text-transform: capitalize;
}

/* first level menu items */
.cbp-tm-menu > li {
  display: inline-block;
  margin: 0 2.6em;
  position: relative;
}

.cbp-tm-menu > li > a {
  line-height: 4em;
  padding: 0 0.3em;
  font-size: 1.2em;
  display: block;
  color: #fff;
}

.no-touch .cbp-tm-menu > li > a:hover,
.no-touch .cbp-tm-menu > li > a:active {
  color: #02639d;
}

/* sumbenu with transitions */
.cbp-tm-submenu {
  position: absolute;
  display: block;
  visibility: hidden;
  opacity: 0;
  padding: 0;
  text-align: left;
  pointer-events: none;
  -webkit-transition: visibility 0s, opacity 0s;
  -moz-transition: visibility 0s, opacity 0s;
  transition: visibility 0s, opacity 0s;
}

.cbp-tm-show .cbp-tm-submenu {
  width: 16em;
  left: 50%;
  margin: 0 0 0 -8em;
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  -webkit-transition: visibility 0s, opacity 0.3s;
  -moz-transition: visibility 0s, opacity 0.3s;
  transition: visibility 0s, opacity 0.3s;
}

.cbp-tm-show-above .cbp-tm-submenu {
  bottom: 100%;
  padding-bottom: 10px;
}

.cbp-tm-show-below .cbp-tm-submenu {
  top: 100%;
  padding-top: 10px;
}

/* extreme cases: not enough space on the sides */
.cbp-tm-nospace-right .cbp-tm-submenu {
  right: 0;
  left: auto;
}

.cbp-tm-nospace-left .cbp-tm-submenu {
  left: 0;
}

/* last menu item has to fit on the screen */
.cbp-tm-menu > li:last-child .cbp-tm-submenu {
  right: 0;
}

/*
arrow: depending on where the menu will be shown, we set
the right position for the arrow
*/

.cbp-tm-submenu:after {
  border: solid transparent;
  content: " ";
  height: 0;
  width: 0;
  position: absolute;
  pointer-events: none;
}

.cbp-tm-show-above .cbp-tm-submenu:after {
  top: 100%;
  margin-top: -10px;
}

.cbp-tm-show-below .cbp-tm-submenu:after {
  bottom: 100%;
  margin-bottom: -10px;
}

.cbp-tm-submenu:after {
  border-color: transparent;
  border-width: 16px;
  margin-left: -16px;
  left: 50%;
}

.cbp-tm-show-above .cbp-tm-submenu:after {
  border-top-color: #fff;
}

.cbp-tm-show-below .cbp-tm-submenu:after {
  border-bottom-color: #fff;
}

.cbp-tm-submenu > li {
  display: block;
  background: #fff;
}

.cbp-tm-submenu > li > a {
  padding: 5px 2.3em 5px 0.6em; /* top/bottom paddings in 'em' cause a tiny "jump" in Chrome on Win */
  display: block;
  font-size: 1.2em;
  position: relative;
  color: #47a3da;
  border: 4px solid #fff;
  -webkit-transition: all 0.2s;
  -moz-transition: all 0.2s;
  transition: all 0.2s;
}

.no-touch .cbp-tm-submenu > li > a:hover,
.no-touch .cbp-tm-submenu > li > a:active {
  color: #fff;
  background: #47a3da;
}

/* the icons (main level menu icon and sublevel icons) */
.cbp-tm-submenu li a:before,
.cbp-tm-menu > li > a:before {
  font-family: 'cbp-tmicons';
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  line-height: 1;
  vertical-align: middle;
  margin-right: 0.6em;
  -webkit-font-smoothing: antialiased;
}

.cbp-tm-submenu li a:before {
  position: absolute;
  top: 50%;
  margin-top: -0.5em;
  right: 0.5em;
}

.cbp-tm-menu > li > a:not(:only-child):before {
  content: "\f0c9";
  font-size: 60%;
  opacity: 0.3;
}

.cbp-tm-icon-archive:before {
  content: "\e002";
}

.cbp-tm-icon-cog:before {
  content: "\e003";
}

.cbp-tm-icon-users:before {
  content: "\e004";
}

.cbp-tm-icon-earth:before {
  content: "\e005";
}

.cbp-tm-icon-location:before {
  content: "\e006";
}

.cbp-tm-icon-mobile:before {
  content: "\e007";
}

.cbp-tm-icon-screen:before {
  content: "\e008";
}

.cbp-tm-icon-mail:before {
  content: "\e009";
}

.cbp-tm-icon-contract:before {
  content: "\e00a";
}

.cbp-tm-icon-pencil:before {
  content: "\e00b";
}

.cbp-tm-icon-article:before {
  content: "\e00c";
}

.cbp-tm-icon-clock:before {
  content: "\e00d";
}

.cbp-tm-icon-videos:before {
  content: "\e00e";
}

.cbp-tm-icon-pictures:before {
  content: "\e00f";
}

.cbp-tm-icon-link:before {
  content: "\e010";
}

.cbp-tm-icon-refresh:before {
  content: "\e011";
}

.cbp-tm-icon-help:before {
  content: "\e012";
}

/* Media Queries */
@media screen and (max-width: 55.6875em) {
  .cbp-tm-menu {
    font-size: 80%;
  }
}

@media screen and (max-height: 25.25em), screen and (max-width: 44.3125em) {

  .cbp-tm-menu {
    font-size: 100%;
    position: relative;
    text-align: center;
    padding: 0;
    top: auto;
  }

  .cbp-tm-menu > li {
    display: block;
    margin: 0;
    border-bottom: 4px solid #3793ca;
  }

  .cbp-tm-menu > li:first-child {
    border-top: 4px solid #3793ca;
  }

  li.cbp-tm-show > a,
  .no-touch .cbp-tm-menu > li > a:hover,
  .no-touch .cbp-tm-menu > li > a:active {
    color: #fff;
    background: #02639d;
  }

  .cbp-tm-submenu {
    position: relative;
    display: none;
    width: 100%;
  }

  .cbp-tm-submenu > li {
    padding: 0;
  }

  .cbp-tm-submenu > li > a {
    padding: 0.6em 2.3em 0.6em 0.6em;
    border: none;
    border-bottom: 2px solid #6fbbe9;
  }

  .cbp-tm-submenu:after {
    display: none;
  }

  .cbp-tm-menu .cbp-tm-show .cbp-tm-submenu {
    display: block;
    width: 100%;
    left: 0;
    margin: 0;
    padding: 0;
    bottom: auto;
    top: auto;
  }

}

javascript代码

/**
 * cbpTooltipMenu.js v1.0.0
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright 2013, Codrops
 * http://www.codrops.com
 */
;( function( window ) {

  'use strict';

  var document = window.document,
    docElem = document.documentElement;

  function extend( a, b ) {
    for( var key in b ) {
      if( b.hasOwnProperty( key ) ) {
        a[key] = b[key];
      }
    }
    return a;
  }

  // from https://github.com/ryanve/response.js/blob/master/response.js
  function getViewportH() {
    var client = docElem['clientHeight'],
      inner = window['innerHeight'];
    if( client < inner )
      return inner;
    else
      return client;
  }

  // http://stackoverflow.com/a/11396681/989439
  function getOffset( el ) {
    return el.getBoundingClientRect();
  }

  // http://snipplr.com/view.php?codeview&id=5259
  function isMouseLeaveOrEnter(e, handler) {
    if (e.type != 'mouseout' && e.type != 'mouseover') return false;
    var reltg = e.relatedTarget ? e.relatedTarget :
    e.type == 'mouseout' ? e.toElement : e.fromElement;
    while (reltg && reltg != handler) reltg = reltg.parentNode;
    return (reltg != handler);
  }

  function cbpTooltipMenu( el, options ) {
    this.el = el;
    this.options = extend( this.defaults, options );
    this._init();
  }

  cbpTooltipMenu.prototype = {
    defaults : {
      // add a timeout to avoid the menu to open instantly
      delayMenu : 100
    },
    _init : function() {
      this.touch = Modernizr.touch;
      this.menuItems = document.querySelectorAll( '#' + this.el.id + ' > li' );
      this._initEvents();
    },
    _initEvents : function() {

      var self = this;

      Array.prototype.slice.call( this.menuItems ).forEach( function( el, i ) {
        var trigger = el.querySelector( 'a' );
        if( self.touch ) {
          trigger.addEventListener( 'click', function( ev ) { self._handleClick( this, ev ); } );
        }
        else {
          trigger.addEventListener( 'click', function( ev ) {
            if( this.parentNode.querySelector( 'ul.cbp-tm-submenu' ) ) {
              ev.preventDefault();
            }
          } );
          el.addEventListener( 'mouseover', function(ev) { if( isMouseLeaveOrEnter( ev, this ) ) self._openMenu( this ); } );
          el.addEventListener( 'mouseout', function(ev) { if( isMouseLeaveOrEnter( ev, this ) ) self._closeMenu( this ); } );
        }
      } );

    },
    _openMenu : function( el ) {

      var self = this;
      clearTimeout( this.omtimeout );
      this.omtimeout = setTimeout( function() {
        var submenu = el.querySelector( 'ul.cbp-tm-submenu' );

        if( submenu ) {
          el.className = 'cbp-tm-show';
          if( self._positionMenu( el ) === 'top' ) {
            el.className += ' cbp-tm-show-above';
          }
          else {
            el.className += ' cbp-tm-show-below';
          }
        }
      }, this.touch ? 0 : this.options.delayMenu );

    },
    _closeMenu : function( el ) {

      clearTimeout( this.omtimeout );

      var submenu = el.querySelector( 'ul.cbp-tm-submenu' );

      if( submenu ) {
        // based on https://github.com/desandro/classie/blob/master/classie.js
        el.className = el.className.replace(new RegExp("(^|\\s+)" + "cbp-tm-show" + "(\\s+|$)"), ' ');
        el.className = el.className.replace(new RegExp("(^|\\s+)" + "cbp-tm-show-below" + "(\\s+|$)"), ' ');
        el.className = el.className.replace(new RegExp("(^|\\s+)" + "cbp-tm-show-above" + "(\\s+|$)"), ' ');
      }

    },
    _handleClick : function( el, ev ) {
      var item = el.parentNode,
        items = Array.prototype.slice.call( this.menuItems ),
        submenu = item.querySelector( 'ul.cbp-tm-submenu' )

      // first close any opened one..
      if( this.current && items.indexOf( item ) !== this.current ) {
        this._closeMenu( this.el.children[ this.current ] );
        this.el.children[ this.current ].querySelector( 'ul.cbp-tm-submenu' ).setAttribute( 'data-open', 'false' );
      }

      if( submenu ) {
        ev.preventDefault();

        var isOpen = submenu.getAttribute( 'data-open' );

        if( isOpen === 'true' ) {
          this._closeMenu( item );
          submenu.setAttribute( 'data-open', 'false' );
        }
        else {
          this._openMenu( item );
          this.current = items.indexOf( item );
          submenu.setAttribute( 'data-open', 'true' );
        }
      }

    },
    _positionMenu : function( el ) {
      // checking where's more space left in the viewport: above or below the element
      var vH = getViewportH(),
        ot = getOffset(el),
        spaceUp = ot.top ,
        spaceDown = vH - spaceUp - el.offsetHeight;

      return ( spaceDown <= spaceUp ? 'top' : 'bottom' );
    }
  }

  // add to global namespace
  window.cbpTooltipMenu = cbpTooltipMenu;

} )( window );

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • CSS JavaScript 实现菜单功能 改进版

    改进版本优化了这个问题,通过简单的Javascript代码就可以增加菜单.同时使得HTML页面非常简洁,只需要写2行代码即可!O(∩_∩)O 1.使用前提,在HTML页面中引入一个CSS文件,和一个JavaScript文件.如下: 复制代码 代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>Menu</T

  • css+js下拉菜单

    css菜单演示 0? " ": "") + "sfhover"; } sfEls[i].onMouseDown=function() { this.className+=(this.className.length>0? " ": "") + "sfhover"; } sfEls[i].onMouseUp=function() { this.className+=(this.cla

  • 通用的二级菜单代码(css+javascript)

    ]但在<CSS二级菜单>中,如果一级菜单中的超链接是#,那么只要单击该一级菜单,那么与这个一级菜单对应的二级菜单就会一直显示在网页中,不能隐藏,是一个小小的bug.后来仔细的想了一想,其实,无论是什么样的二级菜单,原理都是一样的: 1.每一个一级菜单都会对应一个层,而这个层里放着的就是该一级菜单对应的二级菜单. 2.默认情况下,二级菜单这个层是隐藏的,在CSS中将层的display属性值设为none,可以达到这一目的. 3.当鼠标放在一级菜单上时,将对应的二级菜单层显示出来,在CSS中将层的d

  • JS+CSS 制作的超级简单的下拉菜单附图

    先看效果:  代码: 复制代码 代码如下: <html> <head> <title>Good Test</title> <script> function showSubMenu(SubMenu) { document.getElementById(SubMenu).style.display = "inline"; } function HideSubMenu(SubMenu) { document.getElementB

  • Div+Css(+Js)菜单代码及制作工具

    效果直逼flash的Div+Css+Js菜单 css菜单 body{ background-color:#B8B8A0; } #fbtn{ display:none; overflow:hidden; border-style:solid; border-width:1px; border-color:#e1e1c9 #e1e1c9 #6e6e56 #6e6e56; padding:1 1 1 1; width:115px; height:30px; } #fbtn_txt{ position:

  • JavaScript CSS创建右击菜单效果代码

    效果图:  css和javascript创建页面右键菜单 body { font-family: "宋体"; font-size: 12px; } .skin0 { padding-top: 4px; text-align: left; width: 100px; border: 2px solid black; background-color: menu; font-family: "宋体"; line-height: 20px; cursor: default

  • Div+CSS+JS树型菜单,可刷新

    搞了一个DIV+CSS菜单,兼容Firefox,分享给大家,大家一齐学习 Div+CSS+JS树型菜单,可刷新 #PARENT{ width:300px; padding-left:20px; } 我的网站 [url]www.netany.net[/url] [url]www.netany.net[/url] [url]www.netany.net[/url] 我的帐务 支付 网上支付 登记汇款 在线招领 历史帐务 网站管理 登录 管理 管理 管理 网站管理 登录 管理 管理 管理 工作需要搞了

  • JavaScript CSS 菜单功能代码

    Menu #menubar { font-family:verdana; font-size:12px; margin:1px; } #menubar li { float:left; position:relative; text-align:left; } /* each menu item style */ #menubar li a { border-style:none; color:black; display:block; width:150px; height:20px; lin

  • 无js5款纯div+css制作的弹出菜单标准

    一.最基本的:二级dropdown弹出菜单 二级dropdown弹出菜单--A CROSS BROWSER Drop DOWN CASCADING VALIDATING MENU /* common styling */ /* set up the overall width of the menu div, the font and the margins */ .menu { font-family: arial, sans-serif; width:750px; margin:0; mar

  • js+css实现tab菜单切换效果的方法

    本文实例讲述了js+css实现tab菜单切换效果的方法.分享给大家供大家参考.具体实现方法如下: index.css如下: 复制代码 代码如下: * {      margin: 0px;      padding: 0px;  }  body {      width: 600px;      margin: 0 auto;      background-color: silver;  }    #contanier {      background-color: yellow;     

随机推荐