bootstrap modal.js解析

来源:互联网 发布:内江王记牛肉干淘宝网 编辑:程序博客网 时间:2024/06/05 07:22

modal.css

html {  font-family: sans-serif;  -webkit-text-size-adjust: 100%;      -ms-text-size-adjust: 100%;}body {  margin: 0;}article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary {  display: block;}audio, canvas, progress, video {  display: inline-block;  vertical-align: baseline;}audio:not([controls]) {  display: none;  height: 0;}[hidden],template {  display: none;}a {  background-color: transparent;}a:active,a:hover {  outline: 0;}abbr[title] {  border-bottom: 1px dotted;}b, strong {  font-weight: bold;}dfn {  font-style: italic;}h1 {  margin: .67em 0;  font-size: 2em;}mark {  color: #000;  background: #ff0;}small {  font-size: 80%;}sub, sup {  position: relative;  font-size: 75%;  line-height: 0;  vertical-align: baseline;}sup {  top: -.5em;}sub {  bottom: -.25em;}img {  border: 0;}svg:not(:root) {  overflow: hidden;}figure {  margin: 1em 40px;}hr {  height: 0;  -webkit-box-sizing: content-box;     -moz-box-sizing: content-box;          box-sizing: content-box;}pre {  overflow: auto;}code, kbd, pre, samp {  font-family: monospace, monospace;  font-size: 1em;}button, input, optgroup, select, textarea {  margin: 0;  font: inherit;  color: inherit;}button {  overflow: visible;}button, select {  text-transform: none;}button,html input[type="button"],input[type="reset"],input[type="submit"] {  -webkit-appearance: button;  cursor: pointer;}button[disabled],html input[disabled] {  cursor: default;}button::-moz-focus-inner,input::-moz-focus-inner {  padding: 0;  border: 0;}input {  line-height: normal;}input[type="checkbox"],input[type="radio"] {  -webkit-box-sizing: border-box;     -moz-box-sizing: border-box;          box-sizing: border-box;  padding: 0;}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button {  height: auto;}input[type="search"] {  -webkit-box-sizing: content-box;     -moz-box-sizing: content-box;          box-sizing: content-box;  -webkit-appearance: textfield;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration {  -webkit-appearance: none;}fieldset {  padding: .35em .625em .75em;  margin: 0 2px;  border: 1px solid #c0c0c0;}legend {  padding: 0;  border: 0;}textarea {  overflow: auto;}optgroup {  font-weight: bold;}table {  border-spacing: 0;  border-collapse: collapse;}td, th {  padding: 0;}/**********************************************************//**********************************************************//**********************************************************/.fade {  opacity: 0;  -webkit-transition: opacity .15s linear;       -o-transition: opacity .15s linear;          transition: opacity .15s linear;}.fade.in {  opacity: 1;}.modal-open {  overflow: hidden;}.modal {  position: fixed;  top: 0;  right: 0;  bottom: 0;  left: 0;  z-index: 1040;  display: none;  overflow: hidden;  -webkit-overflow-scrolling: touch;  outline: 0;}.modal.fade .modal-dialog {  -webkit-transition: -webkit-transform .3s ease-out;       -o-transition:      -o-transform .3s ease-out;          transition:         transform .3s ease-out;  -webkit-transform: translate(0, -25%);      -ms-transform: translate(0, -25%);       -o-transform: translate(0, -25%);          transform: translate(0, -25%);}.modal.in .modal-dialog {  -webkit-transform: translate(0, 0);      -ms-transform: translate(0, 0);       -o-transform: translate(0, 0);          transform: translate(0, 0);}.modal-open .modal {  overflow-x: hidden;  overflow-y: auto;}.modal-dialog {  position: relative;  width: auto;  margin: 10px;}.modal-content {  position: relative;  background-color: #fff;  -webkit-background-clip: padding-box;          background-clip: padding-box;  border: 1px solid #999;  border: 1px solid rgba(0, 0, 0, .2);  border-radius: 6px;  outline: 0;  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);          box-shadow: 0 3px 9px rgba(0, 0, 0, .5);}.modal-backdrop {  position: fixed;  top: 0;  right: 0;  bottom: 0;  left: 0;  background-color: #000;}.modal-backdrop.fade {  filter: alpha(opacity=0);  opacity: 0;}.modal-backdrop.in {  filter: alpha(opacity=50);  opacity: .5;}.modal-header {  min-height: 16.42857143px;  padding: 15px;  border-bottom: 1px solid #e5e5e5;}.modal-header .close {  margin-top: -2px;}.modal-title {  margin: 0;  line-height: 1.42857143;}.modal-body {  position: relative;  padding: 15px;}.modal-footer {  padding: 15px;  text-align: right;  border-top: 1px solid #e5e5e5;}.modal-footer .btn + .btn {  margin-bottom: 0;  margin-left: 5px;}.modal-footer .btn-group .btn + .btn {  margin-left: -1px;}.modal-footer .btn-block + .btn-block {  margin-left: 0;}.modal-scrollbar-measure {  position: absolute;  top: -9999px;  width: 50px;  height: 50px;  overflow: scroll;}@media (min-width: 768px) {  .modal-dialog {    width: 600px;    margin: 30px auto;  }  .modal-content {    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);            box-shadow: 0 5px 15px rgba(0, 0, 0, .5);  }  .modal-sm {    width: 300px;  }}@media (min-width: 992px) {  .modal-lg {    width: 900px;  }}.modal-footer:before,.modal-footer:after {  display: table;  content: " ";}.modal-footer:after {  clear: both;}

modal.js

+function ($) {    'use strict';    function transitionEnd() {        var el = document.createElement('bootstrap')        var transEndEventNames = {            WebkitTransition : 'webkitTransitionEnd',            MozTransition    : 'transitionend',            OTransition      : 'oTransitionEnd otransitionend',            transition       : 'transitionend'        }        // el.style.transition        // el.style.WebkitTransition        // el.style.MozTransition        // el.style.OTransition        for (var name in transEndEventNames) {            if (el.style[name] !== undefined) {                return { end: transEndEventNames[name] }            }        }        return false // explicit for ie8 (  ._.)    }    // http://blog.alexmaccaw.com/css-transitions    $.fn.emulateTransitionEnd = function (duration) {        var called = false        var $el = this        $(this).one('bsTransitionEnd', function () { called = true })        var callback = function () { if (!called) $($el).trigger($.support.transition.end) }        setTimeout(callback, duration)        return this    }    $(function () {        $.support.transition = transitionEnd()        if (!$.support.transition) return        $.event.special.bsTransitionEnd = {            bindType: $.support.transition.end,            delegateType: $.support.transition.end,            handle: function (e) {            if ($(e.target).is(this))                 return e.handleObj.handler.apply(this, arguments)            }        }    })}(jQuery);+(function($){    var Modal = function(element,options){        this.options = options;        this.$body = $(document.body);        this.$element = $(element);            this.$backdrop = null;        this.isShown = null;        //模态框是否显示        this.scrollbarWidth = false;        //滚动条宽度        if(this.options.remote){            this.$element.find(".modal-content").load(this.options.remote,$.proxy(function(){                this.$element.trigger("loaded.bs.modal");            },this));        }    }    Modal.VERSION = "3.3.0";    Modal.TRANSITION_DURATION = 300;        //过渡时间    Modal.BACKDROP_TRANSITION_DURATION = 150;   //背景过渡时间    Modal.DEFAULTS = {        backdrop: true, //默认点击弹框以外的地方关闭弹框 和 有无黑色背景遮罩        keyboard: true, //默认按Esc关闭弹窗        show: true      //默认触发元素时打开弹窗    }    // 反转弹框状态    Modal.prototype.toggle = function(_relatedTarget){        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.scrollbarWidth        this.checkScrollbar();        // 设置overflow: hidden        this.$body.addClass("modal-open");        // 设置body内边距        this.setScrollbar();        // 设置esc按钮事件 调用hide方法        this.escape();        // 为包含data-dismiss="modal"属性的元素注册关闭模态框(比如点x按钮,就隐藏模态框功能)        this.$element.on("click.dismiss.bs.modal","[data-dismiss='modal']",$.proxy(this.hide,this));        //backdrop函数:背景逻辑, 回调函数功能:显示model逻辑        this.backdrop(function(){            // 是否支持动画 && model的元素包含fade class            var transition = $.support.transition && that.$element.hasClass("fade");            // model没有父元素 则将model附加到body上            if(!that.$element.parent().length){                that.$element.appendTo(that.$body)            }            // 将model元素设置成显示(jq.show方法), 并移动到最上面            that.$element.show().scrollTop(0);            // 动画效果准备            if(transition){                that.$element[0].offsetWidth            }            that.$element.addClass("in").attr("aria-hidden",false);            //解绑并为document对象注册focusin.bs.modal事件, 具体处理是:如果不是model产生的,就触发model的facus事件            //简单的说,就是获取焦点            that.enforceFocus();            //准备触发shown.bs.modal事件            var e = $.Event("shown.bs.modal",{ relatedTarget: _relatedTarget});            //有动画,就动画完成后触发focus事件和shown.bs.modal事件            $.support.transition?that.$element.find(".modal-dialog").one("bsTransitionEnd",function(){                that.$element.trigger("focus").trigger(e)            }).emulateTransitionEnd(300):that.$element.trigger("focus").trigger(e);        });    }    // 关闭弹框    Modal.prototype.hide = function(e){        if(!!e) e.preventDefault();        // 绑定hide.bs.modal事件并触发        e = $.Event("hide.bs.modal");        this.$element.trigger(e);        // 如果已经hide了 || 调用hide事件时阻止了默认行为 则返回        if(!this.isShown || e.isDefaultPrevented()) return;        this.isShown = false;        // 解除esc按键事件        this.escape();        // 解除document对象的focusin.bs.modal事件绑定, (对应show中enforceFocus)        $(document).off("focusin.bs.modal");        // 移除class in  解绑click关闭模态框事件        this.$element.removeClass("in").attr("aria-hidden",true).off("click.dismiss.bs.modal");        // 动画,然后调用hideModal方法(加上背景div的关联处理)        $.support.transition&&this.$element.hasClass("fade")?        this.$element.one("bsTransitionEnd",$.proxy(this.hideModal,this))        .emulateTransitionEnd(300):this.hideModal();    }    //解绑并为document对象注册focusin.bs.modal事件, 具体处理是:如果不是model产生的,就触发model的facus事件    // $element获取焦点    Modal.prototype.enforceFocus = function(){        $(document).off("focusin.bs.modal").on("focusin.bs.modal",$.proxy(function(e){            if(this.$element[0] !== e.target && !this.$element.has(e.target).length){                this.$element.trigger("focus");            }        },this))    }    // esc事件     Modal.prototype.escape = function(){        if(this.isShown && this.options.keyboard){            this.$element.on("keydown.dismiss.bs.modal",$.proxy(function(e){                e.which == 27 && this.hide();            },this));        }else if(!this.isShown){            this.$element.off("keydown.dismiss.bs.modal");        }    }    // 关闭modal    Modal.prototype.hideModal = function(){        var that = this;        // 调用jq的隐藏函数 hide()        this.$element.hide();        // 隐藏背景         this.backdrop(function(){            // 撤销为body加上的class modal-open (overflow:hidden)            that.$body.removeClass("modal-open");            // 还原 为了设置滚动条(使滚动条不可见) body加上的padding-right            that.resetScrollbar();            // 触发hidden.bs.modal事件            that.$element.trigger("hidden.bs.modal");        });    }    // 移除背景div modal-backdrop    Modal.prototype.removeBackdrop = function(){        this.$backdrop && this.$backdrop.remove();        this.$backdrop = null;    }    // callback为具体的model的隐藏或显示逻辑,backdrop负责背景div逻辑    Modal.prototype.backdrop = function(callback){        var that = this;        var animate = this.$element.hasClass("fade")?"fade":"";        if(this.isShown && this.options.backdrop){            //$.support.transition  { end: "webkitTransitionEnd"}            var doAnimate = $.support.transition && animate;            this.$backdrop = $('<div class="modal-backdrop '+ animate +'"></div>')                                .prependTo(this.$element)                                .on("click.dismiss.bs.modal",$.proxy(function(e){  //绑定click.dismiss.bs.modal事件                                    if(e.target !== e.currentTarget) return;                                    // 如果传入option backdrop参数是static 则为静态背景获取焦点 否则隐藏模态框                                    this.options.backdrop == "static"?this.$element[0].focus().call(this.$element[0]):this.hide.call(this);                                },this))            // 准备动画            if(doAnimate) this.$backdrop[0].offsetWidth            this.$backdrop.addClass("in");            if(!callback) return;            //背景div有动画就动画后回调,没有直接回调, 回调是指(显示或关闭逻辑)            doAnimate?this.$backdrop.one("bsTransitionEnd",callback).emulateTransitionEnd(150):callback();        }else if(!this.isShown && this.$backdrop){ //关闭modal框            this.$backdrop.removeClass("in");            //回调函数: 移除遮罩div后回调            var callbackRemove = function(){                that.removeBackdrop()                callback && callback()            }            // 有动画则调用动画            $.support.transition?this.$element.one("bsTransitionEnd",callbackRemove).emulateTransitionEnd(150):callbackRemove();        }else if(callback){            callback();        }    }     Modal.prototype.checkScrollbar = function(){        this.scrollbarWidth = this.measureScrollbar();    }    // 设置body内边距    Modal.prototype.setScrollbar = function(){        var bodyPad = parseInt((this.$body.css("padding-right") || 0),10);        if(this.scrollbarWidth) this.$body.css("padding-right",bodyPad+this.scrollbarWidth);    }    // 还原设置的body内边距    Modal.prototype.resetScrollbar = function(){        this.$body.css('padding-right', '');    }    // 获取滚动条宽度    Modal.prototype.measureScrollbar = function(){        // 如果有滚动条 window.innerWidth >= document.body.clientWidth        // 如果没有滚动条 window.innerWidth = document.body.clientWidth        //如果没有滚动条        if(document.body.clientWidth >= window.innerWidth) return 0;            // 如果有滚动条 创建一个有滚动条的div 获取滚动条宽度        var scrollDiv = document.createElement('div');        scrollDiv.className = "modal-scrollbar-measure";        this.$body.append(scrollDiv);        var scrollbarWidth  = scrollDiv.offsetWidth - scrollDiv.clientWidth;        // 移除刚才创建的div        this.$body[0].removeChild(scrollDiv);        return scrollbarWidth;    }    function Plugin(option,_relatedTarget){        // _relatedTarget目标target <a class="btn btn-default" data-toggle="modal" data-target="#delete">xx</a>        return this.each(function(){            var $this = $(this);            var data = $this.data('bs.modal');            var options = $.extend({},Modal.DEFAULTS,$this.data(),typeof option =='object' && option);            if(!data){                $this.data("bs.modal",(data = new Modal(this,options)));            }            if(typeof option == "string"){  //点击按钮 toggle hide show                data[option](_relatedTarget);                // 未知option data表示new Modal                // data[option]表示 Modal.show /Modal.hide /Modal.toggle            }else if(options.show){ //初始化为显示 则显示                data.show(_relatedTarget)            }        });    }    var old = $.fn.modal;    $.fn.modal = Plugin;    $.fn.modal.Constructor = Modal;    $.fn.modal.noConflict = function(){        $.fn.modal = old;        return this;    }    $(document).on("click.bs.modal.data-api","[data-toggle='modal']",function(e){        var $this = $(this);        var href = $this.attr("href");        // 获取目标模态框id        var $target = $($this.attr("data-target") || (href&&href.replace(/.*(?=#[^\s]+$)/,'')));        /****            $this.data()获取 data-toggle="modal" data-target="#delete"            $this.data() = Object{                target : "#delete",                toggle : "modal"            }            { remote: !/#/.test(href) && href } -> {remote: false/href}        ****/        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){            //如果前面注册的事件处理器一定调用了preventDefault方法,就不会显示,后面也就不绑定隐藏事件了,所以这里也不要处理了            if(showEvent.isDefaultPrevented()) return;            $target.one("'hidden.bs.modal",function(){                $this.is(":visible") && $this.trigger("focus");            });        });        Plugin.call($target,option,this);    });})(jQuery)html:```html<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title>    <link rel="stylesheet" href="css/modal.css"></head><body>    <a class="btn btn-default" data-toggle="modal" data-target="#delete"  href="#ccc">删除</a>    <div class="modal fade" id="delete"  tabindex="-1">        <div class="modal-dialog">            <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>                </div>                <div class="modal-body"></div>                <div class="modal-footer">                    <button type="button" data-dismiss="modal">取消</button>                    <button type="button">确定</button>                </div>            </div>        </div>    </div>    <script src="js/jquery-1.12.3.min.js"></script>    <script src="js/modal.js"></script>    <script>        $(function(){            $('#delete').modal();            // $('#delete').modal({backdrop: "static"});            // $('#delete').on("show.bs.modal",function(e){ console.log("show.bsssss") });            // $('#delete').on("shown.bs.modal",function(e){ console.log("shown.bsssss") });            // $('#delete').on('hide.bs.modal', function (e) {              //  e.preventDefault();            //  console.log("hide.bssss")             // })        })    </script></body></html>

原地址:https://my.oschina.net/haogrgr/blog/323079?p=1

0 0
原创粉丝点击