私はTwitter Bootstrap modalsを使用しています。デフォルトのオプションでは、背景をクリックするか、[Esc]を押してモーダルを閉じます。
ただし、モーダルでajax操作を開始するときは、モーダルが何らかの方法で閉じられないようにします。そのため、ボタンを無効にしてモーダルの閉じるボタンを非表示にしていますが、背景と[Esc]キーを無効にする方法がわかりません。
私は試した:
$('#myModal').modal({
backdrop: 'static',
keyboard: false
});
しかし、これはその場では機能しないようです。
また、ajax操作が終了したら、背景とキーボードを再度有効にする必要があります。
注:このソリューションの対象は Twitter bootstrap 2.x !参照 この回答 (すぐ下)bootstrap 3。
拡張bootstrap=モーダル機能なしで元のソースを変更せずに.
@Davidと彼の提案のおかげで Twitterを拡張する方法Bootstrapプラグイン ようやく動作しました。これは、モーダル「ロック」を使用した彼のソリューションのわずかに変更されたバージョンです「追加しました。私と同じようにこの問題に苦労している他の人にとっては、それが出発点になると思うので、私はそれを追加の回答として投稿します。
// 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を変更する必要はありません。同じ機能をbootstrapプロジェクト間でより簡単に共有できます。このメソッドは、他のすべてのbootstrap plugins。これまでのところ、ボタンのみで試してみましたが、なぜそれがいけないのかわかりません。
動作中のフィドルを参照->http://jsfiddle.net/Sz7ZS/
それを行う簡単な方法があります。 これ bootstrapプルリクエストはもう少し説明します。ソリューションはモーダルを閉じるためのすべてのメソッド(キーボード、マウスクリック、閉じるボタン)を無効にします。
モーダルを閉じることを無効にするためにあなたがしなければならないすべては次のとおりです:
$('#myModal').data('bs.modal').isShown = false;
クローズを再度有効にするには:
$('#myModal').data('bs.modal').isShown = true;
例
以下は、jQuery getと連携して機能するサンプルコードです。
// disable closing the modal
$('#myModal').data('bs.modal').isShown = false;
// Send an HTTP GET request to the server - replace this with getJSON, post or ajax as needed
$.get( "ajax/test.html", function( data ) {
// enable closing the modal
$('#myModal').data('bs.modal').isShown = true;
// Do something with the data
$( ".result" ).html( data );
});
その機能が欠けているのはあなただけではありません。 bootstrapは時々「ミニマル」すぎると思います。背後の人々は「実装層」で多くのことを行うべきだと考えていますが、bootstrap jQueryプラグイン自体はそれを不可能にします!
次のように、自分で機能を実装する必要があります:
bootstrap.js
v2.1.1モーダルは61行目から始まります。
Modal.prototype
、2つの関数lock
とunlock
を追加すると、次のようになります(ここでは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
}
これで、bootstrapモーダルにオンザフライのロック/ロック解除機能があり、ユーザーが重要な瞬間にモーダルを閉じることができなくなりました。
例:
これは http://Twitter.github.com/bootstrap/javascript.html#modals からの「ライブデモ」の変更バージョンです。
<!-- 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…</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');
}
});
AJAXをtrueに呼び出しているときに設定できる変数isBlockedを作成できます。その後、ブートストラップモーダル非表示イベントで次のように確認できます。
$('#myModal').on('hide.bs.modal', function (e) {
//Prevent modal from closing is isBlocked is true
if(isBlocked) return e.preventDefault();
})
この方法はBootsrapを拡張するよりも簡単だと思います。誰かを助けることを願っています:D
これに関するあなたの仕事を@davidkonradに感謝します。私もこれを実装しようとしていましたが、bootstrap 3で変更されているようです。
__superModal.defaults
_
これはコンストラクタにアタッチされているので、
__superModal.Constructor.DEFAULTS
_
また、コンストラクターが変更されたため、コピーして変更する必要があり、理想的ではありませんでした。代わりに、機能し、コンストラクターをコピーしない以下のコードを考え出しました。bootstrap変更が今後行われる場合、より確実になります。試してみてください。
_// 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');
わーい!
Bootstrap 4&3で動作するようにこの素晴らしいスクリプトを更新しました。プロジェクトで使用しているグローバルスクリプトがあり、それらの一部が両方を使用しているため、両方のシナリオを維持していますBoostrapのバージョン(心配しないでください、プロジェクトごとに1つbootstrap)。より良いアイデアがある場合は、私たちと共有してください。
// save the original function object
var _superModal = $.fn.modal;
// Bootstrap 3: Constructor.DEFAULTS
// Bootstrap 4: Constructor.Default
var _superModalDefault = (typeof _superModal.Constructor.DEFAULTS === 'undefined') ? _superModal.Constructor.Default : _superModal.Constructor.DEFAULTS;
// add locked as a new option
$.extend(_superModalDefault, {
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
// Bootstrap 3: this.options
// Bootstrap 4: this._config
lock: function() {
// console.log('lock called');
if (this.options)
this.options.locked = true; // Bootstrap 3
else
this._config.locked = true; // Bootstrap 4
}
// 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');
if (this.options)
this.options.locked = false; // Bootstrap 3
else
this._config.locked = false; // Bootstrap 4
}
// 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)
if (this.options.locked) return; // Bootstrap 3
else
if (this._config.locked) return; // Bootstrap 4
_hide.apply(this, arguments);
}
});