Bootstrap模態對話框嵌套bug的解決方案


最近在用Bootstrap做項目,越來越發現這是個很好的框架。不過在用的同時也遇到了不少的問題,不過都已經自行解決啦。下面是我對於Bootstrap模態對話框嵌套bug的研究。

什么是模態對話框的嵌套

Bootstrap不用多說了。Bootstrap自帶有模態對話框插件,使用起來很方便,只需按照如下格式定義html,然后用js觸發,或者用指定data屬性的普通html元素來觸發。下面來看一段出現問題的代碼:

<div id="part1" class="modal fade">
        <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>
              <h4 class="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" data-dismiss="modal" data-toggle="modal" data-target="#signup">快速報名</button>
            </div>
          </div><!-- /.modal-content -->
        </div><!-- /.modal-dialog -->
      </div><!-- modal -->

其中定義了data-dismiss="modal"屬性的按鈕用於關閉該模態對話框,稱其為“關閉”按鈕。一般情況下,這樣的默認設置沒有任何問題。但在項目中遇到的問題是:所設計設計的"modal-footer"里面的內容有一個按鈕,包含另一個子模態對話框的定義時,問題就出現了。子模態對話框彈出之后,點擊其“關閉”按鈕,會順帶着把父模態對話框給關閉掉。要解決這樣的問題,或者說是Bootstrap的一個bug,就需要查看源碼了。

Bootstrap相關的源碼研究

好不容易找到了相關的源碼。查看Bootstrap 2.3.1版(未壓縮)的源碼,在872行可以找到如下函數,它定義了模態對話框類的構造函數:

var Modal = function (element, options) {
    this.options = options
    this.$element = $(element)
      .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
    this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
  }

Modal對象的構造在模態對話框顯示之前進行。我們不用關心具體的實現細節,只需看到代碼第3-4行將模態對話框的“隱藏”方法(hide)委托給帶有data-dismiss="modal"屬性的元素的click事件,通俗點說就是:找到父模態對話框中所有帶data-dismiss="modal"屬性的“關閉”元素,對其指定一個click事件處理函數,在這個函數中關閉該模態對話框。當子頁面中包含“關閉”元素時,它也會被賦予父對話框的關閉操作,因此點擊子頁面(子模態對話框)的“關閉”元素就順帶把父模態對話框給關閉了!找到了問題的原因,我們只需根據需要,修改相應的選擇器即可。只需在選擇器后面添加一個:first過濾器,意為選擇父模態對話框中的第一個“關閉”元素即可:

var Modal = function (element, options) {
    this.options = options
    this.$element = $(element)
      .delegate('[data-dismiss="modal"]:first', 'click.dismiss.modal', $.proxy(this.hide, this))
    this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
  }

問題解決。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM