在前文 创建基于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. 详细解读XMLHttpRequest(一)同步请求和异步请求

    本文主要参考:MDN XMLHttpRequest 让发送一个HTTP请求变得非常容易.你只需要简单的创建一个请求对象实例,打开一个URL,然后发送这个请求.当传输完毕后,结果的HTTP状态以及返回的 ...

  2. gulp-babel 取消严格模式方法

    最近项目决定用ES6语法重构,于是引入了gulp-babel去编译ES6. 问题来了,babel编译ES6会自动添加"use strict"在js文件的最前面,这就导致之前的项目文 ...

  3. Python正则表达式使用实例

    最近做题需要使用正则表达式提取信息,正则表达式很强大,之前都是纸上谈兵,这次刚好动动手,简单实现下: 文本内容如下: var user={star: false, vip :false}; var f ...

  4. Tomcat https自制证书和浏览器配置

    Tomcat配置成https后,如过使用的是自己的证书,登陆首页时,总是提示证书安全问题,网上的很多资料有描述,但比较复杂,找了几个配置不成功,现在描述一个比较简单的方法. 生成证书的脚本 #!/bi ...

  5. NSURLSession从网络上下载资源,此程序下载的是视频

    #import "ViewController.h" @interface ViewController ()<NSURLSessionDelegate, NSURLSess ...

  6. RxJava 和 RxAndroid 三(生命周期控制和内存优化)

    rxjava rxandroid 赵彦军 前言:对Rxjava.Rxandroid不了解的同学可以先看看 RxJava 和 RxAndroid RxJava 和 RxAndroid 二(操作符的使用) ...

  7. iOS 学习 - 10下载(1) NSURLConnection 篇

    程序的实现需要借助几个对象: NSURLRequest:建立了一个请求,可以指定缓存策略.超时时间.和NSURLRequest对应的还有一个NSMutableURLRequest,如果请求定义为NSM ...

  8. java "".split(",")

    String[] string = "".split(","); 结果是string = []; String[] string = " " ...

  9. IOS开发之音频--录音

    前言:本篇介绍录音. 关于录音,这里提供更为详细的讲解网址:http://www.cnblogs.com/kenshincui/p/4186022.html#audioRecord  ,并且该博客有更 ...

  10. 用Objective-C写了一个简单的批量更改文件名的程序

    前言:因为本人要高仿一个app,从app中解压asserts得到的所有图片文件,文件名都带有~iPhone这个干扰的名字,为了去除这个~iPhone这个字符串,所以本人写了个简答的批量更改所有文件名的 ...