Попереджувальне повідомлення 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

Відхилення даних повністю видаляє елемент. Використовуйте натомість метод jQuery's .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()
    })
})

а потім змінити відхилення даних на приховання даних у розмітці. Приклад на jsfiddle .

$("." + $(this).attr("data-hide")).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();, що вплине лише на найближчий батьківський елемент, оскільки кнопка відхилення зазвичай розміщується в межах попередження, на яке вона впливає.
Алекс Турпін

1
Це правда, я не думав змусити це працювати так. Це, однак, дещо зменшить простоту цього рішення. Я додам його як коментар до існуючого коду. Дякую!
Генрік Карлссон

1
Нове в цьому .. де ви б визначили '$ (function () {..'
S Rosam

1
У будь-якому місці у файлі JavaScript або в тезі <script> тут </script>.
Генрік Карлссон

1
Якщо ви використовуєте $ (document) .on ('click', '[data-hidden]', 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
Набагато простіше / краще рішення, ніж прийнята відповідь, що була дуже голосовою!
Абс

Набагато краще рішення на мій погляд
devqon

мені подобається ваша ідея
Kumaresan Perumal

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, негативні наслідки можуть бути величезними для команди розробників. Ось чудове запитання (та відповіді) про нокаут та дещо суперечливий data-bindатрибут stackoverflow.com/questions/13451414/unobtrusive-knockout
Лев

Що ви вважаєте "JavaScript"? Що робити, якщо він містив лише ім'я методу для виклику? Чи той факт, що він називає його параметром (false), робить його нав'язливим у ваших очах?
Охад Шнайдер

2

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

я використовую

$(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 ("прихований арією", "справжній") до кінця, щоб він виглядав так:

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

2
Це справді потрібно? jQuerys .hide функція встановлює дисплей: жоден, чи не повинні читці екрану бути достатньо розумними, щоб все-таки розпізнати його як прихований?
Генрік Карлссон

1

Усі вищезазначені рішення використовують зовнішні бібліотеки, або кутові, або 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
Насправді проблема полягає у відхиленні даних при видаленні елемента
Генрік Карлссон

0

На основі інших відповідей та зміни даних відхилення даних на приховання даних цей приклад обробляє відкриття попередження від посилання та дозволяє повторне відкриття та закриття попередження

$('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 щоразу. Здається, працює для мене?

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.