Подтвердить что ты не робот

Модальный фон загрузочного лотка

Я показываю модальное окно Bootstrap для загрузки при выполнении вызовов AJAX. Я транслировал событие "progress.init", когда мода загрузки должна отображаться, и "progress.finish", когда я хочу, чтобы модальная скрыть. Существуют определенные условия, при которых модальность скрывается очень быстро после показа, что приводит к тому, что модальный фон остается на экране. Последующие вызовы сокрытия элемента не удаляют фон. Я также не могу просто удалить все фоны, поскольку в окне загрузки могут отображаться другие модальные окна. Я собрал jsfiddle, демонстрируя проблему с просто вызовом модальной функции (вместо запуска событий).

var loadingModal = $("#loadingModal");

$("#btnShow").click(function () {
   loadingModal.modal("show");
    //hide after 3 seconds
    setTimeout(function () {
        loadingModal.modal("hide");
    }, 3000);
});

$("#btnProblem").click(function () {
   //simulate a loading screen finishing fast, followed by another loading screen
    loadingModal.modal("show");
    loadingModal.modal("hide");
    loadingModal.modal("show");

    //Again simulate 3 seconds
    setTimeout(function () {
        loadingModal.modal("hide");
    }, 3000);
});

И HTML:

<div id="loadingModal" class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-body">
        <p>Loading...</p>
      </div>
    </div>
  </div>
</div>
<button id="btnShow">Show Loading</button>
<button id="btnProblem">Cause show/hide problem</button>

В идеале я хотел бы разрешить это, не дожидаясь указанного времени до вызова модального ( "скрыть" ). Другими словами, я хочу попытаться избежать чего-то вроде:

elem.on("progress.finish", function () {
    window.setTimeout(loadingModal.modal("hide");
}, 750);

Я также попытался подписаться на события hidden.bs.modal и показанные .bs.modal из бутстрапа, чтобы попытаться показать/скрыть элемент, если это необходимо, но может быть, это происходит неправильно... Любые идеи чтобы этот модал отображался/скрывался?

4b9b3361

Ответ 1

На всякий случай кто-то сталкивается с подобной проблемой: я обнаружил, что исключение класса из модального класса не позволит этому фону приклеиться к экрану даже после того, как модаль скрыт. Кажется, это ошибка в bootstrap.js для модалов.

Другим (при сохранении эффектов затухания) было бы заменить вызов jQueryElement.modal собственным пользовательским javascript, который добавляет класс "in", устанавливает отображение: блок и добавляет задний фон при показе, затем выполняет противоположные операции, когда вы хотите скрыть модальный.

Простое удаление затухания было достаточным для моего проекта.

Ответ 2

Если после модального скрытия остался затухающий фон, вы не можете щелкнуть по нему, где вы можете принудительно удалить их, используя ниже фрагмент кода.

сначала скройте свой модальный элемент div.

$('modalId').modal('hide');

во-вторых, удалите класс "модально-открытый" из тела и ".modal-backdrop" в конце страницы.

$('body').removeClass('modal-open');
$('.modal-backdrop').remove();

Ответ 3

На всякий случай кто-то другой сталкивается с подобной проблемой: я сохранил затухание, но добавил кнопку data-dismiss="modal" к кнопке сохранения. Работает для меня.

Ответ 4

Проблема заключается в том, что bootstrap асинхронно удаляет фоновый рисунок. Поэтому, когда вы вызываете hide и show быстро друг за другом, фон не удаляется.

Решение (как вы уже упоминали) - дождаться полного скрытия модальности, используя событие 'hidden.bs.modal'. Используйте jQuery one, чтобы выполнить обратный вызов один раз. Я отклонил ваш jsfiddle, чтобы показать, как это будет работать.

// wait for the backdrop to be removed nicely.
loadingModal.one('hidden.bs.modal', function()
{
    loadingModal.modal("show");

    //Again simulate 3 seconds
    setTimeout(function () {
        loadingModal.modal("hide");
    }, 3000);
});
// hide for the first time, after binding to the hidden event.
loadingModal.modal("hide");

Просматривая код в Bootstrap:

Это то, что скрывает модальное асинхронное:

$.support.transition && this.$element.hasClass('fade') ?
    this.$element
        .one('bsTransitionEnd', $.proxy(this.hideModal, this))
        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
    this.hideModal()

Это проверяет, поддерживаются ли переходы, а класс fade включен в модальный. Когда оба параметра true, он ожидает завершения эффекта затухания, прежде чем скрывать модальность. Это ожидание происходит снова перед удалением фона.

Вот почему удаление класса fade будет скрывать модальную синхронность (больше не ждать завершения эффекта затухания CSS) и почему решение по reznic работает.

Эта проверка определяет, следует ли добавлять или удалять фон. isShown = true выполняется синхронно. Когда вы вызываете hide и show быстро друг после друга, isShown становится true, и проверка добавляет задний фон вместо того, чтобы удалять предыдущий, создавая проблему, с которой вы сталкиваетесь.

Ответ 5

Временное решение - полностью скрыть фон, если вам не нужен такой: Данные-фон = ""

<div class="modal fade preview-modal" data-backdrop="" id="preview-modal"  role="dialog" aria-labelledby="preview-modal" aria-hidden="true">

Ответ 6

Лучший и простой подход - использовать атрибут data-dismiss. По сути, атрибут data-dismiss отклонит модальное значение, и вы не увидите оставшийся фон.

Как использовать атрибут data-dismiss

Все, что вам нужно сделать, это добавить следующее в то место, где вы хотите закрыть свой модал:

data-dismiss="modal" 

Например, у меня есть кнопка, и когда кто-то нажимает кнопку, она закрывает модальное.

<button class="btn btn-info float-right" onclick="foo()" data-dismiss="modal">Save changes</button>

Вы также можете обработать функцию JavaScript на onClick и она закроет модальное окно, а также запустит функцию JavaScript.

Это лучший подход для использования атрибута data-dismiss.

Ответ 7

Это то, что сработало для меня -

Когда событие hidden.bs.modal запущено, функция jQuery .remove() может удалить элемент с классом .modal-backdrop. Поэтому каждый раз, когда модальная функция закрыта, модальный фон будет удален.

//setting callback function for 'hidden.bs.modal' event
$('#modal').on('hidden.bs.modal', function(){
  //remove the backdrop
  $('.modal-backdrop').remove();
})

Удачи.

Ответ 8

просто удалите класс "fade" из модального

Ответ 9

После проверки элемента div с классом modal-backdrop по-прежнему остается после нажатия кнопки "Назад" браузера, поэтому я просто удаляю его:

$(window).on('popstate', function() {
    $(".modal-backdrop").remove();
});

Ответ 10

Еще один возможный случай (мой) - вы динамически добавляете модальный html в DOM, и он содержит больше 1 root node. Gotcha здесь состоит в том, что узлы комментариев также учитываются, поэтому, если вы скопировали шаблон с сайта начальной загрузки - у вас есть они.

Ответ 11

Добавь это:
$ ( "модальный-фон.") скрыть().
к функции ng-click в контроллере, чтобы предотвратить появление фонового перехода.

Ответ 12

Используйте этот код, чтобы полностью удалить модальный:

 $('.modal').remove();
 $('.modal-backdrop').remove();
 $('body').removeClass( "modal-open" );

Ответ 13

Будьте аккуратны {Данные отклонить = "модальные" } как упоминалось во втором ответе. При работе с функцией Angulars ng-commit, использующей определенную диспетчером функцию, функция-увольнение будет выполняться первой, а функция, определяющая область действия контроллера, никогда не будет вызываться. Я трачу час, чтобы понять это.

Ответ 14

Проблема, с которой я столкнулся (может кому-то помочь), заключалась в том, что я просто использовал партиал для загрузки модала.

<li data-toggle="modal" data-target="#priceInfoModal">
<label>Listing Price</label>
<i class="fa fa-money"></i>
@Html.Partial("EditPartials/PriceInfo_Edit")
</li>

Я поместил частичный вызов в один и тот же элемент списка, поэтому data-target = "# priceInfoModal" и div id = "priceInfoModal" были в одном контейнере, из-за чего я не смог закрыть мой модальный

Ответ 15

Так что, если вы не хотите убирать замирание или возиться с объектами dom, все, что вам нужно сделать, - это дождаться окончания шоу:

$('#load-modal').on('shown.bs.modal', function () {
    console.log('Shown Modal Backdrop');
    $('#load-modal').addClass('shown');
});

function HideLoader() {
    var loadmodalhidetimer = setInterval(function () {
        if ($('#load-modal').is('.shown')) {                
            $('#load-modal').removeClass('shown').modal('hide');
            clearInterval(loadmodalhidetimer);
            console.log('HideLoader');
        }
        else { //this is just for show.
            console.log('Waiting to Hide');
        }
    }, 200);
}

IMO Bootstrap уже должен этим заниматься. Ну, может быть, еще немного, если есть вероятность, что вы могли бы вызвать hide, не сделав show, вы можете добавить немного в show.bs.modal, добавить класс 'показ' и убедиться, что таймер проверяет, что показ предназначен, прежде чем попасть в петлю. Убедитесь, что вы очистили "показ" в точке, которую он показал.

Ответ 16

У меня та же проблема, решение состоит в том, чтобы добавить свойство data-dismiss="modal" к кнопке, которую вы собираетесь нажать.

Ответ 18

Использование кода ниже непрерывно добавляет отступ 7px к элементу body каждый раз, когда вы открываете и закрываете модальное окно.

$('modalId').modal('hide');
$('body').removeClass('modal-open');
$('.modal-backdrop').remove();'

Для тех, кто все еще использует Bootstrap 3, есть обходной путь.

$('#modalid').modal('hide');
$('.modal-backdrop').hide();
document.body.style.paddingRight = '0'
document.getElementsByTagName("body")[0].style.overflowY = "auto";

Ответ 19

Просто создайте событие, которое называется ниже. В моем случае, используя Angular, просто поместите в NgOnInit.

let body = document.querySelector('.modal-open');
body.classList.remove('modal-open');
body.removeAttribute('style');
let divFromHell = document.querySelector('.modal-backdrop');
body.removeChild(divFromHell);

Ответ 20

После выполнения действия просто нажмите кнопку закрытия.

Пример

$('.close').click();