Kiểm tra xem lớp đã được chỉ định chưa trước khi thêm


113

Trong jQuery, bạn nên kiểm tra xem một lớp đã được gán cho một phần tử trước khi thêm lớp đó chưa? Nó thậm chí sẽ có bất kỳ tác dụng nào?

Ví dụ:

<label class='foo'>bar</label>

Khi nghi ngờ nếu lớp bazđã được chỉ định label, đây có phải là cách tốt nhất:

var class = 'baz';
if (!$('label').hasClass(class)) {
  $('label').addClass(class);
}

hoặc điều này là đủ:

$('label').addClass('baz');

12
Tôi .hasClasschỉ sử dụng khi tôi cần kiểm tra xem lớp có tồn tại hay không, nếu tôi chỉ cần gán lớp - tôi sử dụng .addClass. jQuery không lặp lại trong các lớp học
Samich

7
Chỉ cần thêm lớp mà không cần thử nghiệm. Nếu nó đã tồn tại, nó sẽ không được thêm lại.
Blazemonger

Câu trả lời:


177

Chỉ cần gọi addClass(). jQuery sẽ kiểm tra cho bạn. Nếu bạn tự kiểm tra, bạn đang tăng gấp đôi công việc, vì jQuery sẽ vẫn chạy kiểm tra cho bạn.


47

Một kiểm tra đơn giản trong bảng điều khiển sẽ cho bạn biết rằng việc gọi addClassnhiều lần với cùng một lớp là an toàn.

Cụ thể, bạn có thể tìm kiểm tra trong nguồn

if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
  setClass += classNames[ c ] + " ";
}

2
Hãy đọc lại câu hỏi của tôi và bạn sẽ nhận thấy rằng nó không phải là về beeing an toàn nhưng về thực hành tốt nhất
Muleskinner

7
Từ câu trả lời đã chỉnh sửa của bạn tôi thấy rằng jQuery thực sự kiểm tra xem lớp allready được gán trước khi thêm nó, tức là nó sẽ là xấu thực hành để làm việc kiểm tra bản thân / nhờ
Muleskinner

5
@Muleskinner đó là những gì tôi đang ám chỉ.
Raynos

41
@Raynos: Một kiểm tra đơn giản trong bảng điều khiển sẽ cho bạn biết rằng việc gọi addClass nhiều lần với cùng một lớp là an toàn. Tuy nhiên, câu hỏi này là một trong những câu hỏi phổ biến nhất khi tôi tìm kiếm câu trả lời trên Google ... Ngay cả những thứ nhỏ nhặt được ghi chép rõ ràng ở những nơi khác cũng có một vị trí trên Stack Overflow.
eirirlar

10
Có quá nhiều thái độ trong câu trả lời này. Có thể đã trả lời nó với một số khéo léo.
dreadwail

4

Câu hỏi này khiến tôi chú ý theo sau một câu hỏi khác được đánh dấu là trùng lặp với câu hỏi này .

Câu trả lời này tóm tắt câu trả lời được chấp nhận với một chút chi tiết bổ sung.

Bạn đang cố gắng tối ưu hóa bằng cách tránh kiểm tra không cần thiết, về mặt này, đây là các yếu tố bạn phải biết:

  1. không thể có tên lớp trùng lặp trong thuộc tính lớp bằng cách thao tác phần tử DOM thông qua JavaScript. Nếu bạn có class="collapse"trong HTML của mình, việc gọi Element.classList.add("collapse");sẽ không thêm phần thu gọn bổ sung lớp thu . Tôi không biết việc triển khai cơ bản, nhưng tôi cho rằng nó phải đủ tốt.
  2. JQuery thực hiện một số kiểm tra cần thiết trong quá trình triển khai addClassvà của nó removeClass(tôi đã kiểm tra mã nguồn ). Đối với addClass, sau khi thực hiện một số kiểm tra và nếu một lớp tồn tại, JQuery không cố gắng thêm lại nó. Tương tự như vậy removeClass, JQuery thực hiện điều gì đó dọc theo dòng cur.replace( " " + clazz + " ", " " );sẽ loại bỏ một lớp chỉ khi nó tồn tại.

Đáng chú ý, JQuery thực hiện một số tối ưu hóa trong quá trình removeClasstriển khai của nó để tránh kết xuất vô nghĩa. Nó diễn ra như thế này

...
// only assign if different to avoid unneeded rendering.
finalValue = value ? jQuery.trim( cur ) : "";
if ( elem.className !== finalValue ) {
    elem.className = finalValue;
}
...

Vì vậy, tối ưu hóa vi mô tốt nhất mà bạn có thể làm là với mục đích tránh chi phí gọi hàm và các kiểm tra triển khai liên quan.

Giả sử bạn muốn chuyển đổi một lớp có tên collapse, nếu bạn hoàn toàn kiểm soát thời điểm lớp đó được thêm vào hoặc bị xóa và nếu collapselớp ban đầu vắng mặt, thì bạn có thể tối ưu hóa như sau:

$(document).on("scroll", (function () {
    // hold state with this field
    var collapsed = false;

    return function () {
        var scrollTop, shouldCollapse;

        scrollTop = $(this).scrollTop();
        shouldCollapse = scrollTop > 50;

        if (shouldCollapse && !collapsed) {
            $("nav .branding").addClass("collapse");
            collapsed = true;

            return;
        }

        if (!shouldCollapse && collapsed) {
            $("nav .branding").removeClass("collapse");
            collapsed = false;
        }
    };
})());

Ngoài ra, nếu bạn đang chuyển đổi một lớp do những thay đổi về vị trí cuộn, bạn rất nên tiết chế việc xử lý sự kiện cuộn.


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.