Bootstrap中不乏很多优秀的小插件来让界面更加漂亮。比如之前做过笔记的bootstrap-fileinput,select2,datetimepicker等都是属于这一系列的。这些相对而言比较大一点。其他还有一些比较轻比较小的插件,也很好,特此开篇来记录一下。

  由于是基于bootstrap的插件,所以基本上所有插件都是需要bootstrap和jquery相关文件的。也就是说下面的说明中我们默认页面上已经有了:

<link href="/static/css/bootstrap.min.css" rel="stylesheet" />

<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>

■  ladda-bootstrap

  转自【http://www.cnblogs.com/landeanfen/p/5603790.html#_label3】

  按钮通常是发起ajax请求或提交表单数据的第一入口,有时候点击按钮发送请求之后反应会比较慢,如果用户等不及了再按一下按钮就导致重复请求了。这个就很僵硬了。

  这个插件可以让我们点击按钮之后让按钮出现转菊花,并且禁用。虽说自己实现逻辑也不复杂,不过这个很好看。

  这个插件在github上的地址是:【https://github.com/msurguy/ladda-bootstrap】,使用这个插件需要引入的静态文件有:

<link href="/static/ladda-bootstrap/dist/ladda-themeless.min.css" rel="stylesheet" />

<script src="/static/ladda-bootstrap/dist/spin.min.js"></script>
<script src="/static/ladda-bootstrap/dist/ladda.min.js"></script>

  然后HTML是一个简单的按钮,但是需要加入一些class和新的属性:

<button type="button" class="btn btn-primary ladda-button" data-style="expand-right" id="testbtn"><span class="ladda-label">测试</span></button>

  然后是js初始化这个按钮:

$(document).ready(function(){
$('#testbtn').click(function(event){
var l = Ladda.create(this);
l.start(); //启动动画,禁用按钮
l.setProgress(0-1); //设置进度条
/* 做这个按钮该做的操作 */
l.stop(); //结束动画,启用按钮
});
});

  首先需要注意的是,Ladda.create方法的参数不是一个jquery对象而是一个DOM对象(所以我们用this而不是$(this)),这一点在click外面写时尤其重要。比如我和一个bootstrap-table结合起来,点击按钮时触发bootstrap-table的refresh事件:

$('#table').bootstrapTable({
/*其他参数*/
onLoadSuccess: function(data){
var l = Ladda.create($('#testbtn')[0]);
l.stop();
}
}); $('#testbtn').click(function(event){
var l = Ladda.create(this);
l.start();
l.setProgress(0-1);
$('#table').bootstrapTable('refresh'); //触发refresh事件
});

  然后再来看button的data-style属性。这个属性指出了按钮的动画以何种形式出现。expand-right是按钮先扩展然后在文字右边出现一个转菊花。除了这个还有以下这些data-style可以选择:

  expand-left , expand-up , expand-down

  zoom-in , zoom-out  文字先放大/缩小淡出,然后菊花淡入

  slide-up/down/left/right  文字向指定方向划出,然后菊花淡入

  此外,button也有一些属性可以进一步定制这个组件的样式,比如

  data-spinner-color  可以指定转菊花时菊花的颜色,值是类似于'#6600ff'这种

  

  最后再说下,setProgress是个什么东西。这个组件其实默认会给按钮上加上一个进度条,反映在界面上就是文字退出按钮的时间的快慢。作为实用的话这个方法肯定是要在某个回调函数中调用的。参数设置0到1间的某个实数来体现进度条。

■  bootstrap-switch

  这个插件可以帮我们方便地实现像IOS那样风格的开关按钮。开关这个东西,本质上是一个checkbox(分成开和关两种状态,多个开关之间互相不关联)。

  源码下载:【https://github.com/Bttstrp/bootstrap-switch】

  官方文档:【http://bootstrapswitch.com/options.html】

  使用:

  需要引用的文件:

<link href="/static/bootstrap-switch/dist/css/bootstrap3/bootstrap-switch.min.css" rel="stylesheet" />

<script src="/static/bootstrap-switch/dist/js/bootstrap-switch.min.js"></script>

  HTML:

<input type="checkbox" id="testswitch" checked />

  JS:

$(document).ready(function(){
$('#testswtich').bootstrapSwtich({
size: 'mini'
});
});

  这是基本用法,就可以渲染出一个开关了。开关的取值和一般的checkbox一致,只需要$('#testswitch').prop('checked')或者is(':checked')来获取true和false

  事件的话和普通checkbox不同,无法通过change方法绑定事件处理函数。而是要在初始化时定义好处理函数比如有这些事件:
  onSwitchChange  最主要的事件,定义开关切换状态时触发的事件的处理函数,绑定的函数有两个参数,分别是事件对象event和data(该switch做完变化后的状态,true和false)

  onInit  初始化时发生的事件

  绑定事件的具体方式是$('#test').bootstrapSwitch('onSwitchChange',function(event,data){...})

  另外这些是初始化时的参数:

  size  指定组件大小,从小到大有mini,small,normal,large等

  onColor,offColor  指定开关状态时开关的颜色,可选值有success,warning,primary,info,danger,default

  onText,offText  指定开关状态下显示的文字,默认是ON和OFF

  state  设置默认状态下是开是关

  inverse  默认情况下开在按钮左边关在右边,设置inverse参数为true时倒过来

  handleWidth  设置开关宽度,单位为px,可设置成'auto'

  

  在此额外提一下(也是一个比较通用的知识点)如果不想在初始化时设置这些参数,可以在初始化方法外面进行全局设定的重写,方法是:

$.fn.bootstrapSwitch.defaults.size = 'large';
$.fn.bootstrapSwitch.defaults.onColor = 'sucess';

■  步骤条ystep

  步骤条是开发流程、多步骤表单时常用的一种组件。ystep这个组件是由一位叫杨园的前辈(https://github.com/iyangyuan/ystep)开发的,轻量级的步骤条组件。然后我还结合了这篇文章对插件做了一些定制化的内容。

  首先引入文件:

<link href="{% static 'ystep-master/css/ystep.css' %}" rel="stylesheet" />
<script src="{% static 'js/skill.js' %}"></script>

  然后HTML上写一个div:

<div id="teststep"></div>

  然后是JS来初始化:

$(document).ready(function(){
$('#teststep').loadStep({
//size: 'small',
size: 'large',
color: 'blue',
steps: [{
title: '第一步',
content: '打开冰箱门'
},{
title: '第二步',
content: '把大象塞进冰箱'
},{
title: '第三步',
content: '把冰箱门带上'
},{
title: '第四步',
content: '完成'
}
]
}).setStep(0);
});

  size指出了步骤条大小,只有large和small两个选项。color是颜色风格,有blue和green两种。steps是步骤条主题,title是步骤名称,content是鼠标悬浮在步骤名附近时给出的关于步骤详细内容的提示信息。

  先来说说方法,setStep(n)可以将当前步骤条调整到第n步(是0开始的),getStep()获取当前第几步,nextStep和prevStep是前后调整。

  ●  自己的一些小修改

  结合上面给出的第二篇文章,ystep这个组件还存在一些小缺点。其实最困扰我的还是大小问题。虽然提供了large这个选项,但是整个步骤条还是一个比较短的状态,我想让它变长,最好是达到100%容器的宽度。于是我在ystep.js中做出了如下修改:

/*在540行附近的large参数的函数,如果愿意改small或者新增一个自定义的参数也是可以的*/
large: function($html){
var stepCount = $html.find("li").length-1,
/* beg 将原来写死的px值换成百分比 */
containerWidth = "100%";
progressWidth = "100%";
progressbarWidth = ((stepCount/(stepCount+1))*100)+"%";
/* end */
$html.css({
width: containerWidth
});
$html.find(".ystep-progress").css({
width: progressWidth
});
$html.find(".ystep-progress-bar").css({
width: progressbarWidth //原来progress和progress-bar长度一样,现在应该让progress-bar比progress略短一些,具体短多少看上面公式
});
$html.addClass("ystep-lg");
}

以及

/* 在600行附近新增调整每个步骤margin-right的值的逻辑 */
//调整步骤margin以对齐
var containerWidth = $n.width();
var fullStepCount = $baseHtml.find('li').length;
var modify = ( containerWidth - fullStepCount * 100 ) / fullStepCount;
$n.find('li').css('margin-right',modify+'px');

  通过这样渲染出来的步骤条,它就是一个长度可以填满.ystep-container这个div相当一部分的步骤条了。不能做到填满到100%是因为progress的进度逻辑和宽度逻辑是不相符的,如果progressbarWidth和progressWidth一样保持100%,那么调用一次nextStep(或者其他方法)后进度条不会刚好走到步骤条节点上而是有所出入。如果要改进度逻辑,那么就要修改各个方法了,有点麻烦,所以走了简单的路改宽度逻辑。

  如此修改之后得到的步骤条还是有些不好的地方,就是会往左边偏一点。想要去除这个可以看情况把#teststep这个div加上一个col-lg-offset-x的class,尽量把.ystep-container这个div调整到画面中间。

■  遮罩效果

  在发起ajax之后等场景下,可能需要页面出现一个所谓的遮罩效果,防止用户在这段时间内做出多余的操作。遮罩的基本思路就是在页面上添加一个覆盖所有元素(从CSS的角度上来看z-index较大)的div,并添加一些提示信息和进出效果,提示信息可以分为简单的文字提示,也可以有转菊花等比较好看的提示,转菊花又可以分成图片实现(直接插入一张gif图)和css/js实现。

  虽然整体而言,自己实现遮罩起来也不困难,但是也有一些现成的组件可以使用。比如这位大神提到的一些:【http://www.cnblogs.com/landeanfen/p/5461849.html#_label2】

  1. 简单的单层遮罩

  组件很简单,就是一个js文件:

/*******************************************
*
* Plug-in:友好的页面加载效果
* Author:sqinyang (sqinyang@sina.com)
* Time:2015/04/20
* Explanation:随着HTML5的流行,页面效果越来越炫,同时也需要加载大量的插件及素材,万恶的网速,特别对于挂在国外服务器的网站,一打开一堆素材缓缓加载,位置错乱不齐,故编写此方法,方便大家使用
*
*********************************************/ jQuery.bootstrapLoading = {
start: function (options) {
var defaults = {
opacity: 1,
//loading页面透明度
backgroundColor: "#fff",
//loading页面背景色
borderColor: "#bbb",
//提示边框颜色
borderWidth: 1,
//提示边框宽度
borderStyle: "solid",
//提示边框样式
loadingTips: "Loading, please wait...",
//提示文本
TipsColor: "#666",
//提示颜色
delayTime: 1000,
//页面加载完成后,加载页面渐出速度
zindex: 999,
//loading页面层次
sleep: 0
//设置挂起,等于0时则无需挂起 }
var options = $.extend(defaults, options); //获取页面宽高
var _PageHeight = document.documentElement.clientHeight,
_PageWidth = document.documentElement.clientWidth; //在页面未加载完毕之前显示的loading Html自定义内容
var _LoadingHtml = '<div id="loadingPage" style="position:fixed;left:0;top:0;_position: absolute;width:100%;height:' + _PageHeight + 'px;background:' + options.backgroundColor + ';opacity:' + options.opacity + ';filter:alpha(opacity=' + options.opacity * 100 + ');z-index:' + options.zindex + ';"><div id="loadingTips" style="position: absolute; cursor1: wait; width: auto;border-color:' + options.borderColor + ';border-style:' + options.borderStyle + ';border-width:' + options.borderWidth + 'px; height:80px; line-height:80px; padding-left:80px; padding-right: 5px;border-radius:10px; background: ' + options.backgroundColor + ' url(/Content/bootstrap-loading/images/loading.gif) no-repeat 5px center; color:' + options.TipsColor + ';font-size:20px;">' + options.loadingTips + '</div></div>'; //呈现loading效果
$("body").append(_LoadingHtml); //获取loading提示框宽高
var _LoadingTipsH = document.getElementById("loadingTips").clientHeight,
_LoadingTipsW = document.getElementById("loadingTips").clientWidth; //计算距离,让loading提示框保持在屏幕上下左右居中
var _LoadingTop = _PageHeight > _LoadingTipsH ? (_PageHeight - _LoadingTipsH) / 2 : 0,
_LoadingLeft = _PageWidth > _LoadingTipsW ? (_PageWidth - _LoadingTipsW) / 2 : 0; $("#loadingTips").css({
"left": _LoadingLeft + "px",
"top": _LoadingTop + "px"
}); //监听页面加载状态
document.onreadystatechange = PageLoaded; //当页面加载完成后执行
function PageLoaded() {
if (document.readyState == "complete") {
var loadingMask = $('#loadingPage'); setTimeout(function () {
loadingMask.animate({
"opacity": 0
},
options.delayTime,
function () {
$(this).hide(); }); },
options.sleep); }
}
},
end: function () {
$("#loadingPage").remove();
}
}

  然后在我们自己的页面可以这样调用(当然,默认已经导入了bootstrap的js和css以及jquery):

$('#test').click(function(event){
event.preventDefault(); // 显示遮罩
$.bootstrapLoading.start({
//一些初始化参数,可以参考组件代码中的default中的字段
loadingTips: '正在加载中...',
backgroundColor: '#EEE8CD',
opacity: 0.8
});
//做一些耗时操作如ajax请求等,如果是ajax那么关闭遮罩的方法end可以在complete参数指定的函数中调用 // 关闭遮罩
$.bootstrapLoading.end();
});

  2. spin.js

  这个组件有通过css+js实现的转菊花效果。用到的组件文件主要有

  spin.js【根据参考文中给出的提示进行了修改】:

/**
* Copyright (c) 2011-2014 Felix Gnass
* Licensed under the MIT license
* http://spin.js.org/
*
* Example:
var opts = {
lines: 12, // The number of lines to draw
length: 7, // The length of each line
width: 5, // The line thickness
radius: 10, // The radius of the inner circle
scale: 1.0, // Scales overall size of the spinner
corners: 1, // Roundness (0..1)
color: '#000', // #rgb or #rrggbb
opacity: 1/4, // Opacity of the lines
rotate: 0, // Rotation offset
direction: 1, // 1: clockwise, -1: counterclockwise
speed: 1, // Rounds per second
trail: 100, // Afterglow percentage
fps: 20, // Frames per second when using setTimeout()
zIndex: 2e9, // Use a high z-index by default
className: 'spinner', // CSS class to assign to the element
top: '50%', // center vertically
left: '50%', // center horizontally
shadow: false, // Whether to render a shadow
hwaccel: false, // Whether to use hardware acceleration (might be buggy)
position: 'absolute' // Element positioning
};
var target = document.getElementById('foo');
var spinner = new Spinner(opts).spin(target);
*/
;(function(root, factory) {
if (typeof module == 'object' && module.exports) module.exports = factory(); // CommonJS
else if (typeof define == 'function' && define.amd) define(factory); // AMD module
else root.Spinner = factory(); // Browser global
}
(this, function() {
'use strict'; var prefixes = ['webkit', 'Moz', 'ms', 'O']; // Vendor prefixes
var animations = {}; // Animation rules keyed by their name
var useCssAnimations; // Whether to use CSS animations or setTimeout
var sheet; // A stylesheet to hold the @keyframe or VML rules /**
* Utility function to create elements. If no tag name is given,
* a DIV is created. Optionally properties can be passed.
*/
function createEl(tag, prop) {
var el = document.createElement(tag || 'div');
var n; for (n in prop) el[n] = prop[n];
return el;
} /**
* Appends children and returns the parent.
*/
function ins(parent /* child1, child2, ...*/) {
for (var i = 1, n = arguments.length; i < n; i++) {
parent.appendChild(arguments[i]);
} return parent;
} /**
* Creates an opacity keyframe animation rule and returns its name.
* Since most mobile Webkits have timing issues with animation-delay,
* we create separate rules for each line/segment.
*/
function addAnimation(alpha, trail, i, lines) {
var name = ['opacity', trail, ~~(alpha * 100), i, lines].join('-');
var start = 0.01 + i/lines * 100;
var z = Math.max(1 - (1-alpha) / trail * (100-start), alpha);
var prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase();
var pre = prefix && '-' + prefix + '-' || ''; if (!animations[name]) {
sheet.insertRule(
'@' + pre + 'keyframes ' + name + '{' +
'0%{opacity:' + z + '}' +
start + '%{opacity:' + alpha + '}' +
(start+0.01) + '%{opacity:1}' +
(start+trail) % 100 + '%{opacity:' + alpha + '}' +
'100%{opacity:' + z + '}' +
'}', sheet.cssRules.length); animations[name] = 1;
} return name;
} /**
* Tries various vendor prefixes and returns the first supported property.
*/
function vendor(el, prop) {
var s = el.style;
var pp;
var i; prop = prop.charAt(0).toUpperCase() + prop.slice(1);
if (s[prop] !== undefined) return prop;
for (i = 0; i < prefixes.length; i++) {
pp = prefixes[i]+prop;
if (s[pp] !== undefined) return pp;
}
} /**
* Sets multiple style properties at once.
*/
function css(el, prop) {
for (var n in prop) {
el.style[vendor(el, n) || n] = prop[n];
} return el;
} /**
* Fills in default values.
*/
function merge(obj) {
for (var i = 1; i < arguments.length; i++) {
var def = arguments[i];
for (var n in def) {
if (obj[n] === undefined) obj[n] = def[n];
}
}
return obj;
} /**
* Returns the line color from the given string or array.
*/
function getColor(color, idx) {
return typeof color == 'string' ? color : color[idx % color.length];
} // Built-in defaults var defaults = {
lines: 12, // The number of lines to draw
length: 7, // The length of each line
width: 5, // The line thickness
radius: 10, // The radius of the inner circle
scale: 1.0, // Scales overall size of the spinner
corners: 1, // Roundness (0..1)
color: '#000', // #rgb or #rrggbb
opacity: 1/4, // Opacity of the lines
rotate: 0, // Rotation offset
direction: 1, // 1: clockwise, -1: counterclockwise
speed: 1, // Rounds per second
trail: 100, // Afterglow percentage
fps: 20, // Frames per second when using setTimeout()
zIndex: 2e9, // Use a high z-index by default
className: 'spinner', // CSS class to assign to the element
top: '50%', // center vertically
left: '50%', // center horizontally
shadow: false, // Whether to render a shadow
hwaccel: false, // Whether to use hardware acceleration
position: 'absolute' // Element positioning
}; /** The constructor */
function Spinner(o) {
this.opts = merge(o || {}, Spinner.defaults, defaults);
} // Global defaults that override the built-ins:
Spinner.defaults = {}; merge(Spinner.prototype, {
/**
* Adds the spinner to the given target element. If this instance is already
* spinning, it is automatically removed from its previous target b calling
* stop() internally.
*/
spin: function(target) {
this.stop(); var self = this;
var o = self.opts;
var el = self.el = createEl(null, {className: o.className}); css(el, {
position: o.position,
width: 0,
zIndex: o.zIndex,
left: o.left,
top: o.top
}); if (target) {
target.insertBefore(el, target.firstChild || null);
target.className = "fade";
} el.setAttribute('role', 'progressbar');
self.lines(el, self.opts); if (!useCssAnimations) {
// No CSS animation support, use setTimeout() instead
var i = 0;
var start = (o.lines - 1) * (1 - o.direction) / 2;
var alpha;
var fps = o.fps;
var f = fps / o.speed;
var ostep = (1 - o.opacity) / (f * o.trail / 100);
var astep = f / o.lines; (function anim() {
i++;
for (var j = 0; j < o.lines; j++) {
alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity); self.opacity(el, j * o.direction + start, alpha, o);
}
self.timeout = self.el && setTimeout(anim, ~~(1000 / fps));
})();
} return self;
}, /**
* Stops and removes the Spinner.
*/
stop: function() {
var el = this.el;
if (el) {
clearTimeout(this.timeout);
if (el.parentNode) {
var reg = new RegExp('(\\s|^)fade(\\s|$)');
el.parentNode.className = el.parentNode.className.replace(reg, ' ');
el.parentNode.removeChild(el);
}
this.el = undefined;
}
return this;
}, /**
* Internal method that draws the individual lines. Will be overwritten
* in VML fallback mode below.
*/
lines: function(el, o) {
var i = 0;
var start = (o.lines - 1) * (1 - o.direction) / 2;
var seg; function fill(color, shadow) {
return css(createEl(), {
position: 'absolute',
width: o.scale * (o.length + o.width) + 'px',
height: o.scale * o.width + 'px',
background: color,
boxShadow: shadow,
transformOrigin: 'left',
transform: 'rotate(' + ~~(360/o.lines*i + o.rotate) + 'deg) translate(' + o.scale*o.radius + 'px' + ',0)',
borderRadius: (o.corners * o.scale * o.width >> 1) + 'px'
});
} for (; i < o.lines; i++) {
seg = css(createEl(), {
position: 'absolute',
top: 1 + ~(o.scale * o.width / 2) + 'px',
transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
opacity: o.opacity,
animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1 / o.speed + 's linear infinite'
}); if (o.shadow) ins(seg, css(fill('#000', '0 0 4px #000'), {top: '2px'}));
ins(el, ins(seg, fill(getColor(o.color, i), '0 0 1px rgba(0,0,0,.1)')));
}
return el;
}, /**
* Internal method that adjusts the opacity of a single line.
* Will be overwritten in VML fallback mode below.
*/
opacity: function(el, i, val) {
if (i < el.childNodes.length) el.childNodes[i].style.opacity = val;
} }); function initVML() { /* Utility function to create a VML tag */
function vml(tag, attr) {
return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr);
} // No CSS transforms but VML support, add a CSS rule for VML elements:
sheet.addRule('.spin-vml', 'behavior:url(#default#VML)'); Spinner.prototype.lines = function(el, o) {
var r = o.scale * (o.length + o.width);
var s = o.scale * 2 * r; function grp() {
return css(
vml('group', {
coordsize: s + ' ' + s,
coordorigin: -r + ' ' + -r
}),
{ width: s, height: s }
);
} var margin = -(o.width + o.length) * o.scale * 2 + 'px';
var g = css(grp(), {position: 'absolute', top: margin, left: margin});
var i; function seg(i, dx, filter) {
ins(
g,
ins(
css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
ins(
css(
vml('roundrect', {arcsize: o.corners}),
{
width: r,
height: o.scale * o.width,
left: o.scale * o.radius,
top: -o.scale * o.width >> 1,
filter: filter
}
),
vml('fill', {color: getColor(o.color, i), opacity: o.opacity}),
vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
)
)
);
} if (o.shadow)
for (i = 1; i <= o.lines; i++) {
seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
} for (i = 1; i <= o.lines; i++) seg(i);
return ins(el, g);
}; Spinner.prototype.opacity = function(el, i, val, o) {
var c = el.firstChild;
o = o.shadow && o.lines || 0;
if (c && i + o < c.childNodes.length) {
c = c.childNodes[i + o]; c = c && c.firstChild; c = c && c.firstChild;
if (c) c.opacity = val;
}
};
} if (typeof document !== 'undefined') {
sheet = (function() {
var el = createEl('style', {type : 'text/css'});
ins(document.getElementsByTagName('head')[0], el);
return el.sheet || el.styleSheet;
}()); var probe = css(createEl('group'), {behavior: 'url(#default#VML)'}); if (!vendor(probe, 'transform') && probe.adj) initVML();
else useCssAnimations = vendor(probe, 'animation');
} return Spinner; }));

  原生的组件不带有遮罩,只有转菊花。为了加上遮罩我们还要写一个小css,命名为spin.css:

.fade {
position: fixed;
top:;
right:;
bottom:;
left:;
z-index:;
opacity: 0.8;
background-color: #CDCDCD;
}

  然后就是调用了,当然别忘了在调用界面引入上面两个js和css文件。由于spin.js不需要jquery,而采用javascript原生的方式调用方法,所以有些特殊。为了更清楚地说明,下面将完整写出一整个调用页面的情况:

{% extends 'orig/my_base.html' %}

{% load static %}

{% block styles %}
{{ block.super }}
<link href="{% static 'spinjs/spin.css' %}" rel="stylesheet" />
{% endblock %} {% block front_scripts %}
{{ block.super }}
<script src="{% static 'spinjs/spin.js' %}"></script>
<script src="{% static 'test.js' %}"></script>
{% endblock %} {% block page_content %}
<button type="button" class="btn btn-default" id="req">发起ajax请求</button>
<!-- spin.js的遮罩需要手动在页面上写上一个div,如下 -->
<div id="mask"></div>
{% endblock %}

  然后再来看下在test.js中是如何具体调用遮罩发生方法的:

$(document).ready(function(event){
// 点击按钮发起请求,同时带起遮罩
$('#req').click(function(event){
event.preventDefault();
var spinner; // 进入ajax前声明spinner变量以使得变量得以在ajax参数中传递
$.ajax({
url: '/test/spinload',
type: 'get',
dataType: 'json',
data: {},
// 遮罩的启用在beforeSend中进行
beforeSend: function(){
var target = $('#mask')[0]; // 注意,取的是[0],或者用js的document.getElementById('mask')也行
spinner = new Spinner({
lines: 12,
length: 2,
width: 5,
radius: 10,
shadow: true,
opacity: 0.1
//更多的初始化参数可以参考spin.js里面的defaults
}).spin(target); // 这里就算是显示遮罩了
},
success: function(data){
console.log(data);
},
complete: function(){
target.spin(); // 隐去遮罩
}
})
}) })

  

  3. fakeLoader

  fakeLoader同样需要bootstrap和jquery的支持。这个组件严格来说并不是一个遮罩,而是一个提升体验的组件。比如在网页还在加载中或者其他一些不太好看的时候,可以放出fakeLoader,但是fakeLoader只能显示固定秒数,不能和上面那几个插件一样加入某个动作的钩子。

  引入方法很简单,就是在有bootstrap和jquery的情况下把下载【https://github.com/joaopereirawd/fakeLoader.js/tree/master/demo】来的css和js分别引用进去即可。和上面的spinjs类似的,需要在页面上<body>中添加一个<div>,然后用这个标识的div调用fakeLoader的一些方法即可。

  调用时用:

$('#mask').fakeLoader({
timeToHide: 3000 // fakeLoader隐藏的秒数。由于无钩子控制,需要合理设置不能太大也不能太小
spinner: 'spinner4' // 有7-8种spinner,不同的“菊花”样式,可以网上查下哪个好看
});

  正如上面所说,fakeLoader无法加入钩子,这主要是因为他没有留出(动作结束时)隐藏fakeLoader的接口。虽然我们可以通过这样的方式来进行手动的隐藏:

$('#mask').fakeLoader({
timeToHide: 60000, // 设置一个很长的时间,保证动作完成前fakeLoader一直在
spinner: 'spinner4'
}); // 一些动作过后 $('#mask').fakeLoader({
timeToHide: 1, // 隐藏fakeLoader
spinner: 'spinner4' // 设置和出现的spinner一样,否则可能会出现出入
})

  虽然这样可以实现一次,但是如果再来一次相同的动作的话可能会导致fakeLoader无法再次出现,也就是说一次性的。。有符合场景的情况的话不妨可以用用。

【Bootstrap】优秀小插件收集的更多相关文章

  1. 近期十大优秀jQuery插件推荐

    当有限的开发知识限制了设计进展,你无法为自己插上创新的翅膀时,jQuery可以扩展你的视野.本文将推荐从jQuery网站的Plugin频道中推选出的近期十款优秀jQuery插件. 1.jQuery U ...

  2. 第二百四十八节,Bootstrap轮播插件

    Bootstrap轮播插件 学习要点: 1.轮播插件 本节课我们主要学习一下 Bootstrap 中的轮播插件. 一.轮播 轮播插件就是将几张同等大小的大图,按照顺序依次播放. 基本实例. 第一步,给 ...

  3. 第二百四十三节,Bootstrap模态框插件

    Bootstrap模态框插件 学习要点: 1.基本使用 2.用法说明 本节课我们主要学习一下 Bootstrap 中的模态框插件,这是一款交互式网站非常常见的 弹窗功能插件. 一.基本使用 使用模态框 ...

  4. bootstrap学习——javascript插件篇

    飞近期做的一个小项目须要用到一个模态框和一个图片浏览插件,并把二者结合,刚好bootstrap有相应插件,下面是学习应用流程: 1.    引入js文件: 能够单个引入相应插件文件,或一次所有引入.飞 ...

  5. Web前端开发人员实用Chrome插件收集

    越来越多的前端开发人员喜欢在Chrome里开发调试代码,Chrome有许多优秀的插件可以帮助前端开发人员极大的提高工作效率.尤其Chrome本身是可以登录的,登录后你所有的插件都会自动同步到每一个登录 ...

  6. Visual Studio Code 和Visual Studio插件收集(持续更新)

    Visual Studio Code 插件收集 Chinese (Simplified) Language Pack 默认刚安装的VSC是原味英文的,如果你用不习惯,非常简单,官方出品的简体中文语言包 ...

  7. 开源Unity小插件CheatConsole

    我们在开发游戏的过程中,通常都需要一些快捷的方式来进行一些非常规的测试,这些功能一般被称作控制台或者GM指令,比如虚幻竞技场中,可以使用~键呼出控制台,输入一些指令即可进行快捷设置,比如设置分辨率,全 ...

  8. 浮动【电梯】或【回到顶部】小插件:iElevator.js

    iElevator.js 是一个jquery小插件,使用简单,兼容IE6,支持UMD和3种配置方式,比锚点更灵活. Default Options _defaults = { floors: null ...

  9. aBowman >>可以运用到自己博客上的小插件

    大家进入我的博客会发现页面右边有一只小狗这部分.这个就是我用在上面的 一个小插件.插件网址是:http://abowman.com/google-modules/,这上面有很多的小插件,可以直接运用到 ...

随机推荐

  1. 3_使用指针对象(Using Object Pointer)

    类的成员函数有两种调用方式,一种是由对象调用,另一种是由对象指针调用.其中,对象调用的方式为objectName.memberFunctionName(parameters),而对象指针调用的方式为o ...

  2. FMECA分析

    FMECA是针对产品所有可能的故障,并根据对故障模式的分析,确定每种故障模式对产品工作的影响,找出单点故障,并按故障模式的严重度及其发生概率确定其危害性.所谓单点故障指的是引起产品故障的,且没有冗余或 ...

  3. Android Gradle项目Hotfix热修复技术的接入

    https://github.com/AItsuki/HotFix Issues MAC系统无法自动打包补丁,原因可能是路径分隔符问题 使用谷歌multidex分包后无法注入代码(开启multidex ...

  4. Caused by: java.lang.ClassNotFoundException: Could not load requested class : org.h2.Driver

    1.错误描述 WARN:2015-05-01 13:26:10[localhost-startStop-1] - HHH000402: Using Hibernate built-in connect ...

  5. freemarker写select组件(五)

    freemarker写select组件 1.宏定义 <#macro select id datas value="" key="" text=" ...

  6. HTML5之Canvas画正方形

    HTML5之Canvas画正方形 1.设计源码 <!DOCTYPE html> <head> <meta charset="utf-8" /> ...

  7. 项目中的导出(jxl插件)

    第一步,获取要导出的参数,为导出做准备 public ModelAndView downloadInfo(final HttpServletRequest request, final HttpSer ...

  8. Aspose.Words for .NET

    Aspose.Words for .NET Aspose.Words for .NET是 .NET 下先进的 Word 文档处理 API.它支持 DOC, OOXML, RTF, HTML, Open ...

  9. Python 爬取 中关村CPU名字和主频

    0.准备工作   1.相关教程         Python 爬虫系列教程:http://cuiqingcai.com/1052.html         Python Web课程:http://ww ...

  10. javscript eval()的优缺点与web安全防范

    要说JavaScript中最为强大的一个方法便是eval()方法呢,为何如此说呢?因为它就像是一个JavaScript解析器,也就是说它的参数就是一段js代码所构成的字符串,当执行这个函数的时候,会把 ...