在前文 创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件 中,实现了DropDownList的JQuery组件,但是留有遗憾。就是当下拉菜单出现滚动条的时候,滚动条会覆盖菜单右侧的两个圆角。使得下拉菜单左侧有2个圆角,右侧没有,看上去不是很完美。如下图所示:

 

本文的内容就是如何恢复右侧的圆角

 

先看看原本的下拉菜单的HTML结构:

 

.sh_darkness{background:none; padding:0; margin:0; border:0 none;}.sh_darkness .sh_sourcecode{background-color:#000;color:#fff;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_keyword{color:#ff0;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_type{color:#0f0;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_string{color:#abab00;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_regexp{color:#abab00;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_specialchar{color:#bfbfbf;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_comment{color:#888;font-weight:normal;font-style:italic;}.sh_darkness .sh_sourcecode .sh_number{color:#619de7;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_preproc{color:#1da3cf;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_symbol{color:#f0f;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_function{color:#f34627;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_cbracket{color:#f0f;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_url{color:#abab00;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_date{color:#ff0;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_time{color:#ff0;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_file{color:#ff0;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_ip{color:#abab00;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_name{color:#abab00;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_variable{color:#26e0e7;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_oldfile{color:#bfbfbf;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_newfile{color:#abab00;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_difflines{color:#ff0;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_selector{color:#26e0e7;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_property{color:#ff0;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_value{color:#abab00;font-weight:bold;font-style:normal;}

/*-------- Snippet Base Styles ----------*/
.snippet-wrap {position:relative;}
*:first-child+html .snippet-wrap {display:inline-block;}
* html .snippet-wrap {display:inline-block;}
.snippet-wrap .snippet-menu {position:absolute; top:10px; right:15px; font-size:.9em;z-index:1;background-color:transparent; width:50%; text-align:right;}
.snippet-wrap .snippet-menu pre {background-color:transparent; margin:0; padding:0;}
.snippet-wrap .snippet-menu a {padding:0 5px; text-decoration:underline;}
.snippet-wrap pre.sh_sourcecode{padding:1em;line-height:1.8em;overflow:auto;position:relative;
-moz-border-radius:15px 0px 15px 0px;
-webkit-border-radius:15px 0px 15px 0px;
border-radius:15px 0px 15px 0px;
}
.snippet-wrap pre.snippet-textonly {padding:2em;}
*:first-child+html .snippet-wrap pre.snippet-formatted {padding:2em 1em;}
* html .snippet-wrap pre.snippet-formatted {padding:2em 1em;}
.snippet-wrap .snippet-no-num{list-style:none !important; padding:.6em 1em; margin:0 !important;}
.snippet-wrap .snippet-no-num li {list-style:none; padding-left:0; margin:0px;}

.snippet-container{width:80%;word-wrap:break-word;}

  • <ul class="dropdown-menu dropdown-menu-right" role="menu">
  •     <li><a href="#">Action</a></li>
  •     <li><a href="#">Another action</a></li>
  •     <li><a href="#">Something else here</a></li>
  •     <li class="divider"></li>
  •     <li><a href="#">Separated link</a></li>
  • </ul>

 

从上面的结构可以看出,由ul标签实现下拉菜单的外观(通过引用dropdown-menu样式),由li标签实现菜单项(包括菜单、分隔符、组标题)。来看看ul和li标签对应的CSS:

 

  • .dropdown-menu {
  •   position: absolute;
  •   top: 100%;
  •   left: 0;
  •   z-index: 1000;
  •   display: none;
  •   float: left;
  •   min-width: 160px;
  •   padding: 5px 0;
  •   margin: 2px 0 0;
  •   font-size: 14px;
  •   text-align: left;
  •   list-style: none;
  •   background-color: #fff;
  •   -webkit-background-clip: padding-box;
  •           background-clip: padding-box;
  •   border: 1px solid #ccc;
  •   border: 1px solid rgba(0, 0, 0, .15);
  •   border-radius: 4px;
  •   -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
  •           box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
  • }
  •  
  • .dropdown-menu > li > a {
  •   display: block;
  •   padding: 3px 20px;
  •   clear: both;
  •   font-weight: normal;
  •   line-height: 1.42857143;
  •   color: #333;
  •   white-space: nowrap;
  • }
  •  
  • .dropdown-menu > li > a:hover,
  • .dropdown-menu > li > a:focus {
  •   color: #262626;
  •   text-decoration: none;
  •   background-color: #f5f5f5;
  • }

 

由于a的样式是通过.dropdown-menu > li > a来实现的,故要实现a的外观必须是在含有样式dropdown-menu的ul里面的li的里面的a的。

 

于是,动了一个念头,在HTML结构里的ul里面的li里再嵌套一个包含样式dropdown-menu的ul,ul里面是li,li里面是a。

但是从上面的CSS可以看出,嵌套在里面的ul也会实现菜单的外观(圆角、投影、浮动等),故在该ul的标签里强制添加style属性,把一些样式强制性的去除(改成inherit,采用默认样式),这些样式包括display、position、top、float、padding、border、border-radius、-webkit-box-shadow、box-shadow。

 

再说说MaxHeight。本次修改后直接采用CSS的样式max-height,而减少对菜单高度的判断。会有疑问,如果浏览器不支持max-height怎么办?一是不支持max-height的浏览器比较少(IE6等),二是如果浏览器不支持max-height,也就不能很好的支持Bootstrap。故不必考虑浏览器是否支持max-height属性。由于里外有2个ul标签,我们需要对里面的ul标签应用max-height属性,故用UL=Obj.find("ul[style]")语句来找寻里面的ul标签(因为里面的ul含有style属性,而外面的ul没有)。

 

再说说JQuery的height方法。当调用JQuery的height方法来计算隐藏元素高度时,估计是先会显示元素,然后计算高度,再隐藏元素。这会有两个问题。一是显示再隐藏,速度很快,肉眼看不出,但是浏览器不会说谎,有时浏览器会额外显示滚动条。二是如果该元素的父元素也是隐藏的,则height方法会返回0。

 

完善版的源代码:

 

  • (function($){
  •     jQuery.fn.DropDownList = function(options) {
  •         var defaults ={
  •             InputName:"Q",
  •             ButtonText:"示例",
  •             ReadOnly:true,
  •             MaxHeight:-1,
  •             onSelect:$.noop(),
  •         }
  •  
  •         var options = $.extend(defaults,options);
  •  
  •         return this.each(function(){
  •             var o=options;
  •             var Obj=$(this);
  •  
  •             var S="<div class='input-group'>";
  •             S = S + "<input type='text' class='form-control' name='" + o.InputName + "' id='" + o.InputName + "'  />";
  •             S = S + "<div class='input-group-btn'>";
  •             S = S + "<button type='button' class='btn btn-default dropdown-toggle' data-toggle='dropdown'>" + o.ButtonText + " <span class='caret'></span></button>";
  •             S = S + "<ul class='dropdown-menu dropdown-menu-right' role='menu' >";
  •             S = S + "<li><ul class='dropdown-menu ' style='display:inherit;position:inherit;top:0;float:inherit;padding:0;border:0px;border-radius:0px;-webkit-box-shadow: inherit;box-shadow: inherit;'>";
  •  
  •             var SelText,SelData;
  •  
  •             if (o.Sections!== undefined)
  •                 {
  •                     $.each(o.Sections,function(n,value){
  •                         if (n>0) {S=S + "<li class='divider'></li>";}
  •                         if (value.ItemHeader!==undefined) {S = S + "<li class='dropdown-header'>" + value.ItemHeader + "</li>";}
  •                         CreateItem(value);
  •                     });
  •                 }
  •             else
  •                 {
  •                     CreateItem(o);
  •                 }
  •   
  •             function CreateItem(Items)
  •             {
  •                 $.each(Items.Items,function(n,Item){
  •                     if (Item.ItemData===undefined) {Item.ItemData=Item.ItemText;}
  •                     S=S + "<li><a href='#' ItemData='"  + Item.ItemData + "' >" + Item.ItemText + "</a></li>";
  •                     if (Item.Selected==true) {SelText=Item.ItemText;SelData=Item.ItemData;}
  •                 });
  •             }
  •   
  •             S =S + "</ul></li></ul></div></div>";
  •  
  •             Obj.html(S);
  •  
  •             var Input=Obj.find("input");
  •  
  •             if (SelText!="") {SetData(SelText,SelData);}
  •  
  •             Obj.find("a").bind("click", function(e) {
  •                                             SetData($(this).html(),$(this).attr("ItemData"));
  •                                         });
  •  
  •             if (o.ReadOnly==true)
  •             {
  •                 Input.bind("cut copy paste keydown", function(e) {e.preventDefault();}); 
  •             }
  •  
  •             if (o.MaxHeight>0)
  •             {
  •                 var UL=Obj.find("ul[style]");
  •                 UL.css({'max-height':o.MaxHeight,'overflow':'auto'});
  •             }
  •  
  •             function SetData(Text,Data)
  •             {
  •                 Input.val(Text);
  •                 if (o.onSelect) {o.onSelect(o.InputName,Data);}
  •             }
  •  
  •         });
  •  }
  • })(jQuery);

 

样张:

 

这样通过两层的ul实现了下拉菜单,并且滚动条也没有覆盖右侧的两个圆角。较之上个版本,比较完善。

基于Bootstrap的DropDownList的JQuery组件的完善版的更多相关文章

  1. 基于Bootstrap的超酷jQuery开关按钮插件

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJgAAAA2CAIAAAC0tsfoAAAB/0lEQVR4nO3bQWrCQBTGcc/mbVz0DD

  2. 【转】基于Bootstrap的超酷jQuery开关按钮插件

    基于Bootstrap的超酷jQuery开关按钮插件

  3. 基于Bootstrap的炫酷jQuery slider插件

    简要教程 这是一款在原生bootstrap slider的基础上制作效果非常炫酷的jQuery slider插件.该slider插件可以自定义slider的颜色.形状.透明度和tooltip等属性,美 ...

  4. 基于bootstrap 的datatable插件的使用(php版)

    Datatables是一款jquery表格插件.它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能.详细学习请参考其官网:http://datatables.net/中文网:http:/ ...

  5. 创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件

    Bootstrap是当下流行的前端UI组件库之一.利用Bootstrap,可以很方便的构造美观.统一的页面.把设计师从具体的UI编码中解放出来.   Bootstrap提供了不少的前端UI组件.带下拉 ...

  6. 循序渐进BootstrapVue,开发公司门户网站(1)---基于Bootstrap网站模板构建组件界面

    在前面随笔<使用BootstrapVue相关组件,构建Vue项目界面>概括性的介绍了BootstrapVue的使用过程,其实选用这个主要就是希望能够用来构建一些公司门户网站的内容,毕竟基于 ...

  7. JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果分享(你值得拥有)

    前言:最近园子里多了许多谈语言.谈环境.谈逼格(格局)的文章,看看笑笑过后,殊不知其实都是然并卵.提升自己的技术才是王道.之前博主分享过多篇bootstrap组件的文章,引起了很多园友的关注和支持,看 ...

  8. JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化

    前言:之前发表过一篇  JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果分享(你值得拥有) ,收到很多园友的反馈,当然也包括很多诟病,因为上篇只是将功能实现了,很多细节都没有处理 ...

  9. JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果

    Ace模板地址:http://code.google.com/p/ace-engine/wiki/AceTemplate(有时会打不开) Ace英文官网:http://wrapbootstrap.co ...

随机推荐

  1. store.js - 轻松实现本地存储(LocalStorage)

    store.js 是一个兼容所有浏览器的 LocalStorage 包装器,不需要借助 Cookie 或者 Flash.store.js 会根据浏览器自动选择使用 localStorage.globa ...

  2. 用Phaser来制作一个html5游戏——flappy bird (二)

    在上一篇教程中我们完成了boot.preload.menu这三个state的制作,下面我们就要进入本游戏最核心的一个state的制作了.play这个state的代码比较多,我不会一一进行说明,只会把一 ...

  3. 模拟position:fixed效果

    大家都知道fixed定位相对于浏览器窗口,下面就介绍一种不用fixed也能实现其效果的定位方法,就那点css代码,这里就直接呼上来: <!DOCTYPE html> <html> ...

  4. SharePoint 2010 系统账户没完全控制权限了

    网上下载了一个试用版的wsp包,安装部署后感觉不好就卸载掉了.坑爹的事情发生了,系统账户登录网站集竟然没完全控制权限了.连添加列表项的权限都没有了. 去管理中心查看,网站集管理员,没发现问题. 更坑爹 ...

  5. 高清DVI编码器|上海视涛科技

    DVI编码器(E600)简介 高清DVI编码器是上海视涛科技出品的高性能DVI编码产品.该DVI编码器是上海视涛科技完全自主研发,并适用于VGA.DVI.HDMI等信号的编码采集及网络传输的专用硬件设 ...

  6. Source Insight基本使用和快捷键

    Source Insight基本使用和快捷键 为什么要用Source Insight呢?貌似是因为比完整的IDE要更快一些,比较利于查看大量的代码. 软件的安装很简单,设置好安装目录. 配置好文档路径 ...

  7. Android Testing学习01 介绍 测试测什么 测试的类型

    Android Testing学习01 介绍 测试测什么 测试的类型 Android 测试 测什么 1.Activity的生命周期事件 应该测试Activity的生命周期事件处理. 如果你的Activ ...

  8. iOS9 HTTP 通信报错解决方案

    UIWebView *myview = [[UIWebView alloc] initWithFrame:CGRectMake(, , [UIScreen mainScreen].bounds.siz ...

  9. 【iOS】使用CoreText实现图文混排

    iOS没有现成的支持图文混排的控件,而要用多个基础控件组合拼成图文混排这样复杂的排版,是件很苦逼的事情.对此的解决方案有使用CoreText进行绘制,或者使用TextKit.本文主要讲解对于CoreT ...

  10. UIButton、UILabel、UITextField 初学者需要了解的基本定义和常用设置

     以下是三个IOS开发中最常用的控件,作为IOS基础学习教程知识 ,初学者需要了解其基本定义和常用设置,以便在开发在熟练运用. UIButton按钮 第一.UIButton的定义 UIButton * ...