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 原型方法
//切换
Modal.prototype.toggle = function (_relatedTarget) {
//如果标识为true执行原型方法hide(),否则执行原型方法show
return this.isShown ? this.hide() : this.show(_relatedTarget)
};
//显示
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)
})
};
//隐藏
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>×</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">×</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>
网友评论