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


Posted in Javascript onJune 26, 2016

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

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

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 );

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

Javascript 相关文章推荐
用js实现键盘方向键翻页功能的代码
Jun 03 Javascript
JS 模态对话框和非模态对话框操作技巧汇总
Apr 15 Javascript
Javascript弹出窗口的各种方法总结
Nov 11 Javascript
iframe跨域通信封装详解
Aug 11 Javascript
js实现具有高亮显示效果的多级菜单代码
Sep 01 Javascript
日常收集整理的JavaScript常用函数方法
Dec 10 Javascript
JavaScript基础知识及常用方法总结
Jan 10 Javascript
jQuery实现的自适应焦点图效果完整实例
Aug 24 Javascript
AngularJS ui-router刷新子页面路由的方法
Jul 23 Javascript
微信小程序扫描二维码获取信息实例详解
May 07 Javascript
layui table复选框禁止某几条勾选的实例
Sep 20 Javascript
javascript解析json格式的数据方法详解
Aug 07 Javascript
JS中的进制转换以及作用
Jun 26 #Javascript
JavaScript类型系统之布尔Boolean类型详解
Jun 26 #Javascript
基于JavaScript实现单选框下拉菜单添加文件效果
Jun 26 #Javascript
JQuery控制图片由中心点逐渐放大效果
Jun 26 #Javascript
JavaScript直播评论发弹幕切图功能点集合效果代码
Jun 26 #Javascript
jquery实现上传文件大小类型的验证例子(推荐)
Jun 25 #Javascript
jQuery实现对无序列表的排序功能(附demo源码下载)
Jun 25 #Javascript
You might like
php中使用Imagick实现图像直方图的实现代码
2011/08/30 PHP
PHP中文处理 中文字符串截取(mb_substr)和获取中文字符串字数
2011/11/10 PHP
iis下php mail函数的sendmail配置方法(官方推荐)
2012/04/25 PHP
PHP的foreach中使用引用时需要注意的一个问题和解决方法
2014/05/29 PHP
php数组中包含中文的排序方法
2014/06/03 PHP
php序列化函数serialize() 和 unserialize() 与原生函数对比
2015/05/08 PHP
PHP创建多级目录的两种方法
2016/10/28 PHP
jQuery中与toggleClass等价的程序段 以及未来学习的方向
2010/03/18 Javascript
通过js获取div的background-image属性
2013/10/15 Javascript
javascript中处理时间戳为日期格式的方法
2014/01/02 Javascript
JavaScript的Ext JS框架中的GridPanel组件使用指南
2016/05/21 Javascript
Node.js检测端口(port)是否被占用的简单示例
2016/09/29 Javascript
详解JavaScript中的属性和特性
2016/12/08 Javascript
vue组件父子间通信之综合练习(聊天室)
2017/11/07 Javascript
深入Node TCP模块的理解
2019/03/13 Javascript
如何基于vue-cli3.0构建功能完善的移动端架子
2019/04/24 Javascript
JQuery animate动画应用示例
2019/05/14 jQuery
简单分析js中的this的原理
2019/08/31 Javascript
使用Angular material主题定义自己的组件库的配色体系
2019/09/04 Javascript
如何基于filter实现网站整体变灰功能
2020/04/17 Javascript
js简单实现自动生成表格功能示例
2020/06/02 Javascript
Python图像处理之识别图像中的文字(实例讲解)
2018/05/10 Python
Python基于最小二乘法实现曲线拟合示例
2018/06/14 Python
使用Selenium破解新浪微博的四宫格验证码
2018/10/19 Python
在Python 不同级目录之间模块的调用方法
2019/01/19 Python
Django实现web端tailf日志文件功能及实例详解
2019/07/28 Python
Python线程条件变量Condition原理解析
2020/01/20 Python
Python3.7实现验证码登录方式代码实例
2020/02/14 Python
CSS3的column-fill属性对齐列内容高度的用法详解
2016/07/01 HTML / CSS
女方婚礼新郎答谢词
2014/01/11 职场文书
九月份红领巾广播稿
2014/01/22 职场文书
2014年元旦活动方案
2014/02/15 职场文书
创建精神文明单位实施方案
2014/03/08 职场文书
2015年高校辅导员工作总结
2015/04/20 职场文书
你会写报告?产品体验报告到底该怎么写?
2019/08/14 职场文书
Ajax异步刷新功能及简单案例
2021/11/20 Javascript