美文网首页
Bootstrap插件解析1 模态框

Bootstrap插件解析1 模态框

作者: 波拉拉 | 来源:发表于2020-03-08 22:33 被阅读0次

1 插件整体结构

(function ($) {
    'use strict';
    //原始构造函数
    let Modal = function (element, options) {
        //内部变量
        this.options = options;//选项
        this.$element = $(element);//作用的元素
        //....
    };

    //函数静态变量对象等
    Modal.VERSION = '3.3.7';
    //...

    //原型方法
    Modal.prototype.toggle = function () {};
    Modal.prototype.show = function () {};
    //...

    // Plugin插件入口
    function Plugin(option, _relatedTarget) {}

    //为后面防冲突处理做准备
    let old = $.fn.modal;
    $.fn.modal = Plugin;//将实例方法暴露出来
    //增加函数一个静态变量Constructor,指向原构造函数
    $.fn.modal.Constructor = Modal;

    //防冲突处理
    $.fn.modal.noConflict = function () {};

    //不写js实现插件功能
    $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', 
        function (e) {}
    )
    })(jQuery);

2 Plugin插件入口

// Plugin插件入口
    function Plugin(option, _relatedTarget) {
        //遍历模态框并执行函数,最后返回
        return this.each(function () {
            var $this   = $(this);
            //获取存储的modal对象,第一次是undefined
            var data    = $this.data('bs.modal');
            //合并参数:1 默认值 2 这个模态框上所有自定义数据,3 传入的option对象(如果传入的是对象的话)
            /*
             Modal.DEFAULTS = {
             backdrop: true,
             keyboard: true,
             show: true
             };
             */
            var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option);
            // 如果data是undefined,实例化一个modal传入bs.modal中
            if (!data) $this.data('bs.modal', (data = new Modal(this, options)));
            // obj1["show"]();obj1.show();一样的效果
            //如果传入字符串,调用modal实例对象原型上的方法
            if (typeof option == 'string') data[option](_relatedTarget);
            //如果合并对象中有data-show参数,就执行原型的show方法
            else if (options.show) data.show(_relatedTarget)
        })
    }

    //为后面防冲突处理做准备
    let old = $.fn.modal;
    $.fn.modal = Plugin;//将实例方法暴露出来
    //增加函数一个静态变量Constructor,指向原构造函数
    $.fn.modal.Constructor = Modal;

    //防冲突处理
    $.fn.modal.noConflict = function () {};
  • 合并参数:1 定义在构造函数静态变量上的对象,包括 backdrop, keyboard, show。2 模态框上的自定义数据包括:data-backdrop, data-keyboard, data-show。3 传入的option,如果是对象就是合并对象包括: backdrop, keyboard, show,remote,如果是字符串就执行原型上对应的方法,包括 toggle,show,hide等。
  • bs.modal这个自定义数据模态框没执行前是undefined,执行一次以后存储着modal构造函数实例化的对象、

3 data-api实现插件

//在触发按钮上绑定(点击.模态框.data-api)事件
  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
    var $this   = $(this);
    var href    = $this.attr('href');//如果是a元素实现的按钮
    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))); //找到目标模态框
    //  没执行过option就是"toggle",否则就是触发按钮上的data数据+模态框data数据
    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data());

    if ($this.is('a')) e.preventDefault();//取消链接的自动跳转
    //处理消失后出现时的焦点回复功能
    $target.one('show.bs.modal', function (showEvent) {
      if (showEvent.isDefaultPrevented()) return; // 
      $target.one('hidden.bs.modal', function () {
        $this.is(':visible') && $this.trigger('focus')
      })
    });
    Plugin.call($target, option, this);
  //Plugin.call($target, "toggle", this)//执行切换事件
  })

4 构造函数

  var Modal = function (element, options) {
    this.options             = options;//选项
    this.$body               = $(document.body);//body
    this.$element            = $(element);//作用的元素
    this.$dialog             = this.$element.find('.modal-dialog');//模态框主题部分
    this.$backdrop           = null;//黑色半透明背景 默认true
    this.isShown             = null;//显示与否的标识
    this.originalBodyPad     = null;//?
    this.scrollbarWidth      = 0;//?
    this.ignoreBackdropClick = false;//?
      //如果选项中有remote,就是异步加载指定内容到模态框中
    if (this.options.remote) {
      this.$element
        .find('.modal-content')
        .load(this.options.remote, $.proxy(function () {
          this.$element.trigger('loaded.bs.modal')
        }, this))
    }
  };

5 构造函数的静态变量和对象

Modal.VERSION  = '3.3.7';//插件版本

  Modal.TRANSITION_DURATION = 300;//主体动画时间
  Modal.BACKDROP_TRANSITION_DURATION = 150;//背景动画时间

  Modal.DEFAULTS = {//一些默认值
    backdrop: true,
    keyboard: true,
    show: true
  };

6 原型方法

  • toggle 切换模态框
  //切换
  Modal.prototype.toggle = function (_relatedTarget) {
    //如果标识为true执行原型方法hide(),否则执行原型方法show
    return this.isShown ? this.hide() : this.show(_relatedTarget)
  };
  • show 显示模态框
 //显示
  Modal.prototype.show = function (_relatedTarget) {
    var that = this;//将实例对象保存成变量 方便事件中使用
    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget });
    //自定义模态框显示事件

    this.$element.trigger(e);//触发自定义事件

    if (this.isShown || e.isDefaultPrevented()) return;//如果显示了就返回

    this.isShown = true;//改变标识

    this.checkScrollbar();//滚动条相关
    this.setScrollbar();//滚动条相关
    this.$body.addClass('modal-open');//body添加类名

    this.escape();//按esc退出
    this.resize();//窗口大小调整

    this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this));
    //关闭按钮上的关闭事件

    this.$dialog.on('mousedown.dismiss.bs.modal', function () {//模态框内容上按下鼠标,背景上抬起鼠标
      that.$element.one('mouseup.dismiss.bs.modal', function (e) {
        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true//忽略背景点击为true
      })
    });
    //遮罩层
    this.backdrop(function () {
      var transition = $.support.transition && that.$element.hasClass('fade');
      //支持动画并且模态框有fade类名

      if (!that.$element.parent().length) {
        that.$element.appendTo(that.$body) ;//??
      }

      that.$element
        .show()
        .scrollTop(0);

      that.adjustDialog();//调整对话框

      if (transition) {
        that.$element[0].offsetWidth // force reflow
      }

      that.$element.addClass('in');

      that.enforceFocus();

      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget });

      transition ?
        that.$dialog // wait for modal to slide in
          .one('bsTransitionEnd', function () {
            that.$element.trigger('focus').trigger(e)
          })
          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
        that.$element.trigger('focus').trigger(e)
    })
  };
  • hide 隐藏模态框
//隐藏
  Modal.prototype.hide = function (e) {
    if (e) e.preventDefault();//取消默认行为

    e = $.Event('hide.bs.modal');//替换成hide事件

    this.$element.trigger(e);//触发hide

    if (!this.isShown || e.isDefaultPrevented()) return;

    this.isShown = false;//改变标记

    this.escape();//移除esc事件
    this.resize();//移除窗口调整事件

    $(document).off('focusin.bs.modal');

    this.$element
      .removeClass('in')
      .off('click.dismiss.bs.modal')
      .off('mouseup.dismiss.bs.modal');

    this.$dialog.off('mousedown.dismiss.bs.modal');//事件全部移除

    $.support.transition && this.$element.hasClass('fade') ?
      this.$element
        .one('bsTransitionEnd', $.proxy(this.hideModal, this))
        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
      this.hideModal()
  };

7 一些使用方法

详细用法

<!DOCTYPE html>
<html lang="en">
<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>Bootstrap 101 Template</title>

    <link href="bootstrap.css" rel="stylesheet">
</head>
<body>
<button type="button" class="btn btn-primary btn-lg"
        data-toggle="modal" data-target="#myModal">
    Launch demo modal
</button>
<input type="button" value="点击" id="print">
<div class="modal fade" id="myModal" data-backdrop="static" data-keyboard="false" data-show="true">
    <div class="modal-dialog" >
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" ><span>&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">Modal title</h4>
            </div>
            <div class="modal-body">
                ...
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="bootstrap.js"></script>
<script>
    $("#print").click(function () {
        $("#myModal").modal({
            keyboard:true
        })
    })
</script>
</body>
</html>
```<!DOCTYPE html>
<html lang="en">
<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>Bootstrap 101 Template</title>

    <link href="bootstrap.css" rel="stylesheet">
    <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
</head>
<body>
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
    Launch demo modal
</button>
<input type="button" value="点击" id="print">
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" data-show="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">Modal title</h4>
            </div>
            <div class="modal-body">
                ...
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="bootstrap.js"></script>
<script>
    $("#print").click(function () {
        console.log($("#myModal").data()["bs.modal"]);

    });
</script>
</body>
</html>

相关文章

网友评论

      本文标题:Bootstrap插件解析1 模态框

      本文链接:https://www.haomeiwen.com/subject/swdsdhtx.html