Twitter Bootstrap-Warnmeldung schließen und wieder öffnen

102

Ich habe ein Problem mit Warnmeldungen. Es wird normal angezeigt, und ich kann es schließen, wenn der Benutzer drückt x(schließen), aber wenn der Benutzer versucht, es erneut anzuzeigen (z. B. auf das Schaltflächenereignis klicken), wird es nicht angezeigt. (Wenn ich diese Warnmeldung an die Konsole drucke, ist sie außerdem gleich [].) Mein Code ist hier:

 <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>

Und Veranstaltung:

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

PS! Ich muss eine Warnmeldung erst anzeigen, nachdem ein Ereignis aufgetreten ist (z. B. durch Klicken auf die Schaltfläche). Oder was mache ich falsch?

ben3000
quelle

Antworten:

180

Durch Datenentlassung wird das Element vollständig entfernt. Verwenden Sie stattdessen die .hide () -Methode von jQuery.

Die Fix-It-Quick-Methode:

Verwenden Sie Inline-Javascript, um das Element beim Klicken wie folgt auszublenden:

<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/

Dies sollte jedoch nur verwendet werden, wenn Sie faul sind (was nicht gut ist, wenn Sie eine wartbare App wünschen).

Die Do-it-Right-Methode:

Erstellen Sie ein neues Datenattribut zum Ausblenden eines Elements.

Javascript:

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

und ändern Sie dann im Markup die Option "Daten entlassen" in "Daten ausblenden". Beispiel bei jsfiddle .

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

Dadurch werden alle Elemente mit der in data-hide angegebenen Klasse ausgeblendet, dh: data-hide="alert"Alle Elemente mit der Alert-Klasse werden ausgeblendet.

Xeon06 bot eine alternative Lösung:

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

Dadurch wird nur das nächstgelegene übergeordnete Element ausgeblendet. Dies ist sehr nützlich, wenn Sie nicht jeder Warnung eine eindeutige Klasse zuweisen möchten. Bitte beachten Sie jedoch, dass Sie die Schaltfläche zum Schließen in der Warnung platzieren müssen.

Definition von .closest from jquery doc :

Rufen Sie für jedes Element in der Menge das erste Element ab, das dem Selektor entspricht, indem Sie das Element selbst testen und seine Vorfahren im DOM-Baum durchlaufen.

Henrik Karlsson
quelle
4
Hallo! In Bezug auf Ihre Antwort richtig machen. Dadurch wird JEDES Element ausgeblendet, das dieselbe Klasse (dh alert) auf der Seite hat. Eine Lösung hierfür wäre, den Inhalt des Rückrufs durch diese Zeile zu ersetzen $(this).closest("." + $(this).attr("data-hide")).hide();, die nur das nächstgelegene übergeordnete Element betrifft, da die Schaltfläche zum Schließen normalerweise in der betroffenen Warnung platziert ist.
Alex Turpin
1
Das stimmt, ich habe nicht daran gedacht, dass es so funktioniert. Dies wird jedoch die Einfachheit dieser Lösung in geringem Maße beseitigen. Ich werde es als Kommentar zum vorhandenen Code hinzufügen. Vielen Dank!
Henrik Karlsson
1
Neu in diesem .. wo würden Sie die '$ (function () {..'
S Rosam
1
Überall in einer JavaScript-Datei oder in einem <script> -Code hier </ script> -Tag.
Henrik Karlsson
1
Wenn Sie $ (document) .on ('click', '[data-hide]', function () {/ * * /}) verwenden würden, wäre Ihre Antwort perfekt;)
schock_gone_wild
26

Ich habe gerade eine Modellvariable verwendet, um den Dialog ein- / auszublenden, und die entfernt data-dismiss="alert"

Beispiel:

<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>

arbeitet für mich und stoppt die Notwendigkeit, zur Abfrage zu gehen

user1661621
quelle
1
Eine viel einfachere / bessere Lösung als die hoch bewertete akzeptierte Antwort!
Abs
Viel bessere Lösung meiner Meinung nach
Devqon
Ich mag Ihre Idee
Kumaresan Perumal
15

Ich denke, ein guter Ansatz für dieses Problem wäre, den close.bs.alertEreignistyp von Bootstrap zu nutzen, um die Warnung auszublenden, anstatt sie zu entfernen. Der Grund, warum Bootstrap diesen Ereignistyp verfügbar macht, besteht darin, dass Sie das Standardverhalten beim Entfernen der Warnung aus dem DOM überschreiben können.

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

Wenn Sie eine MVVM-Bibliothek wie knockout.js verwenden (was ich sehr empfehle), können Sie dies sauberer tun:

<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/

Ohad Schneider
quelle
data-bind="click:function(){showAlert(false);}ist ein perfektes Beispiel für aufdringliches Javascript, das alles andere als sauber ist . Ich empfehle dringend , diesem Ansatz NICHT zu folgen
Leo
@ Leo aufdringlich in welcher Weise?
Ohad Schneider
In jeder Hinsicht aufdringlich. Sie "binden" das Verhalten aktiv in Ihre HTML-Struktur / Markup ein. Stellen Sie sich vor, Sie müssten dieses Verhalten ändern ... wie viele Seiten und HTML-Elemente müssen Sie ändern? Versteh mich nicht falsch, es beantwortet immer noch die gestellte Frage und deshalb werde ich es nicht ablehnen. Dies ist jedoch
Leo
Nein, was ich eigentlich sage, ist die Trennung von Bedenken . Ihre Ansichten (HTML) sollten niemals Javascript enthalten, die negativen Auswirkungen könnten in einem Entwicklerteam enorm sein. Hier ist eine großartige Frage (und Antwort) zu Knockout und dem etwas kontroversen data-bindAttribut stackoverflow.com/questions/13451414/unobtrusive-knockout
Leo
Was halten Sie von "JavaScript"? Was ist, wenn es nur den Namen der aufzurufenden Methode enthält? Ist es die Tatsache, dass es mit einem Parameter (false) aufgerufen wird, der es in Ihren Augen aufdringlich macht?
Ohad Schneider
2

Wenn Sie also eine Lösung suchen, die mit dynamischen HTML-Seiten umgehen kann, wie Sie sie bereits enthalten, sollten Sie jQuery's Live verwenden, um den Handler für alle Elemente festzulegen, die sich jetzt und in Zukunft im Dom befinden oder entfernt werden.

ich benutze

$(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
quelle
2

Das hat bei mir am besten funktioniert:

$('.alert').on('close.bs.alert', function (e) {
    e.preventDefault();
    $(this).hide();
});
Harshal Lonare
quelle
1

Ich bin auch auf dieses Problem gestoßen, und das Problem beim einfachen Hacken der Schaltfläche zum Schließen besteht darin, dass ich weiterhin Zugriff auf die Standardereignisse zum Schließen von Bootstrap-Warnungen benötige.

Meine Lösung bestand darin, ein kleines, anpassbares JQuery-Plugin zu schreiben einen ordnungsgemäß gestalteten Bootstrap 3-Alarm (mit oder ohne Schließen-Taste nach Bedarf) einfügt und es Ihnen ermöglicht, ihn nach dem Schließen der Box einfach neu zu generieren.

Verwendung, Tests und Beispiele finden Sie unter https://github.com/davesag/jquery-bs3Alert .

Dave Sag
quelle
1

Ich stimme der Antwort von Henrik Karlsson zu, die von Martin Prikryl bearbeitet wurde. Ich habe einen Vorschlag, der auf der Zugänglichkeit basiert. Ich würde .attr ("aria-hidden", "true") am Ende hinzufügen, so dass es so aussieht:

$(this).closest("." + $(this).attr("data-hide")).attr("aria-hidden", "true");
cfnerd
quelle
2
Wird das wirklich gebraucht? jQuerys .hide-Funktionssätze werden angezeigt: keine, sollten Bildschirmleser nicht intelligent genug sein, um sie sowieso als versteckt zu erkennen?
Henrik Karlsson
1

Alle oben genannten Lösungen verwenden externe Bibliotheken, entweder Angular oder jQuery, und eine alte Version von Bootstrap. Hier ist also die Lösung von Charles Wyke-Smith in reinem JavaScript , die auf Bootstrap 4 angewendet wird . Ja, Bootstrap benötigt jQuery für seinen eigenen Modal- und Warncode, aber nicht mehr jeder schreibt seinen eigenen Code mit jQuery.

Hier ist das HTML der Warnung:

<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>

Beachten Sie, dass die Warnung zunächst ausgeblendet ist ( style="display: none;") und anstelle des Standards data-dismiss="alert"hier verwendet wurdedata-hide="alert" .

Hier ist das JavaScript, um die Warnung anzuzeigen und die Schaltfläche zum Schließen zu überschreiben:

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';
});

Wenn Sie die Warnung an anderer Stelle im Code programmgesteuert ausblenden oder anzeigen möchten, tun Sie einfach myAlert.style.display = 'none';oder myAlert.style.display = 'block';.

Jaifroid
quelle
0

Das Problem wird durch die Verwendung von verursacht style="display:none". Sie sollten die Warnung mit Javascript ausblenden oder zumindest beim Anzeigen das Stilattribut entfernen.

Plamen Nikolov
quelle
2
Nicht wirklich, das Problem ist, dass Data-Dism das Element entfernt
Henrik Karlsson
0

Basierend auf den anderen Antworten und dem Ändern der Datenentlassung in Datenverstecken behandelt dieses Beispiel das Öffnen der Warnung über einen Link und ermöglicht das wiederholte Öffnen und Schließen der Warnung

$('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 */
   });
});
Charles Wyke-Smith
quelle
0

Ich habe alle Methoden ausprobiert und der beste Weg für mich ist die Verwendung der integrierten Bootstrap-Klassen .fadeund.in

Beispiel:

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

Hinweis: Fügen Sie in jQuery addClass ('in') hinzu, um die Warnung anzuzeigen, und removeClass ('in'), um sie auszublenden.

Lustige Tatsache: Dies funktioniert für alle Elemente. Nicht nur Warnungen.

klodal
quelle
0

Hier ist eine Lösung, die auf der Antwort von Henrik Karlsson basiert, aber eine ordnungsgemäße Ereignisauslösung aufweist (basierend auf Bootstrap-Quellen ):

$(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'))
    })
});

Die Antwort vor allem für mich als Notiz.

maxkoryukov
quelle
0

Kann dies nicht einfach durch Hinzufügen eines zusätzlichen "Container" -Divs und Hinzufügen des entfernten Alarm-Divs jedes Mal erfolgen. Scheint für mich zu arbeiten?

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
quelle