>웹 프론트엔드 >JS 튜토리얼 >Bootstrap 모달 팝업 상자 예제 튜토리얼

Bootstrap 모달 팝업 상자 예제 튜토리얼

PHPz
PHPz원래의
2018-05-15 15:43:453455검색

이전 단어

  Bootstrap 프레임워크에서는 모달 팝업 상자를 총칭하여 Modal이라고 합니다. 이 팝업 효과는 대부분의 웹 사이트 상호 작용에서 볼 수 있습니다. 예를 들어, 버튼을 클릭하면 팝업 상자가 나타나며, 팝업 상자에는 파일 설명이 있을 수도 있고, 버튼 조작이 있을 수도 있고, 그림이 나타날 수도 있습니다. 이번 글에서는 부트스트랩 모달 팝업 상자

구조 분석

을 자세히 소개하겠습니다. -dialog"와 "modal-content" 스타일이 있으며, 팝업 창의 실제 내용은 "modal-content"에 배치되는데, 이는 주로 세 부분으로 구성됩니다. 일반적으로 "modal-header"로 표현되며, 주로 제목과 닫기 버튼을 포함합니다  🙌 팝업 상자의 본문, 일반적으로 "modal-body"로 표현되는 팝업 상자의 주요 내용   xml 일반적으로 "modal-footer"로 표시되는 팝업 상자의 하단에는 주로 작업 버튼이 배치됩니다.

<p class="modal show"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button><h4 class="modal-title">模态弹出窗标题</h4></p><p class="modal-body"><p>模态弹出窗主体内容</p></p><p class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">关闭</button><button type="button" class="btn btn-primary">保存</button></p></p><!-- /.modal-content --></p><!-- /.modal-dialog --></p><!-- /.modal -->

팝업 창의 경우 모달 콘텐츠가 스타일의 핵심입니다. 주로 팝업창의 테두리, 여백, 배경색, 그림자 스타일을 설정합니다

.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-content의 modal-header, modal-body, modal-footer 세 부분의 스타일은 다음과 같이 설정됩니다.

.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;
}

이 세 부분은 주로 일부 간격 스타일을 제어합니다. 모달 바닥글은 버튼을 배치하는 데 사용되므로 포함된 버튼도 하단에 스타일이 지정됩니다. 특정 작업(이벤트)만 모달 팝업 창 표시를 트리거할 수 있습니다. Bootstrap 프레임워크에는 두 가지 구현 방법이 있습니다

트리거링 방법을 소개하기 전에 먼저 .show 및 .fade 두 가지 방법을 설명해야 합니다. 모달 팝업 창만 표시를 실행하기 위해 기본적으로 숨겨집니다

.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;
}

[방법 1]

  모달 팝업 창을 선언하려면 data-toggle 및 data-라는 두 가지 필수 속성만 사용자 정의하면 됩니다. 대상(부트스트랩에 선언됨 수식 트리거 방법은 일반적으로 이러한 사용자 정의 data-xxx 속성에 의존합니다. 예를 들어 data-toggle="" 또는 data-dismiss="")

 data-toggle은 모달로 설정되어야 합니다(중국어 번역 전환)

 data-target은 CSS 선택기로 설정할 수도 있고, 일반적으로 모달 팝업창의 ID 값으로 설정할 수도 있습니다. window, 왜냐하면 ID 값은 고유한 값이기 때문입니다

.fade {opacity: 0;
-webkit-transition: opacity .15s linear;
-o-transition: opacity .15s linear;
transition: opacity .15s linear;
}.show {display: block!important;
}

【방법 2】

  모달 팝업 창은 링크 요소에 의해 트리거될 수도 있으며, 대신 link 요소의 href 속성을 사용할 수 있습니다.

그러나

<!-- 触发模态弹出窗的元素 --><button type="button" data-toggle="modal" data-target="#mymodal" class="btn btn-primary">点击</button><!-- 模态弹出窗 --><p class="modal fade" id="mymodal"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button><h4 class="modal-title">模态弹出窗标题</h4></p><p class="modal-body"><p>模态弹出窗主体内容</p></p><p class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">关闭</button><button type="button" class="btn btn-primary">保存</button></p></p><!-- /.modal-content --></p><!-- /.modal-dialog --></p><!-- /.modal -->

Dimensions

을 트리거하려면 데이터 대상의 통합 사용을 사용하는 것이 좋습니다. Bootstrap 프레임워크는 모달 팝업에 대해 다양한 크기를 제공합니다. 그 중 하나는 대형 스타일입니다." modal-lg"이고 다른 하나는 작은 크기 스타일의 "modal-sm"입니다. 구조가 약간 조정되었습니다

 [참고].bs-example-modal-lg 및 .bs-example-modal-sm은 맞춤 이름이며 필수는 아닙니다

<!-- 触发模态弹出窗的元素 --><a data-toggle="modal" href="#mymodal" class=" btn btn-primary" >点击</a><!-- 模态弹出窗 --><p class="modal fade" id="mymodal"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button><h4 class="modal-title">模态弹出窗标题</h4></p><p class="modal-body"><p>模态弹出窗主体内容</p></p><p class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">关闭</button><button type="button" class="btn btn-primary">保存</button></p></p><!-- /.modal-content --></p><!-- /.modal-dialog --></p><!-- /.modal -->
<!-- 大尺寸模态弹出窗 --><p class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true"><p class="modal-dialog modal-lg">   <p class="modal-content"> ... </p></p></p><!-- 小尺寸模态弹出窗 --><p class="modal fade bs-example-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"><p class="modal-dialog modal-sm">   <p class="modal-content"> ... </p></p></p>

CSS 구문 분석

 부트스트랩 "Pop- up box"는 다음과 같은 특징을 가지고 있습니다.

 1. 모달 팝업 창이 브라우저에서 수정되었습니다.

 2. 오른쪽의 전체화면 버튼을 클릭하세요. 전체화면 상태에서 모달 팝업창의 너비는 가변적이며, 모달 대화상자는 가로 중앙에 위치합니다.

 3. 브라우저 창이 768px보다 큰 경우 모달 팝업창의 너비는 600px입니다

 4. 모달 팝업창의 배경은 종종 투명한 마스킹 효과를 가집니다

 5. 팝업이 표시될 때 -업창이 발생하면 팝업창은 위에서 아래로 점차적으로 페이지 앞쪽으로 나옵니다

【브라우저 구현에 고정】

<button type="button" class="btn btn-primary" data-toggle="modal" data-target=".bs-example-modal-lg">大尺寸</button><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">默认尺寸</button><button type="button" class="btn btn-primary" data-toggle="modal" data-target=".bs-example-modal-sm">小尺寸</button><p class="modal fade" id="myModal"><p class="modal-dialog"><p class="modal-content"><p class="modal-body"><p>小火柴的蓝色理想</p></p></p></p></p><p class="modal fade bs-example-modal-lg"><p class="modal-dialog modal-lg"><p class="modal-content"><p class="modal-body"><p>小火柴的蓝色理想</p></p></p></p></p><p class="modal fade bs-example-modal-sm"><p class="modal-dialog modal-sm"><p class="modal-content"><p class="modal-body"><p>小火柴的蓝色理想</p></p></p></p></p>

【가로 중심 구현】

.modal {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1050;
  display: none;
  overflow: hidden;
  -webkit-overflow-scrolling: touch;
  outline: 0;
}

【브라우저 창이 뜰 때 768px보다 크면 모달 팝업창의 너비는 600px로 구현됩니다. 】

.modal-dialog {
  position: relative;
  width: auto;
  margin: 10px;
}

【Mask】

  팝업창이 뜨면 .modal-open 클래스를 추가하세요. <body> 요소를 사용하여 페이지의 기본 스크롤 동작을 재정의하고 .modal-backdrop 요소가 자동으로 생성되어 클릭 가능한 영역을 제공합니다. 모달 상자를 닫으려면 이 영역

@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;
  }}
.modal-open {overflow: hidden;
}

 전환 애니메이션이 추가되어 페이드에서 인으로 불투명도 값이 0에서 0.5로 변경됩니다.

.modal-backdrop {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1040;
  background-color: #000;
}

[애니메이션 효과]

 팝업 창의 애니메이션 내용은 다음과 같습니다. 상위 값 위치 -25%부터 상위 위치:0

.modal-backdrop.fade {
  filter: alpha(opacity=0);
  opacity: 0;
}.modal-backdrop.in {
  filter: alpha(opacity=50);
  opacity: .5;
}

 모달박스가 팝업되지 않는 경우 애니메이션 효과(페이드 효과)는 .fade 클래스를 삭제하세요.

.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: translate3d(0, -25%, 0);   -o-transform: translate3d(0, -25%, 0);  transform: translate3d(0, -25%, 0);
}.modal.in .modal-dialog {
  -webkit-transform: translate3d(0, 0, 0);   -o-transform: translate3d(0, 0, 0);  transform: translate3d(0, 0, 0);
}

매개변수 설명

데이터 토글 및 데이터 대상을 통해 모달 팝업 창을 제어하는 ​​것 외에도 Bootstrap 프레임워크는 모달 팝업을 제어하기 위해 모달 팝업에 다른 사용자 정의 데이터 속성이 제공됩니다. 모달 팝업 창의 사용자 정의 속성에 대한 관련 지침은 다음과 같습니다<body> 元素添加 .modal-open类,从而覆盖页面默认的滚动行为,并且还会自动生成一个 .modal-backdrop 元素用于提供一个可点击的区域,点击此区域就即可关闭模态框

<!-- 触发模态弹出窗的元素 --><button type="button" data-toggle="modal" data-target="#mymodal" class="btn btn-primary">点击</button><!-- 模态弹出窗 --><p class="modal" id="mymodal"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button><h4 class="modal-title">模态弹出窗标题</h4></p><p class="modal-body"><p>模态弹出窗主体内容</p></p><p class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">关闭</button><button type="button" class="btn btn-primary">保存</button></p></p><!-- /.modal-content --></p><!-- /.modal-dialog --></p><!-- /.modal -->
<button type="button" data-toggle="modal" data-target="#mymodal1" class="btn btn-primary">默认样式</button><button type="button" data-toggle="modal" data-target="#mymodal2" data-backdrop="false" class="btn btn-primary">无蒙版</button><button type="button" data-toggle="modal" data-target="#mymodal3" data-keyboard="false" class="btn btn-primary">ESC失效</button><button type="button" data-toggle="modal" data-target="#mymodal4" data-show="false" class="btn btn-primary">弹窗默认不显示</button><p class="modal fade"  tabindex="-1" id="mymodal1"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button><h4 class="modal-title">小火柴的蓝色理想</h4></p>        
<p class="modal-body"><p>好的代码像粥一样,都是用时间熬出来的</p></p></p></p></p><p class="modal fade"  
tabindex="-1" id="mymodal2"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;
</span><span class="sr-only">Close</span></button><h4 class="modal-title">小火柴的蓝色理想</h4></p>        
<p class="modal-body"><p>好的代码像粥一样,都是用时间熬出来的</p></p></p></p></p><p class="modal fade"  
tabindex="-1" id="mymodal3"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;
</span><span class="sr-only">Close</span></button><h4 class="modal-title">小火柴的蓝色理想</h4></p>        
<p class="modal-body"><p>好的代码像粥一样,都是用时间熬出来的</p></p></p></p></p><p class="modal fade"  
tabindex="-1" id="mymodal4"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;
</span><span class="sr-only">Close</span></button><h4 class="modal-title">小火柴的蓝色理想</h4></p>        
<p class="modal-body"><p>好的代码像粥一样,都是用时间熬出来的</p></p></p></p></p>

  给其添加了一个过渡动画,从fade到in,把opacity值从0变成了0.5

$('#myModal').modal()

【动画效果】

  弹窗的动画内容是从-25%的top值位置到top:0的位置

<button type="button" class="btn btn-primary">点击</button><p class="modal fade"  
tabindex="-1" id="mymodal"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;
</span><span class="sr-only">Close</span></button><h4 class="modal-title">小火柴的蓝色理想</h4></p>        
<p class="modal-body"><p>好的代码像粥一样,都是用时间熬出来的</p></p></p></p></p><script>$(function(){
    $(".btn").click(function(){
        $("#mymodal").modal();
    });
});</script>

  如果不需要模态框弹出时的动画效果(淡入淡出效果),删掉 .fade

 이 매개 변수는 버튼이나 팝업 창에서 설정할 수 있습니다. 편의상 일반적으로 버튼에

를 설정합니다. [참고] 팝을 닫는 데 Esc 키를 지원하려면 속성 값을 따옴표로 묶어야 합니다. 팝업 창에 tabindex를 설정해야 합니다. ="-1"

<button type="button" data-toggle="modal" data-target="#mymodal1" class="btn btn-primary">默认样式</button><button type="button" data-toggle="modal" data-target="#mymodal2" data-backdrop="false" class="btn btn-primary">无蒙版</button><button type="button" data-toggle="modal" data-target="#mymodal3" data-keyboard="false" class="btn btn-primary">ESC失效</button><button type="button" data-toggle="modal" data-target="#mymodal4" data-show="false" class="btn btn-primary">弹窗默认不显示</button><p class="modal fade"  tabindex="-1" id="mymodal1"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button><h4 class="modal-title">小火柴的蓝色理想</h4></p>        
<p class="modal-body"><p>好的代码像粥一样,都是用时间熬出来的</p></p></p></p></p><p class="modal fade"  
tabindex="-1" id="mymodal2"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;
</span><span class="sr-only">Close</span></button><h4 class="modal-title">小火柴的蓝色理想</h4></p>        
<p class="modal-body"><p>好的代码像粥一样,都是用时间熬出来的</p></p></p></p></p><p class="modal fade"  
tabindex="-1" id="mymodal3"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;
</span><span class="sr-only">Close</span></button><h4 class="modal-title">小火柴的蓝色理想</h4></p>        
<p class="modal-body"><p>好的代码像粥一样,都是用时间熬出来的</p></p></p></p></p><p class="modal fade"  
tabindex="-1" id="mymodal4"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;
</span><span class="sr-only">Close</span></button><h4 class="modal-title">小火柴的蓝色理想</h4></p>        
<p class="modal-body"><p>好的代码像粥一样,都是用时间熬出来的</p></p></p></p></p>

JS触发

  除了使用自定义属性data-触发模态弹出框之外,还可以通过JavaScript方法来触发模态弹出窗。比如说给按钮设置一个单击事件,然后触发模态弹出窗 

  只需一行 JavaScript 代码,即可通过元素的 id myModal 调用模态框

$('#myModal').modal()
<button type="button" class="btn btn-primary">点击</button><p class="modal fade"  
tabindex="-1" id="mymodal"><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;
</span><span class="sr-only">Close</span></button><h4 class="modal-title">小火柴的蓝色理想</h4></p>        
<p class="modal-body"><p>好的代码像粥一样,都是用时间熬出来的</p></p></p></p></p><script>$(function(){
    $(".btn").click(function(){
        $("#mymodal").modal();
    });
});</script>

  使用JavaScript触发模态弹出窗时,Bootstrap框架提供了一些设置,主要包括属性设置、参数设置和事件设置

【属性设置】

  模态弹出窗默认支持的自定义属性主要有

  不想让用户按ESC键关闭模态弹出窗,可以这样做 

$(function(){
    $(".btn").click(function(){
        $("#mymodal").modal({
            keyboard:false});
    });
});

【参数设置】

  在Bootstrap框架中还为模态弹出窗提供了三种参数设置,具体说明如下


<button type="button" class="btn btn-primary" id="btn" style="position:absolute;z-index:9999">打开(关闭)</button>
<p class="modal"  tabindex="-1" id="mymodal" >
    <p class="modal-dialog">
        <p class="modal-content">
            <p class="modal-header">
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;
                </span><span class="sr-only">Close</span></button>
                <h4 class="modal-title">小火柴的蓝色理想</h4>
            </p>        
            <p class="modal-body">
                <p>好的代码像粥一样,都是用时间熬出来的</p>
            </p>
        </p>
    </p>
</p>
<script>;$(function(){
    $("#btn").click(function(){
         $("#mymodal").modal("toggle");
    });
});</script>

【事件设置】

  模态弹窗还支持五种类型的事件,分别是模态弹出窗的弹出前、弹出后,关闭前、关闭后及远端数据加载后,具体描述如下: 

<button type="button" class="btn btn-primary" id="btn" style="position:absolute;z-index:9999">打开</button><p class="modal"  
tabindex="-1" id="mymodal" ><p class="modal-dialog"><p class="modal-content"><p class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;
</span><span class="sr-only">Close</span></button><h4 class="modal-title">小火柴的蓝色理想</h4></p>        
<p class="modal-body"><p>好的代码像粥一样,都是用时间熬出来的</p></p></p></p></p><script>;$(function(){
    $("#btn").click(function(){
         $("#mymodal").modal("toggle");
    });
    $('#mymodal').on('hide.bs.modal', function(){
        $("#btn").html("打开");
    });
    $('#mymodal').on('show.bs.modal', function(){
        $("#btn").html("关闭");
    });    
});</script>

JS解析

【1】IIFE

  使用立即调用函数,防止插件内代码外泄,从而形成一个闭环,并且只能从jQuery的fn里进行扩展

+function ($) {//使用es5严格模式'use strict';//}(window.jQuery);

【2】初始设置

  var Modal = function (element, options) {
  this.options             
  = options//options是设置选项this.$body               
  = $(document.body)//body元素this.$element            
  = $(element)////element表示modal弹出框容器及内容元素this.$dialog             
  = this.$element.find('.modal-dialog')//弹窗对象this.$backdrop           
  = null //蒙版对象this.isShown             
  = null //弹窗是否显示的标识this.originalBodyPad     
  = null //body的padding-right标识this.scrollbarWidth      
  = 0 //滚动条宽度为0this.ignoreBackdropClick = false //默认蒙板可点击
  //如果设置了remote,就加载remote指定url的内容到modal-content样式的元素内,并触发loaded.bs.modal事件
  if (this.options.remote) {      
  this.$element
        .find('.modal-content')
        .load(this.options.remote, $.proxy(function () {          
        this.$element.trigger('loaded.bs.modal')
        }, this))
    }
  }  //组件版本号3.3.7
  Modal.VERSION  = '3.3.7'  //动画持续时间300ms
  Modal.TRANSITION_DURATION = 300  //蒙版动画持续时间150ms
  Modal.BACKDROP_TRANSITION_DURATION = 150  //默认设置
  Modal.DEFAULTS = {
    backdrop: true, //显示蒙版keyboard: true, //按ESC键关闭弹窗show: true //单击触发元素时打开弹窗
  }

【3】插件核心代码

  主要是Modal核心类函数的定义、默认参数的定义和9个原型方法的定义,这9个原型方法主要是处理弹窗的反转、打开、关闭和弹窗背景设置、取消等操作

  // 反转弹窗(打开或关闭)
  Modal.prototype.toggle = function (_relatedTarget) {//如果弹窗处于显示状态,则调用hide()方法,关闭它;否则,调用show()方法,打开弹窗return this.isShown ? this.hide() : this.show(_relatedTarget)
  }  // 打开弹窗
  Modal.prototype.show = function (_relatedTarget) {//保存this值var that = this//定义弹窗前的触发事件
  var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })//打开弹窗前,触发事件
  this.$element.trigger(e)// 如果已经打开了(或者曾经被阻止过),则退出执行,后续代码不做处理
  if (this.isShown || e.isDefaultPrevented()) 
  return//设置弹窗显示标识为true
  this.isShown = truethis.checkScrollbar()this.setScrollbar()this.$body.addClass('modal-open')//处理键盘事件,主要是设置按esc键时是否关闭弹窗
  this.escape()this.resize()// 如果单击了元素内的子元素(带有[data-dismiss="modal"]属性),则关闭弹窗
  this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))//点击弹窗时,如果鼠标的目标是当前弹窗,则将默认蒙板不可点击的标识置为true,并不可再设置
  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  })
    })//绘制蒙版后,处理以下代码this.backdrop(function () {      
    // 判断浏览器是否支持动画,并且弹窗是否设置了动画过渡效果(是否有fade样式)     
    var transition = $.support.transition && that.$element.hasClass('fade')      
    // 如果modal弹窗没有父容器,则将它附加到body上  
    if (!that.$element.parent().length) {
        that.$element.appendTo(that.$body)
      }      // 显示modal弹窗      that.$element
        .show()
        .scrollTop(0)
      that.adjustDialog()      // 如果支持动画,强制刷新UI现场,重绘弹窗  if (transition) {
        that.$element[0].offsetWidth
      }      // 给modal弹窗添加in样式,和modal样式一起  that.$element.addClass('in')      // 强制给弹窗设定焦点      that.enforceFocus()      // 打开弹窗显示后的触发事件  var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
      transition ?that.$dialog //找到弹窗元素  .one('bsTransitionEnd', function () {// 如果支持动画,则动画结束以后给弹窗内的元素设置焦点,并触发shown事件that.$element.trigger('focus').trigger(e)
          })
          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :// 否则直接设置焦点,并触发shown事件  that.$element.trigger('focus').trigger(e)
    })
  }  // 关闭弹窗
  Modal.prototype.hide = function (e) {//阻止冒泡
  if (e) e.preventDefault()//定义关闭弹窗前的触发事件
  e = $.Event('hide.bs.modal')//关闭弹窗前触发事件
  this.$element.trigger(e)// 如果已经关闭了(或者曾经被阻止过),则退出执行,后续代码不做处理
  if (!this.isShown || e.isDefaultPrevented()) return//设置显示状态标识为false
  this.isShown = false//处理键盘事件,主要是设置按Esc键的时候是否关闭弹窗
  this.escape()this.resize()//取消所有的focusin.bs.modal事件
  $(document).off('focusin.bs.modal')this.$element
      .removeClass('in') //删除in样式  
      .off('click.dismiss.bs.modal') //取消dismiss的单击事件  
      .off('mouseup.dismiss.bs.modal')//取消dismiss的鼠标抬起事件//取消dismiss的鼠标放下事件
      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()
  }  //强制弹窗处于焦点状态
  Modal.prototype.enforceFocus = function () {
    $(document)      // 禁用所有的focusin事件,防止无限循环  .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) {      //如果弹窗是打开状态,并且keyboard选项为true,则说明允许按ESC键可以关闭弹窗  
  this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {//检测键盘事件,如果是ESC(keycode=27),则关闭
  e.which == 27 && this.hide()
      }, this))
    } else if (!this.isShown) {      // 否则,取消键盘事件检测  
    this.$element.off('keydown.dismiss.bs.modal')
    }
  }

  Modal.prototype.resize = function () {if (this.isShown) {
      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
    } else {
      $(window).off('resize.bs.modal')
    }
  }  //关闭弹窗
  Modal.prototype.hideModal = function () {
  var that = this//关闭弹窗
  this.$element.hide()this.backdrop(function () {      //移除body上的modal-open样式 
  that.$body.removeClass('modal-open')
      that.resetAdjustments()
      that.resetScrollbar()      //关闭以后,触发hidden事件  
      that.$element.trigger('hidden.bs.modal')
    })
  }    

  //删除蒙版,关闭弹窗时触发
  Modal.prototype.removeBackdrop = function () {// 删除蒙版
  this.$backdrop && this.$backdrop.remove()// 设置蒙版对象为null
  this.$backdrop = null
  }  

  //添加蒙版,打开弹窗时触发
  Modal.prototype.backdrop = function (callback) {
  var that = this//是否设置了动画过渡效果,如果是则将animate设置为fade
  var animate = this.$element.hasClass('fade') ? 'fade' : ''//如果是打开状态,并且设置了backdrop参数
  if (this.isShown && this.options.backdrop) {      //定义动画标识  
  var doAnimate = $.support.transition && animate      // 在body上定义蒙版p元素,并附加fade标识以支持动画  
  this.$backdrop = $(document.createElement('p'))
        .addClass('modal-backdrop ' + animate)
        .appendTo(this.$body)      //蒙版被单击时进行判断:如果backdrop参数为static,则强制将弹窗设置为售点;否则,关闭弹窗  
        this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {if (this.ignoreBackdropClick) {          
        this.ignoreBackdropClick = false  return}if (e.target !== e.currentTarget) returnthis.options.backdrop == 'static'
          ? this.$element[0].focus()
          : this.hide()
      }, this))      // 如果支持动画,强制刷新UI现场,重绘弹窗  if (doAnimate) this.$backdrop[0].offsetWidth 
      //添加in样式  this.$backdrop.addClass('in')      //如果没有回调,则直接返回  
      if (!callback) 
      return  // 如果支持动画,则动画结束执行回调函数;否则,直接执行回调函数  
      doAnimate ?this.$backdrop
          .one('bsTransitionEnd', callback)
          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
        callback()      //如果是关闭状态,但蒙版对象依然还存在  
        } 
        else if (!this.isShown && this.$backdrop) {      //去除in样式  
        this.$backdrop.removeClass('in')      
        var callbackRemove = function () {
        that.removeBackdrop()
        callback && callback()
      }      // 如果支持动画,则动画结束执行回调函数;否则,直接执行回调函数  
      $.support.transition && this.$element.hasClass('fade') ?this.$backdrop
          .one('bsTransitionEnd', callbackRemove)
          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
        callbackRemove()

    } else if (callback) {
      callback()
    }
  }

【4】滚动条处理

  在弹窗插件中,使用了大量的代码对滚动条进行处理

  Modal.prototype.handleUpdate = function () {this.adjustDialog()
  }  //处理因为滚动条而使弹窗位置不固定问题
  Modal.prototype.adjustDialog = function () {//如果元素的高度大于页面的高度,即溢出屏幕,则modalIsOverflowing置为true
  var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight//将元素的paddingLeft和paddingRight设置为scrollbarWidth
  this.$element.css({
      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''})
  }  //重置调节器
  Modal.prototype.resetAdjustments = function () {//将元素的paddingLeft和paddingRight置为空this.$element.css({
      paddingLeft: '',
      paddingRight: ''})
  }  //检查滚动条
  Modal.prototype.checkScrollbar = function () {//fullWindowWidth储存页面宽度
  var fullWindowWidth = window.innerWidth//IE8-浏览器不支持innerWidth属性
  if (!fullWindowWidth) {      //使用getBoundingClientRect方法来获得页面宽度   
  var documentElementRect = document.documentElement.getBoundingClientRect()
      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
    }//如果有滚动条,则bodyIsOverflowing置为true
    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth//将scrollbarWidth置为实际的滚动条宽度
    this.scrollbarWidth = this.measureScrollbar()
  }  //用来为body元素设置padding-right的值,防止body元素被scrollbar阻挡
  Modal.prototype.setScrollbar = function () {
  var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)this.originalBodyPad = document.body.style.paddingRight || ''//如果页面存在滚动条,则body的padding-right设置为默认的padding-right加上滚动条的宽度
  if (this.bodyIsOverflowing) 
  this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
  }  //重置滚动条
  Modal.prototype.resetScrollbar = function () {//将body的padding-right值设置为null
  this.$body.css('padding-right', this.originalBodyPad)
  } 
  
  //测量滚动条宽度
  Modal.prototype.measureScrollbar = function () {var scrollDiv = document.createElement('p')
    scrollDiv.className = 'modal-scrollbar-measure'this.$body.append(scrollDiv)//滚动条宽度等于offetWidth 
    - clientWidthvar scrollbarWidth = scrollDiv.offsetWidth 
    - scrollDiv.clientWidththis.$body[0].removeChild(scrollDiv)return scrollbarWidth
  }

【5】jQuery插件定义

  在jQuery上定义插件,有点特殊的代码是options参数的收集和合并,主要收集了3个部分:插件的默认参数DEFAULTS、modal元素上的data-属性,执行插件时传入的option对象,这三个部分的优先级依次升高

  function Plugin(option, _relatedTarget) {//根据选择器,遍历所有符合规则的元素
  return this.each(function () {      
  var $this   = $(this)      //获取自定义属性bs.modal的值  
  var data    = $this.data('bs.modal')      //将插件的默认参数DEFAULTS、modal元素上的data-属性,执行插件时传入的option对象,这三种值合并到一起,作为options参数  //后面的参数的优先级高于前面的参数  
  var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)      
  //如果值不存在,则将Modal实例设置为bs.modal值  if (!data) $this.data('bs.modal', (data = new Modal(this, options)))      
  //如果option传递了string,则表示要执行某个方法  
  if (typeof option == 'string') data[option](_relatedTarget)      else if (options.show) data.show(_relatedTarget)
    })
  }  var old = $.fn.modal  //保留其他库的$.fn.modal代码(如果定义的话),以便在noConflict之后可以继续使用该老代码
  $.fn.modal             = Plugin  
  //重设插件构造器,可以通过该属性获取插件的真实类函数
  $.fn.modal.Constructor = Modal

【6】防冲突处理

  $.fn.modal.noConflict = function () {//恢复以前的旧代码$.fn.modal = old//将$.fn.modal.noConflict()设置为Bootstrap的Modal插件return this
  }

【7】绑定触发事件

  //监测所有拥有自定义属性data-toggle="modal"的元素上的单击事件
  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
  var $this   = $(this)//获取href属性值
  var href    = $this.attr('href')//获取data-target属性值,如果没有,则获取href值,该值是所弹出元素的idvar 
  $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //如果弹窗元素上已经弹窗实例(即弹出过一次了),则设置option值为字符串toggle,否则将remote值(如果有的话)、弹窗元素上的自定义属性值集合、触发元素上的自定义属性值集合,合并为option对象var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())//如果是a链接,则阻止其默认行为if ($this.is('a')) e.preventDefault()
    $target.one('show.bs.modal', function (showEvent) {      if (showEvent.isDefaultPrevented()) return 
      //定义一次hidden事件,给所单击元素设置focus  $target.one('hidden.bs.modal', function () {
        $this.is(':visible') && $this.trigger('focus')
      })
    })
    Plugin.call($target, option, this)
  })

}(jQuery);


 

위 내용은 Bootstrap 모달 팝업 상자 예제 튜토리얼의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.