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插件使用
})