Thông báo cảnh báo Twitter Bootstrap đóng và mở lại


103

Tôi gặp sự cố với tin nhắn cảnh báo. Nó được hiển thị bình thường và tôi có thể đóng nó khi người dùng nhấn x(đóng), nhưng khi người dùng cố gắng hiển thị lại (ví dụ: nhấp vào sự kiện nút) thì nó không được hiển thị. (Hơn nữa, nếu tôi in thông báo cảnh báo này ra bảng điều khiển, thì nó bằng [].) Mã của tôi ở đây:

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

Và sự kiện:

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

Tái bút! Tôi chỉ cần hiển thị thông báo cảnh báo sau khi một số sự kiện đã xảy ra (ví dụ: được nhấp vào nút). Hay tôi đang làm gì sai?

Câu trả lời:


180

Loại bỏ dữ liệu sẽ loại bỏ hoàn toàn phần tử. Sử dụng phương thức .hide () của jQuery để thay thế.

Phương pháp sửa chữa nhanh chóng:

Sử dụng javascript nội tuyến để ẩn phần tử onclick như sau:

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

Tuy nhiên, điều này chỉ nên được sử dụng nếu bạn lười biếng (điều này không tốt nếu bạn muốn một ứng dụng có thể bảo trì).

Phương pháp làm đúng:

Tạo một thuộc tính dữ liệu mới để ẩn một phần tử.

Javascript:

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

và sau đó thay đổi loại bỏ dữ liệu thành ẩn dữ liệu trong đánh dấu. Ví dụ tại jsfiddle .

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

Điều này sẽ ẩn tất cả các phần tử với lớp được chỉ định trong data-hide, nghĩa là: data-hide="alert"sẽ ẩn tất cả các phần tử với lớp alert.

Xeon06 đã cung cấp một giải pháp thay thế:

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

Điều này sẽ chỉ ẩn phần tử cha gần nhất. Điều này rất hữu ích nếu bạn không muốn cấp cho mỗi cảnh báo một lớp duy nhất. Xin lưu ý rằng, tuy nhiên, bạn cần đặt nút đóng trong cảnh báo.

Định nghĩa của .closest từ jquery doc :

Đối với mỗi phần tử trong tập hợp, hãy lấy phần tử đầu tiên phù hợp với bộ chọn bằng cách kiểm tra chính phần tử đó và duyệt qua tổ tiên của nó trong cây DOM.


4
Chào! Về câu trả lời đúng làm điều đó của bạn. Điều này sẽ ẩn MỌI phần tử có cùng lớp (tức là alert) trên trang. Giải pháp cho điều này là thay thế nội dung của lệnh gọi lại bằng dòng này $(this).closest("." + $(this).attr("data-hide")).hide();, dòng này sẽ chỉ ảnh hưởng đến phần tử mẹ gần nhất, vì nút loại bỏ thường được đặt trong cảnh báo mà nó ảnh hưởng.
Alex Turpin,

1
Đó là sự thật, tôi đã không nghĩ đến việc làm cho nó hoạt động theo cách đó. Tuy nhiên, điều đó sẽ loại bỏ tính đơn giản của giải pháp này ở một mức độ nhỏ. Tôi sẽ thêm nó dưới dạng nhận xét vào mã hiện có. Cảm ơn!
Henrik Karlsson

1
Mới đối với điều này .. bạn sẽ định nghĩa '$ (function () {..'
S Rosam

1
Bất kỳ đâu trong tệp JavaScript hoặc trong thẻ <script> tại đây </script>.
Henrik Karlsson

1
Nếu bạn muốn sử dụng $ (document) .Trên (nghe tiếng 'click', '[data-hide]', function () {/ * * /}) Câu trả lời của bạn sẽ trở nên hoàn hảo;)
shock_gone_wild

26

Tôi vừa sử dụng một biến mô hình để hiển thị / ẩn hộp thoại và loại bỏ data-dismiss="alert"

Thí dụ:

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

làm việc cho tôi và ngăn chặn nhu cầu ra ngoài jquery


1
Một giải pháp đơn giản / tốt hơn nhiều so với câu trả lời được chấp nhận được bình chọn cao!
Abs

Theo ý kiến ​​của tôi, giải pháp tốt hơn nhiều
devqon

tôi thích ý tưởng của bạn
Kumaresan Perumal

15

Tôi nghĩ rằng một cách tiếp cận tốt cho vấn đề này là tận dụng close.bs.alertloại sự kiện của Bootstrap để ẩn cảnh báo thay vì loại bỏ nó. Lý do tại sao Bootstrap để lộ loại sự kiện này là để bạn có thể ghi đè hành vi mặc định là xóa cảnh báo khỏi DOM.

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

5

Nếu bạn đang sử dụng thư viện MVVM chẳng hạn như knockout.js (mà tôi thực sự khuyên bạn nên làm), bạn có thể làm điều đó rõ ràng hơn:

<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);}là một ví dụ hoàn hảo về javascript gây khó chịu mà còn lâu mới sạch hơn . Tôi khuyên KHÔNG làm theo phương pháp này
Leo

@Leo đáng ghét theo cách nào?
Ohad Schneider,

Không phô trương theo mọi cách. Bạn đang tích cực "nhúng" hành vi vào cấu trúc / đánh dấu html của mình. Hãy tưởng tượng bạn phải thay đổi hành vi đó ... bạn sẽ phải thay đổi bao nhiêu trang và phần tử html? Đừng hiểu sai ý tôi, nó vẫn trả lời câu hỏi được hỏi và đó là lý do tại sao tôi sẽ không từ chối nó. Nhưng đây không phải là một giải pháp "sạch sẽ hơn"
Leo

Không, những gì tôi thực sự đang nói là sử dụng tách biệt các mối quan tâm . Chế độ xem của bạn (html) không bao giờ được chứa bất kỳ javascript nào, những tác động tiêu cực có thể rất lớn trong một nhóm phát triển. Đây là câu hỏi lớn (và câu trả lời) về Knockout và phần nào gây tranh cãi data-bindthuộc tính stackoverflow.com/questions/13451414/unobtrusive-knockout
Leo

Bạn coi "JavaScript" là gì? Điều gì sẽ xảy ra nếu nó chỉ chứa tên của phương thức cần gọi? Có phải thực tế là nó gọi nó với một tham số (sai) khiến nó trở nên khó chịu trong mắt bạn?
Ohad Schneider,

2

Vì vậy, nếu bạn muốn một giải pháp có thể đối phó với các trang html động, vì bạn đã bao gồm nó, bạn nên sử dụng jQuery's live để đặt trình xử lý trên tất cả các phần tử hiện tại và tương lai trong dom hoặc bị xóa.

tôi sử dụng

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


2

Điều này làm việc tốt nhất cho tôi:

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

1

Tôi cũng gặp phải vấn đề này và vấn đề chỉ đơn giản là hack nút đóng là tôi vẫn cần truy cập vào các sự kiện đóng cảnh báo bootstrap tiêu chuẩn.

Giải pháp của tôi là viết một plugin jquery nhỏ, có thể tùy chỉnh đưa vào một cảnh báo Bootstrap 3 được định dạng phù hợp (có hoặc không có nút đóng khi bạn cần) với ít phiền phức nhất và cho phép bạn dễ dàng tạo lại nó sau khi đóng hộp.

Xem https://github.com/davesag/jquery-bs3Alert để biết cách sử dụng, kiểm tra và ví dụ.


1

Tôi đồng ý với câu trả lời được đăng bởi Henrik Karlsson và được biên tập bởi Martin Prikryl. Tôi có một đề xuất, dựa trên khả năng tiếp cận. Tôi sẽ thêm .attr ("aria-hidden", "true") vào cuối nó, để nó trông giống như:

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

2
Điều đó có thực sự cần thiết? jQuerys .hide hàm thiết lập hiển thị: không, trình đọc màn hình không phải là đủ thông minh để nhận ra nó là ẩn dù sao?
Henrik Karlsson

1

Tất cả các giải pháp trên đều sử dụng thư viện bên ngoài, góc hoặc jQuery và phiên bản cũ của Bootstrap. Vì vậy, đây là giải pháp của Charles Wyke-Smith bằng JavaScript thuần túy , áp dụng cho Bootstrap 4 . Có, Bootstrap yêu cầu jQuery cho mã phương thức và cảnh báo của riêng nó, nhưng không phải ai cũng viết mã của riêng họ bằng jQuery nữa.

Đây là html của cảnh báo:

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

Lưu ý rằng ban đầu cảnh báo bị ẩn ( style="display: none;") và thay vì tiêu chuẩn data-dismiss="alert", chúng tôi đã sử dụng ở đây data-hide="alert".

Đây là JavaScript để hiển thị cảnh báo và ghi đè nút đóng:

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

Nếu bạn muốn ẩn hoặc hiển thị cảnh báo theo chương trình ở nơi khác trong mã, chỉ cần thực hiện myAlert.style.display = 'none';hoặc myAlert.style.display = 'block';.


0

Vấn đề là do sử dụng style="display:none", bạn nên ẩn cảnh báo bằng Javascript hoặc ít nhất khi hiển thị nó, loại bỏ thuộc tính style.


2
Không thực sự, vấn đề là dữ liệu bỏ loại bỏ các yếu tố
Henrik Karlsson

0

Dựa trên các câu trả lời khác và thay đổi loại bỏ dữ liệu thành ẩn dữ liệu, ví dụ này xử lý việc mở cảnh báo từ một liên kết và cho phép mở và đóng cảnh báo nhiều lần

$('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

Tôi đã thử tất cả các phương pháp và cách tốt nhất cho tôi là sử dụng các lớp bootstrap tích hợp sẵn .fade.in

Thí dụ:

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

Lưu ý: Trong jQuery, addClass ('in') để hiển thị cảnh báo, removeClass ('in') để ẩn nó.

Thực tế thú vị: Điều này hoạt động cho tất cả các yếu tố. Không chỉ là cảnh báo.


0

Đây là một giải pháp dựa trên câu trả lời của Henrik Karlsson nhưng có kích hoạt sự kiện thích hợp (dựa trên nguồn 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'))
    })
});

Câu trả lời chủ yếu dành cho tôi, như một lưu ý.


0

Điều này có thể không được thực hiện đơn giản bằng cách thêm một div "vùng chứa" bổ sung và thêm div cảnh báo đã xóa vào đó mỗi lần. Dường như làm việc cho tôi?

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');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.