zoukankan      html  css  js  c++  java
  • Bootstrap之Button.js

    查看Button.js的源代码

    +function ($) {
      'use strict';
    
      // BUTTON PUBLIC CLASS DEFINITION
      // ==============================
    
      var Button = function (element, options) {
        this.$element  = $(element)
        this.options   = $.extend({}, Button.DEFAULTS, options)
        this.isLoading = false
      }
    
      Button.VERSION  = '3.3.4'
    
      Button.DEFAULTS = {
        loadingText: 'loading...'
      }
    
      Button.prototype.setState = function (state) {
        var d    = 'disabled'
        var $el  = this.$element
        var val  = $el.is('input') ? 'val' : 'html'
        var data = $el.data()
    
        state = state + 'Text'
    
        if (data.resetText == null) $el.data('resetText', $el[val]())
    
        // push to event loop to allow forms to submit
        setTimeout($.proxy(function () {
          $el[val](data[state] == null ? this.options[state] : data[state])
    
          if (state == 'loadingText') {
            this.isLoading = true
            $el.addClass(d).attr(d, d)
          } else if (this.isLoading) {
            this.isLoading = false
            $el.removeClass(d).removeAttr(d)
          }
        }, this), 0)
      }
    
      Button.prototype.toggle = function () {
        var changed = true
        var $parent = this.$element.closest('[data-toggle="buttons"]')
        if ($parent.length) {
          var $input = this.$element.find('input')
          if ($input.prop('type') == 'radio') {
            if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
            else $parent.find('.active').removeClass('active')
          }
          if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
        } else {
          this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
        }
    
        if (changed) this.$element.toggleClass('active')
      }
    
    
      // BUTTON PLUGIN DEFINITION
      // ========================
    
      function Plugin(option) {
        return this.each(function () {
          var $this   = $(this)
          var data    = $this.data('bs.button')
          var options = typeof option == 'object' && option
    
          if (!data) $this.data('bs.button', (data = new Button(this, options)))
          if (option == 'toggle') data.toggle()
          else if (option) data.setState(option)
        })
      }
    
      var old = $.fn.button
    
      $.fn.button             = Plugin
      $.fn.button.Constructor = Button
    
    
      // BUTTON NO CONFLICT
      // ==================
    
      $.fn.button.noConflict = function () {
        $.fn.button = old
        return this
      }
    
    
      // BUTTON DATA-API
      // ===============
    
      $(document)
        .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
          var $btn = $(e.target)
          if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
          Plugin.call($btn, 'toggle')
          e.preventDefault()
        })
        .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
          $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
        })
    
    }(jQuery);
    View Code

     运用场景(运用于a,button,submit提交按钮,reset重置按钮,复选框,单选框,其他的html标签),推特的框架通过css让这个标记元素通过-webkit-appearance: button;让元素表现成按钮的形式

     1   <div class="container">
     2         <a class="btn btn-default" href="#" role="button">链接</a>
     3         <button class="btn btn-default" type="submit" data-toggle="button" aria-pressed="false" autocomplete="off">Button</button>
     4         <input class="btn btn-default" type="button" value="Input">
     5         <input class="btn btn-default" type="submit" value="Submit">
     6         <div class="btn-group" data-toggle="buttons">
     7             <label class="btn btn-primary active">
     8                 <input type="checkbox" autocomplete="off" checked id="checkbox1"> Checkbox 1 (pre-checked)
     9             </label>
    10             <label class="btn btn-primary">
    11                 <input type="checkbox" autocomplete="off"> Checkbox 2
    12             </label>
    13             <label class="btn btn-primary">
    14                 <input type="checkbox" autocomplete="off"> Checkbox 3
    15             </label>
    16         </div>
    17         <div class="btn-group" data-toggle="buttons">
    18             <label class="btn btn-primary active">
    19                 <input type="radio" name="options" id="option1" autocomplete="off" checked> Radio 1 (preselected)
    20             </label>
    21             <label class="btn btn-primary">
    22                 <input type="radio" name="options" id="option2" autocomplete="off"> Radio 2
    23             </label>
    24             <label class="btn btn-primary">
    25                 <input type="radio" name="options" id="option3" autocomplete="off"> Radio 3
    26             </label>
    27         </div>
    28     </div>

     抽离查看整理结构

    //推特的js的写法就是严格格式,前面的"+"号就是立刻执行的函数意思,当然你放"-"号也是可以达到效果的
    +function ($) { 'use strict';
    //定义一个名为Button的构造函数,最终是要通过data绑定到bs.button上,这个jQuery典型的又一种插件的写法!
    var Button = function (element, options) { this.$element = $(element) this.options = $.extend({}, Button.DEFAULTS, options) this.isLoading = false } Button.VERSION = '3.3.4' Button.DEFAULTS = {} //设置按钮的状态和按钮的文字,(比如提交表单的时候,按钮设置为"disabled",文字设置为"提交中...") Button.prototype.setState = function (state) {}
    //通过判断来动态添加"acitve",删除".active",设置"aria-pressed" Button.prototype.toggle
    = function () {}
    //定义Plugin函数,通过data的方式将当前实例化Button绑定到DOM的对象上
    function Plugin(option) {
    //通过遍历,创建多个jQuery的实例
    return this.each(function () { var $this = $(this)
       //通过data的方式获取当前元素中是绑定属性bs.button的值
    var data = $this.data('bs.button')
       //判断options是否是对象,如果是对象,那么就赋予options,然后覆盖Button中defaults的默认值 
    var options = typeof option == 'object' && option    //判断data的值,来判断是否已经创建了实例,如果没有就创建Button的实例(Button中的this就执行了当前的元素的对象上) if (!data) $this.data('bs.button', (data = new Button(this, options)))    //如果传入的是"toggle"字符串而不是对象,那么说明当前DOM的对象要实行的是toggle的方式来添加删除".acitve" if (option == 'toggle') data.toggle()
       //如果不是传入"toggle",那么就是执行setState来改变文字和按钮的状态
    else if (option) data.setState(option) }) } var old = $.fn.button $.fn.button = Plugin $.fn.button.Constructor = Button // BUTTON NO CONFLICT // ==================
     //避免插件的冲突,如果是后面又有人定义了$.fn.button的时候,调用$.fn.button.noConflict()就可以避免重名冲突
     $.fn.button.noConflict = function () { $.fn.button = old return this } 

    }(jQuery);

     Button.prototype.toggle

    Button.prototype.toggle = function () {
        //定于changeed=true的原因是,除了radio单选框外(选中的时候点击还是选中,不会取消选中),其他的元素点击的toggle时候,就在选中和不选中切换
     2     var changed = true
     3     //获取data-toggle="buttons" 的元素,查看上面"运用场景"的时候就会发现data-toggle在复选框和单选框的时候不是绑定在input的上面,所以要判断
     4     var $parent = this.$element.closest('[data-toggle="buttons"]')
     5     //如果是父元素拥有data-toggle="buttons"那么判断是 单选框或者是复选框(因为这个表单的data-toggle是绑定在外面的div上面)
     6     if ($parent.length) {
     7       var $input = this.$element.find('input')
     8       //如果是单选框
           if ($input.prop('type') == 'radio') {
           //如果单选框是选中状态同时外围的lable拥有class名"acitve",那么久证明点击这个单选框的时候不需要改变什么
    11         if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
          //如果是没有选中,先删除所有的active
    12         else $parent.find('.active').removeClass('active')
    13       }
    14       if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
    15     //不是单选或者复选框    
    16     } else {
         //对于非单选框或者是复选框的时候要设置aria-pressed属性
    17       this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
    18     }
    19 
    20     if (changed) this.$element.toggleClass('active')
    21   }

     Button.prototype.setState

    Button.prototype.setState = function (state) {
        var d    = 'disabled'
        var $el  = this.$element
    //如果是input,那么改变文本的时候,需要改变的是value的值,所以这个做了判断
    var val = $el.is('input') ? 'val' : 'html'
      //或者绑定带当前元素的属性值 var data = $el.data()   //data-loading-text 是为了找到这个属性选择器 点击这个查看实例立马就明白 http://v3.bootcss.com/javascript/#buttons state = state + 'Text' //绑定resetText属性一个值,如果是input 那么就是val(),如果不是通过html()就可以获取元素的值 if (data.resetText == null) $el.data('resetText', $el[val]()) //改变函数的作用于执行当前的函数this,改变文本的值 setTimeout($.proxy(function () {
       //设置当前元素的文字,如果data-loading-text有绑定文字,那么就用它,否则就用默认,所以页面上$(this).button("loading")的调用传递参数值还是比较死的,不灵活 $el[val](data[state]
    == null ? this.options[state] : data[state]) if (state == 'loadingText') { this.isLoading = true $el.addClass(d).attr(d, d) } else if (this.isLoading) { this.isLoading = false $el.removeClass(d).removeAttr(d) } }, this), 0) }

    执行函数

    $(document)
      //绑定click事件(同时把事件放在命名空间"bs.button.data-api"),为什么,那天你unbind的时候,它会找到对应命名空间下的click,那样就不会释放我们不想释放的click
      //通过事件冒泡的形式来把事件绑定到document上 .on(
    'click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
    //获取单击事件的目标元素(e.target和this在这里不一定是同一个元素,你懂的)
    var $btn = $(e.target) if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
    //调用Plugin方法,将this指针执行$btn,传入删除toggle Plugin.call($btn,
    'toggle')
    //阻止默认的行为,如果a的跳转链接啊! e.preventDefault() })
    //同上,就是绑定了blur和focus的事件 .on(
    'focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) })
  • 相关阅读:
    手写简易SpringMVC框架,包含@PathVariable
    高并发下,如何保证接口的幂等性?
    JAVA判断奇偶数
    多线程ForkJoin-分治思想
    websocket简单使用
    Git使用教程:最详细、最傻瓜、最浅显、真正手把手教!(转载学习)
    linux配置java环境变量(详细)
    java缓存技术的介绍(转载)
    java 多态性详解及常见面试题
    oracle数据库基础知识总结(一)
  • 原文地址:https://www.cnblogs.com/ip128/p/4554150.html
Copyright © 2011-2022 走看看