35

背景をクリックするか [Esc] を押してモーダルを閉じることができるデフォルトのオプションで、Twitter Bootstrap モーダルを使用しています。

ただし、モーダルで ajax 操作を開始すると、モーダルが何らかの方法で閉じられるのを無効にしたいと考えています。そのため、ボタンを無効にしてモーダルの閉じるボタンを非表示にしましたが、背景と [Esc] キーを無効にする方法がわかりません。

私は試した:

$('#myModal').modal({
    backdrop: 'static',
    keyboard: false
});

しかし、これはその場で機能しないようです。

また、ajax 操作が終了したら、背景とキーボードを再度有効にする必要があります。

4

6 に答える 6

17

: このソリューションは、twitter ブートストラップ 2.xを対象としています。ブートストラップ 3 による違いについては、この回答(すぐ下) を参照してください。


元のソースを変更せずにブートストラップ モーダル機能を拡張します。

@David とHow to Extend Twitter Bootstrap Pluginでの彼の提案のおかげで、ようやく機能するようになりました。これは、モーダル「ロック」が追加された、彼のソリューションのわずかに変更されたバージョンです。私のようにこの問題に苦労している他の人にとっては出発点になるかもしれないと思うので、追加の回答として投稿します。

// save the original function object
var _superModal = $.fn.modal;

// add locked as a new option
$.extend( _superModal.defaults, {
    locked: false
});

// create a new constructor
var Modal = function(element, options) {
    _superModal.Constructor.apply( this, arguments )
}

// extend prototype and add a super function
Modal.prototype = $.extend({}, _superModal.Constructor.prototype, {
    constructor: Modal

    , _super: function() {
        var args = $.makeArray(arguments)
        // call bootstrap core
        _superModal.Constructor.prototype[args.shift()].apply(this, args)
    }

    , lock : function() {
        this.options.locked = true
    }

    , unlock : function() {
        this.options.locked = false
    }

    , hide: function() {
        if (this.options.locked) return
        this._super('hide')
    }
});

// override the old initialization with the new constructor
$.fn.modal = $.extend(function(option) {
    var args = $.makeArray(arguments),
    option = args.shift()

    // this is executed everytime element.modal() is called
    return this.each(function() {
        var $this = $(this)
        var data = $this.data('modal'),
            options = $.extend({}, _superModal.defaults, $this.data(), typeof option == 'object' && option)

        if (!data) {
            $this.data('modal', (data = new Modal(this, options)))
        }
        if (typeof option == 'string') {
            data[option].apply( data, args )
        }
    });
}, $.fn.modal);

この手法を使用すると、bootstrap.js を変更する必要がなくなり、同じ機能をより簡単にブートストラップ プロジェクト間で共有できます。この方法は、他のすべてのブートストラップ プラグインに適用できるはずです。これまでボタンでしか試したことはありませんが、なぜそうすべきなのかわかりません。

作業中のフィドルを参照してください-> http://jsfiddle.net/Sz7ZS/

于 2012-11-19T19:05:54.943 に答える
9

その機能を欠いているのはあなただけではありません。ブートストラップは「最小限」すぎる場合があると思います。背後にいる人々は、「実装レイヤー」で多くのことを行う必要があると考えていますが、ブートストラップjQueryプラグイン自体がそれを不可能にする場合は役に立ちません。

次のように、自分で機能を実装する必要があります

v2.1.1では、bootstrap.jsモーダルは61行目から始まります。

Modal.prototype、2つの関数を追加するlockunlock、次のようになります(modal.prototypeコードが多すぎるため、ここでは先頭のみを示します)

  Modal.prototype = {

      constructor: Modal

      //add this function
    , lock: function () {
        this.options.locked = true
      }

      //add this function
    , unlock: function () {
        this.options.locked = false
      }

    , toggle: function () {
    ... 
    ...

次に、同じくModal.prototypeで、関数を見つけて、hide次のようになるように行を追加します(ここでも、非表示の上部のみが表示されます)

, hide: function (e) {
    e && e.preventDefault()

    var that = this

    //add this line
    if (that.options.locked) return

    e = $.Event('hide')
    ...
    ...

そして最後に、次のように変更$.fn.modal.defaultsします。

  $.fn.modal.defaults = {
      backdrop: true
    , keyboard: true
    , show: true
    , locked: false //this line is added
  }

これで、ブートストラップモーダルにオンザフライのロック/ロック解除機能があり、ユーザーが重要な瞬間にモーダルを閉じるのを防ぐことができます。

これは、 http://twitter.github.com/bootstrap/javascript.html#modalsの「LiveDemo」の変更バージョンです。

<!-- Button to trigger modal -->
<a href="#myModal" role="button" class="btn" data-toggle="modal">Launch demo modal</a>

<!-- Modal -->
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    <h3 id="myModalLabel">Modal header</h3>
  </div>
  <div class="modal-body">
    <p>One fine body…&lt;/p>
  </div>
  <div class="modal-footer">
    <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
    <button class="btn btn-primary" onclick="$('#myModal').modal('lock');">lock</button>
    <button class="btn btn-primary" onclick="$('#myModal').modal('unlock');">unLock</button>
  </div>
</div>
<script type="text/javascript">

「ロック」と「ロック解除」の2つのボタンを挿入しました。クリックすると、モーダルがロックモードまたは通常モードに設定されます(初期化された設定)

編集、あなたの場合、あなたはajaxをするときにlock / onlockを呼び出す必要があります:

$("myModal").modal('lock');
$.ajax({
    url: url,
    ...
    ...
    , success(html) {
       ...
       ...
       $("#myModal").modal('unlock');
    }
});
于 2012-11-17T16:54:10.403 に答える
8

true への AJAX 呼び出しを実行中に設定できる変数 isBlocked を作成すると、次の方法でブートストラップ モーダル非表示イベントで確認できます。

$('#myModal').on('hide.bs.modal', function (e) {
      //Prevent modal from closing is isBlocked is true
      if(isBlocked) return e.preventDefault();
})

この方法は Bootsrap を拡張するよりも簡単だと思います。誰かの役に立てば幸いです :D

于 2014-09-16T11:01:32.257 に答える
5

これに取り組んでくれてありがとう@davidkonrad。私もこれを実装しようとしていましたが、ブートストラップ 3 で状況が変わったようです。

_superModal.defaults

コンストラクターにアタッチされるようになったので、やらなければなりません

_superModal.Constructor.DEFAULTS

また、コンストラクターが変更されたため、それをコピーして変更する必要がありましたが、これは理想的ではありません。代わりに、機能し、コンストラクターをコピーしない次のコードを思いつきました。ブートストラップが今後変更された場合、より確実に実行できるはずです。やってみます:

// save the original function object
var _superModal = $.fn.modal;

// add locked as a new option
$.extend( _superModal.Constructor.DEFAULTS, {
    locked: false
});

// capture the original hide
var _hide = _superModal.Constructor.prototype.hide;
// console.log('HIDE:', _hide);

// add the lock, unlock and override the hide of modal
$.extend(_superModal.Constructor.prototype, {
    // locks the dialog so that it cannot be hidden
    lock: function() {
        // console.log('lock called');
        // console.log('OPTIONS',this.options);
        this.options.locked = true;
    }
    // unlocks the dialog so that it can be hidden by 'esc' or clicking on the backdrop (if not static)
    ,unlock: function() {
        // console.log('unlock called');
        this.options.locked = false;
    }
    // override the original hide so that the original is only called if the modal is unlocked
    ,hide: function() {
        // console.log('hide called');
        if (this.options.locked) return;

        _hide.apply(this, arguments);
    }
});

したがって、モーダルをロックするには:

$('#dlg').modal('lock');

ロックを解除するには:

$('#dlg').modal('unlock');

わーい!

于 2013-11-25T02:43:42.680 に答える