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

前端之家收集整理的这篇文章主要介绍了js css实现垂直方向自适应的三角提示菜单前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

HTML代码

<div class="jb51code">
<pre class="brush:xhtml;">
<ul id="cbp-tm-menu" class="cbp-tm-menu">

  • css代码

    / 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代码

    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( 'mou<a href="/tag/SEO/" title="SEO">SEO</a>ver',function(ev) { if( isMouseLeaveOrEnter( ev,this ) ) self._openMenu( this ); } );
          el.addEventListener( 'mou<a href="/tag/SEO/" title="SEO">SEO</a>ut',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 );

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

    猜你在找的JavaScript相关文章