Предупреждающее сообщение Twitter Bootstrap закрыть и снова открыть


103

У меня проблема с предупреждающими сообщениями. Он отображается нормально, и я могу закрыть его, когда пользователь нажимает x(закрыть), но когда пользователь пытается отобразить его снова (например, щелкнуть событие кнопки), он не отображается. (Более того, если я выведу это предупреждающее сообщение на консоль, оно будет равно [].) Мой код здесь:

 <div class="alert" style="display: none">
   <a class="close" data-dismiss="alert">×</a>
   <strong>Warning!</strong> Best check yo self, you're not looking too good.
 </div>

И событие:

 $(".alert").show();

PS! Мне нужно показать предупреждающее сообщение только после того, как произошло какое-то событие (например, нажата кнопка). Или что делаю не так?

Ответы:


180

Data-dismiss полностью удаляет элемент. Вместо этого используйте метод jQuery .hide ().

Метод быстрого исправления:

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

<div class="alert" style="display: none"> 
    <a class="close" onclick="$('.alert').hide()">×</a>  
    <strong>Warning!</strong> Best check yo self, you're not looking too good.  
</div>

<a href="#" onclick="$('alert').show()">show</a>

http://jsfiddle.net/cQNFL/

Однако это следует использовать только в том случае, если вы ленивы (что не очень хорошо, если вам нужно поддерживаемое приложение).

Правильный метод:

Создайте новый атрибут данных для скрытия элемента.

Javascript:

$(function(){
    $("[data-hide]").on("click", function(){
        $("." + $(this).attr("data-hide")).hide()
        // -or-, see below
        // $(this).closest("." + $(this).attr("data-hide")).hide()
    })
})

а затем измените data-dismiss на data-hide в разметке. Пример на jsfiddle .

$("." + $(this).attr("data-hide")).hide()

Это скроет все элементы с классом, указанным в data-hide, то есть: data-hide="alert" скроет все элементы с классом предупреждения.

Xeon06 предоставил альтернативное решение:

$(this).closest("." + $(this).attr("data-hide")).hide()

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

Определение .closest из jquery doc :

Для каждого элемента в наборе получите первый элемент, соответствующий селектору, путем тестирования самого элемента и обхода его предков в дереве DOM.


4
Привет! По поводу вашего правильного ответа. Это скроет КАЖДЫЙ элемент, имеющий один и тот же класс (т. Е. alert) На странице. Решением для этого было бы заменить содержимое обратного вызова этой строкой $(this).closest("." + $(this).attr("data-hide")).hide();, которая повлияет только на ближайший родительский элемент, поскольку кнопка отклонения обычно помещается в оповещение, на которое она влияет.
Alex Turpin

1
Это правда, я не думал, что это так. Это, однако, в некоторой степени снизит простоту этого решения. Я добавлю это как комментарий к существующему коду. Спасибо!
Хенрик Карлссон

1
Новичок в этом .. где бы вы определили '$ (function () {..'
S Розам

1
Где угодно в файле JavaScript или в теге <script> здесь </script>.
Хенрик Карлссон,

1
Если бы вы использовали $ (document) .on ('click', '[data-hide]', function () {/ * * /}), ваш ответ был бы идеальным;)
shock_gone_wild

26

Я просто использовал переменную модели, чтобы показать / скрыть диалог, и удалил data-dismiss="alert"

Пример:

<div data-ng-show="vm.result == 'error'" class="alert alert-danger alert-dismissable">
    <button type="button" class="close" data-ng-click="vm.result = null" aria-hidden="true">&times;</button>
    <strong>Error  !  </strong>{{vm.exception}}
</div>

работает для меня и избавляет от необходимости выходить на jquery


1
Гораздо более простое / лучшее решение, чем принятый ответ, получивший высокую оценку!
Abs

На мой взгляд, гораздо лучшее решение
devqon


15

Я думаю, что хорошим подходом к этой проблеме было бы использование типа close.bs.alertсобытия Bootstrap, чтобы скрыть предупреждение вместо его удаления. Причина, по которой Bootstrap предоставляет этот тип события, заключается в том, что вы можете перезаписать поведение по умолчанию при удалении предупреждения из DOM.

$('.alert').on('close.bs.alert', function (e) {
    e.preventDefault();
    $(this).addClass('hidden');
});

5

Если вы используете библиотеку MVVM, такую ​​как knockout.js (что я настоятельно рекомендую), вы можете сделать это более аккуратно:

<div class="alert alert-info alert-dismissible" data-bind="visible:showAlert">
   <button type="button" class="close" data-bind="click:function(){showAlert(false);}>
        <span aria-hidden="true">&times;</span>
        <span class="sr-only">Close</span>
   </button>
   Warning! Better check yourself, you're not looking too good.
</div>

http://jsfiddle.net/bce9gsav/5/


data-bind="click:function(){showAlert(false);}является прекрасным примером навязчивого javascript, который далеко не чище . Я настоятельно рекомендую НЕ следовать этому подходу
Лев

@Leo навязчивый каким образом?
Охад Шнайдер

Навязчиво во всех смыслах. Вы активно «встраиваете» поведение в свою структуру / разметку html. Представьте, что вам нужно изменить это поведение ... сколько страниц и элементов HTML вам нужно будет изменить? Не поймите меня неправильно, он по-прежнему отвечает на заданный вопрос, и поэтому я не буду его понижать. Но это далеко не «чистое» решение
Лев

Нет, на самом деле я говорю о разделении ответственности . Ваши представления (html) никогда не должны содержать javascript, отрицательные последствия могут быть огромными для команды разработчиков. Вот большой вопрос (и ответы) о Knockout и несколько противоречивом data-bindатрибут stackoverflow.com/questions/13451414/unobtrusive-knockout
Leo

Что вы считаете «JavaScript»? Что, если бы он содержал только имя вызываемого метода? Это то, что он вызывает его с параметром (false), что делает его навязчивым в ваших глазах?
Охад Шнайдер

2

Поэтому, если вам нужно решение, которое может справиться с динамическими html-страницами, поскольку вы уже включили его, вам следует использовать jQuery live, чтобы установить обработчик для всех элементов, которые сейчас и в будущем находятся в dom или будут удалены.

я использую

$(document).on("click", "[data-hide-closest]", function(e) {
  e.preventDefault();
  var $this = $(this);
  $this.closest($this.attr("data-hide-closest")).hide();
});
.alert-success {
    background-color: #dff0d8;
    border-color: #d6e9c6;
    color: #3c763d;
}
.alert {
    border: 1px solid transparent;
    border-radius: 4px;
    margin-bottom: 20px;
    padding: 15px;
}
.close {
    color: #000;
    float: right;
    font-size: 21px;
    font-weight: bold;
    line-height: 1;
    opacity: 0.2;
    text-shadow: 0 1px 0 #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="alert alert-success">
  <a class="close" data-hide-closest=".alert">×</a>
  <strong>Success!</strong> Your entries were saved.
</div>



1

Я тоже столкнулся с этой проблемой, и проблема с простым взломом кнопки закрытия заключается в том, что мне все еще нужен доступ к стандартным событиям закрытия при начальной загрузке.

Мое решение заключалось в том, чтобы написать небольшой настраиваемый плагин jquery. который вводит правильно сформированное предупреждение Bootstrap 3 (с кнопкой закрытия или без нее, если она вам нужна) с минимумом хлопот и позволяет легко регенерировать его после закрытия коробки.

См. Https://github.com/davesag/jquery-bs3Alert для использования, тестов и примеров.


1

Я согласен с ответом, опубликованным Хенриком Карлссоном и отредактированным Мартином Прикрылом. У меня есть одно предложение, основанное на доступности. Я бы добавил .attr ("aria-hidden", "true") в его конец, чтобы он выглядел так:

$(this).closest("." + $(this).attr("data-hide")).attr("aria-hidden", "true");

2
Это действительно нужно? Функция jQuerys .hide устанавливает display: none, разве программы чтения с экрана не должны быть достаточно умными, чтобы распознать его как скрытый?
Хенрик Карлссон

1

Все вышеперечисленные решения используют внешние библиотеки, angular или jQuery, а также старую версию Bootstrap. Итак, вот решение Чарльза Вайка-Смита на чистом JavaScript , примененное к Bootstrap 4 . Да, Bootstrap требует jQuery для своего модального кода и кода предупреждений, но не все больше пишут свой собственный код с помощью jQuery.

Вот HTML-код предупреждения:

<div id="myAlert" style="display: none;" 
    class="alert alert-success alert-dismissible fade show">
    <button type="button" class="close" data-hide="alert">&times;</button>
    <strong>Success!</strong> You did it!
</div>

Обратите внимание, что изначально предупреждение скрыто ( style="display: none;"), и вместо стандартного data-dismiss="alert", которое мы здесь использовали data-hide="alert".

Вот код JavaScript для отображения предупреждения и отмены кнопки закрытия:

var myAlert = document.getElementById('myAlert');
// Show the alert box
myAlert.style.display = 'block';
// Override Bootstrap's standard close action
myAlert.querySelector('button[data-hide]').addEventListener('click', function() {
    myAlert.style.display = 'none';
});

Если вы хотите программно скрыть или отобразить предупреждение в другом месте кода, просто выполните myAlert.style.display = 'none';или myAlert.style.display = 'block';.


0

Проблема вызвана использованием style="display:none", вы должны скрыть предупреждение с помощью Javascript или, по крайней мере, при его отображении удалить атрибут стиля.


2
Не совсем, проблема в удалении элемента Data-dismiss
Хенрик Карлссон

0

Основываясь на других ответах и ​​изменении data-dismiss на data-hide, этот пример обрабатывает открытие предупреждения по ссылке и позволяет многократно открывать и закрывать предупреждение.

$('a.show_alert').click(function() {
    var $theAlert = $('.my_alert'); /* class on the alert */
    $theAlert.css('display','block');
   // set up the close event when the alert opens
   $theAlert.find('a[data-hide]').click(function() {
     $(this).parent().hide(); /* hide the alert */
   });
});

0

Я перепробовал все методы, и лучший способ для меня - использовать встроенные классы начальной загрузки .fadeи.in

Пример:

<div class="alert alert-danger fade <?php echo ($show) ? 'in' : '' ?>" role="alert">...</div>

Примечание. В jQuery addClass ('in') для отображения предупреждения и removeClass ('in') для его скрытия.

Интересный факт: это работает для всех элементов. Не только предупреждения.


0

Вот это решение , основанное на ответ по Хенрик Карлссон , но при надлежащем случае срабатывания ( на основе источников Bootstrap ):

$(function(){
    $('[data-hide]').on('click', function ___alert_hide(e) {
        var $this = $(this)
        var selector = $this.attr('data-target')
        if (!selector) {
            selector = $this.attr('href')
            selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
        }

        var $parent = $(selector === '#' ? [] : selector)

        if (!$parent.length) {
            $parent = $this.closest('.alert')
        }

        $parent.trigger(e = $.Event('close.bs.alert'))

        if (e.isDefaultPrevented()) return

        $parent.hide()

        $parent.trigger($.Event('closed.bs.alert'))
    })
});

Ответ в основном для меня, в виде примечания.


0

Разве это невозможно сделать, просто добавляя дополнительный div "контейнер" и каждый раз добавляя в него удаленный div предупреждения. Кажется, у меня работает?

HTML

<div id="alert_container"></div>

JS

 $("#alert_container").html('<div id="alert"></div>');          
 $("#alert").addClass("alert alert-info  alert-dismissible");
 $("#alert").html('<a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a><strong>Info!</strong>message');
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.