Предупреждающее сообщение 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! Мне нужно показать предупреждающее сообщение только после того, как произошло какое-то событие (например, нажата кнопка). Или что делаю не так?

ben3000
источник

Ответы:

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

user1661621
источник
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>

Joschi
источник
2

Это сработало для меня лучше всего:

$('.alert').on('close.bs.alert', function (e) {
    e.preventDefault();
    $(this).hide();
});
Харшал Лонаре
источник
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");
cfnerd
источник
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');
Lightning_young
источник