zoukankan      html  css  js  c++  java
  • 【Bootstrap】优秀小插件收集

        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({
                   containerWidth
                });
                $html.find(".ystep-progress").css({
                   progressWidth
                });
                $html.find(".ystep-progress-bar").css({
                   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;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;  auto;border-color:' + options.borderColor + ';border-style:' + options.borderStyle + ';border-' + 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();
        }
    }
    View Code

      然后在我们自己的页面可以这样调用(当然,默认已经导入了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
           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
         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,
             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',
               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
              }),
              {  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}),
                    {
                       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;
    
    }));
    View Code

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

    .fade {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 9999;
        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,
                         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无法再次出现,也就是说一次性的。。有符合场景的情况的话不妨可以用用。

  • 相关阅读:
    发布两个android程序遇到证书不一致的问题!
    第一次下载程序到单片机
    人人网是明文传输,所以只要抓包就能知道用户名和密码
    [转]java调用cmd命令
    qq发送文件是在两个计算机之间建立tcp连接
    CardLayout实现分页效果
    控件 ListView1 的类 MSComctlLib.ListView 不是一个已加载的控件类
    VB中declare function 出现49错误
    oracle instant client
    WARN Please initialize the log4j system properly的解决办法【转载】
  • 原文地址:https://www.cnblogs.com/franknihao/p/8195188.html
Copyright © 2011-2022 走看看