bootstrap按钮源代码实现

bootstrap按钮源码分为css基础部分和js插件部分

一、css基础部分

按钮样式包括基础样式、颜色样式、尺寸样式等等,我们一步一步的来实现各种样式效果。
1、基础样式
基础样式如下图所示,我们来实现一下,代码如下

<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>button</title>
  <style type="text/css">
    * {
      padding: 0;
      margin: 0;
    }

    a {
      text-decoration: none;
      color: #337ab7;
    }

    .btn {
      font-size: 14px;
      padding: 6px 12px;
      line-height: 1.4;
      display: inline-block;
      border: 1px solid transparent;
      border-radius: 4px;
      cursor: pointer;  /*手型 */
      user-select: none;  /*文字不可选 */
    }

    .btn:active,
    .btn.active{
     /*阴影效果,inset 表示阴影效果为内部,给人一种点击的效果 */
    -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
    box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
    }

     /*禁用效果*/
    .btn.disabled,
    .btn[disabled]{
       cursor: not-allowed; 
       filter: alpha(opacity=65);
       opacity: 0.65;   
    }
  </style>
</head>

<body>

  <a class="btn active" href="#" role="button">Link</a>
  <button class="btn active" type="submit">Button</button>
  <input class="btn active" type="button" value="Input">
  <input class="btn active" type="submit" value="Submit">
</body>
</html>

代码分析:需要注意的是.btn的里面需要添加display: inline-block;原因是因为行内元素padding上下边距,margin上下边距起作用依赖于块级元素的性质。:active表示伪样式,点击按钮的时候触发;.active用于初始化按钮【和:active效果一样】

2、颜色样式
颜色样式效果如图所示,分别定义了btn-default和btn-primary风格样式,我们来实现一下:

  .btn-default {
      background-color: #ffffff;
      border-color: #ccc;
      color: #333;
    }

    .btn-default:hover {
      color: #333;
      background-color: #e6e6e6;
      border-color: #adadad;
    }

    .btn-default:focus,
    .btn-default.focus {
      color: #333;
      background-color: #e6e6e6;
      border-color: #8c8c8c;
    }

    .btn-default:active,
    .btn-default.active {
      color: #333;
      background-color: #e6e6e6;
      border-color: #adadad;
    }

    .btn-primary {
      color: #fff;
      background-color: #337ab7;
      border-color: #2e6da4;
    }

    .btn-primary:focus,
    .btn-primary.focus {
      color: #fff;
      background-color: #286090;
      border-color: #122b40;
    }

    .btn-primary:hover {
      color: #fff;
      background-color: #286090;
      border-color: #204d74;
    }

    .btn-primary:active,
    .btn-primary.active {
      color: #fff;
      background-color: #286090;
      background-image: none;
      border-color: #204d74;
    }

  html部分需要修改的代码
  <a class="btn btn-primary" href="#" role="button">Link</a>
  <button class="btn btn-primary" type="submit">Button</button>
  <input class="btn btn-default" type="button" value="Input">
  <input class="btn btn-default" type="submit" value="Submit">

代码分析:每种风格的代码区分在于默认时候【即没有把鼠标放到按钮以及点击】的样式,鼠标移到按钮时候的样式,以及鼠标获取焦点,点击时候的样式不同,围绕这几个部分分别定义即可获得对应的按钮风格。

3、尺寸样式
不同尺寸的按钮效果如图所示:

        .btn-lg {
            padding: 10px 16px;
            font-size: 18px;
            border-radius: 6px;
            line-height: 1.3;
        }
        
        .btn-sm {
            padding: 5px 10px;
            font-size: 12px;
            border-radius: 3px;
            line-height: 1.5;
        }
        
        .btn-xs {
            padding: 1px 5px;
            font-size: 12px;
            border-radius: 3px;
            line-height: 1.5;
        }
        
        .btn-block {
            display: block;
            width: 100%;
        }
        
        .btn-block+.btn-block {
            margin-top: 5px;
        }

        html部分代码:
    <p>
        <button type="button" class="btn btn-primary btn-lg">(大按钮)Large button</button>
        <button type="button" class="btn btn-default btn-lg">(大按钮)Large button</button>
    </p>
    <br/>
    <p>
        <button type="button" class="btn btn-primary">(默认尺寸)Default button</button>
        <button type="button" class="btn btn-default">(默认尺寸)Default button</button>
    </p>
    <br/>
    <p>
        <button type="button" class="btn btn-primary btn-sm">(小按钮)Small button</button>
        <button type="button" class="btn btn-default btn-sm">(小按钮)Small button</button>
    </p>
    <br/>
    <p>
        <button type="button" class="btn btn-primary btn-xs">(超小尺寸)Extra small button</button>
        <button type="button" class="btn btn-default btn-xs">(超小尺寸)Extra small button</button>
    </p>

    <br/>
    <button type="button" class="btn btn-primary btn-lg btn-block">(块级元素)Block level button</button>
    <button type="button" class="btn btn-default btn-lg btn-block">(块级元素)Block level button</button>

分析:这些不同尺寸按钮的主要差别是padding、font-size、line-
height和border-radius;充满父容器的100%宽度的按钮由btn-block实现,它没有padding和margin值,将按钮变成块级元素并且定义100%的宽度即可实现。

js插件部分

Bootstrap里提供的所有Javascript插件都遵循了统一的实现步骤,包含如下5个步骤:
1、声明立即调用函数
2、定义插件类及相关原型方法
3、在jquery上定义插件并重设插件构造函数
4、防冲突处理
5、绑定事件

看下叙代码之前,请确保您知道如下相关知识:
1、js立即执行函数
2、bootstrap源码常用的jquery函数
3、bootstrape插件架构(待整理)

自己实现的Button插件源码如下:

(function($){
        var Button = function(element, options){
            this.$element = $(element); //把当前元素变成jquery对象,才能调用jquery函数
            this.options   = $.extend({}, Button.DEFAULTS, options) //如果有传入json对象,就把json数据合并到默认值        
        }
        
        //定义BUTTON默认值
        Button.DEFAULTS = {
            loadingText: 'loading...'
        }
  
        //改变按钮的状态
        Button.prototype.setState = function(state){
            var $el = this.$element;
            var data = $el.data(); //获取BUTTON所有以data-[key]的数据
            var d = 'disabled';
            var val = $el.is('input')?'val':'html'; //判断按钮是否是input标签,input标签获取数据的是val()函数,其它表是html()函数
            
            state = state + "Text";
            
            //存储改变按钮的文字后,需要恢复的提示文字
            if(data['resetText'] == null){
                $el.data('resetText',$el[val]())
            }
            
            //改变按钮的文字
            $el[val](data[state]==null?this.options[state]:data[state]);
            
            //如果是加载状态就添加禁用的样式,否则就去掉正在加载的禁用样式
            if (state == 'loadingText'){
                $el.addClass(d).attr(d, d).prop(d, true)
            }else{
                $el.removeClass('disabled').removeAttr(d).prop(d, false);
            }
             
        }
    
        //切换按钮是否是active的样式
        Button.prototype.toggle = function () {
            var $el = this.$element;
            $el.toggleClass('active');
        }
    
        //变量所有符合选择器的元素进行处理,例如$('.btn')可以批量选择按钮
        function Plugin(option) {   
            return this.each(function(i){
                    var $this   = $(this)
                    var data = $this.data('bs.button');
                    var options = typeof option == 'object' && option //如果是json对象,在初始化的时候就传给按钮对象用于提供默认值
                    
                    //没有创建按钮对象,就创建
                    if(!data){
                        data = new Button(this,options);
                        $this.data('bs.button',data)
                    }
                    
                    //只有传入的参数是toggle的时候调用toggle(),否则都调用setState(option)函数
                    if(option=='toggle'){
                        data.toggle();
                    }else{
                        data.setState(option);  
                    }
                             
            })          
            
            
        }   
        
        
        var old = $.fn.button;  //防冲突处理,先保存旧的冲突方法
        $.fn.button = Plugin;   //提供给jquery的button插件
        $.fn.button.Constructor = Button    //插件的真正构造器
        $.fn.button.noConflict = function(){    //解决冲突
            $.fn.button = old
            return this; //this可以改为Plugin,原因是因为调用noConflict函数的对象就是Plugin
        }
        
        //绑定事件
        $(document).on('click','[data-toggle="button"]',function(e){
            $(e.target).button('toggle');   //绑定调用toggle()函数
            e.preventDefault()              //阻止超链接等默认行为
        })
    
    })(window.jQuery)

bootstrape插件使用案例【和官方一样】
案例一:单击一个按钮请求ajax数据的时候,想让该按钮上的文本变成“正
在加载”;一旦ajax返回数据,再次将该按钮上的文本变为“获取数据”。

html代码:
<a class="btn btn-default" href="#" role="button">获取数据</a>

js调用:
$('.btn').on('click', function () {
        var $btn = $(this).button('loading')  //改变按钮状态为正在加载
        setTimeout(function(){                //2秒后恢复按钮文字为获取数据
                $btn.button('reset')
        },2000)
})

案例二;点击按钮切换按钮是否是处于选中状态,本质为按钮上是否有加上active样式【可以用调试工具观察class样式变化】

$('.btn').on('click', function () {
        $(this).button('toggle')
    })

案例三:修改按钮默认的正在加载时候的loading值,修改后调用button('loading')方法,按钮显示修改后的默认值

$('.btn').on('click', function () { 
        //方案一:输入json对象,覆盖默认的loadingText的值   
        var $btn = $(this).button({"loadingText":"修改默认的loading值"});  
        //方案二:直接修改构造器的默认值
        $.fn.button.Constructor.DEFAULTS.loadingText = "修改默认的loading值";         
        $(this).button('loading');          
    })

案例四:防冲突处理,当第三方组件也在jquery上定义了名为button插件时候,和bootstrape的button插件就会引起冲突。通过调用插件的 .noConflict 方法恢复其原始值。

    //测试案例:在一如bootstrape官方js文件之前加上
    <script>        
        $.fn.button = function(param){
            console.log(param);
        };
        
        $(this).button('loading');
    </script>

       //使用方法
    var bootstrapButton = $.fn.button.noConflict() // 恢复第三方的button插件,并获取bootstrape的button插件引用
    $.fn.bootstrapBtn = bootstrapButton            // 用bootstrapBtn 取代之前button插件的调用方法

    $('.btn').on('click', function () {         
        $(this).bootstrapBtn('loading');    //bootstrape的插件使用
        $(this).button('loading');  //第三方的button插件使用
    })
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容

  • 1.CSS基本概念 1.1 CSS的定义 CSS(Cascading Style Sheets)层叠样式表,主要用...
    寥寥十一阅读 1,826评论 0 6
  • 第一章 F12: element.style 内联样式(可以直接在上面写代码进行简单调试) user agent...
    fastwe阅读 1,495评论 0 0
  • 一、入门准备 二、整体架构 A.整体架构 1.CSS12栅格系统:以规则的网格阵列来指导和规范网页中的版面布已有以...
    ZyBlog阅读 1,056评论 0 1
  • HTML 5 HTML5概述 因特网上的信息是以网页的形式展示给用户的,因此网页是网络信息传递的载体。网页文件是用...
    阿啊阿吖丁阅读 3,875评论 0 0
  • 20个让你效率更高的CSS代码技巧 前端速报1周前 在这里想与你分享一个由各大CSS网站总结推荐的20个有用的规则...
    X秀秀阅读 145评论 0 0