JQuery .hasClass cho nhiều giá trị trong câu lệnh if


81

Tôi có một câu lệnh if đơn giản như sau:

if ($('html').hasClass('m320')) {

// do stuff 

}

Điều này hoạt động như mong đợi. Tuy nhiên, tôi muốn thêm nhiều lớp hơn vào thẻ if statementđể kiểm tra xem có lớp nào trong <html>thẻ không. Tôi cần nó vì vậy nó không phải là tất cả chúng mà chỉ là sự hiện diện của ít nhất một lớp nhưng có thể nhiều hơn.

Trường hợp sử dụng của tôi là tôi có các lớp học (ví dụ m320, m768) gia tăng đối với độ rộng khung nhìn khác nhau vì vậy tôi chỉ muốn thực hiện một số Jquery nếu đó là một chiều rộng cụ thể (lớp).

Đây là những gì tôi đã thử cho đến nay:

1.

if ($('html').hasClass('m320', 'm768')) {

// do stuff 

}

2.

if ($('html').hasClass('m320')) || ($('html').hasClass('m768')) {

 // do stuff 

}

3.

 if ($('html').hasClass(['m320', 'm768'])) {

 // do stuff 

    }

Không có cái nào trong số này dường như hoạt động. Không chắc tôi đang làm gì sai nhưng rất có thể là cú pháp hoặc cấu trúc của tôi.


1
Thay vì đoán cách hoạt động của API, bạn nên đọc tài liệu. api.jquery.com/hasclass Ngoài ra, bạn nên có / mở bảng điều khiển của nhà phát triển trong quá trình phát triển.
vách đá điên cuồng

Câu trả lời:


74

Bạn vừa có một số dấu ngoặc đơn lộn xộn trong lần thử thứ hai.

var $html = $("html");

if ($html.hasClass('m320') || $html.hasClass('m768')) {

  // do stuff 

}

6
Bạn thực sự nên cache $('html')vào một biến thay vì phải tra cứu nó nhiều lần.
epascarello

1
@epascarello Rất đúng, cập nhật câu trả lời cho hậu thế.
James Montagne

161

Bạn có thể sử dụng is()thay vì hasClass():

if ($('html').is('.m320, .m768')) { ... }

3
Vâng hasClass()có lẽ nhanh hơn nhưng is()thuận tiện hơn hầu hết thời gian
elclanrs

1
BTW đây chúng ta có thể thấy các tiêu chuẩn hiệu suất cho is()hasClass()
Jignesh Gohel

1
Vì vậy, nó chậm hơn rất nhiều, nhưng cũng siêu nhanh về tổng thể. Nếu chỉ có một vài mục được quét, có vẻ như không phải là vấn đề lớn đối với mã sạch hơn nhiều.
jerclarke

27

Để giải trí, tôi đã viết một phương thức bổ trợ jQuery sẽ kiểm tra bất kỳ một trong nhiều tên lớp:

$.fn.hasAnyClass = function() {
    for (var i = 0; i < arguments.length; i++) {
        if (this.hasClass(arguments[i])) {
            return true;
        }
    }
    return false;
}

Sau đó, trong ví dụ của bạn, bạn có thể sử dụng:

if ($('html').hasAnyClass('m320', 'm768')) {

// do stuff 

}

Bạn có thể chuyển bao nhiêu tên lớp tùy thích.


Đây là phiên bản nâng cao cũng cho phép bạn chuyển nhiều tên lớp được phân tách bằng dấu cách:

$.fn.hasAnyClass = function() {
    for (var i = 0; i < arguments.length; i++) {
        var classes = arguments[i].split(" ");
        for (var j = 0; j < classes.length; j++) {
            if (this.hasClass(classes[j])) {
                return true;
            }
        }
    }
    return false;
}

if ($('html').hasAnyClass('m320 m768')) {
    // do stuff 
}

Bản demo làm việc: http://jsfiddle.net/jfriend00/uvtSA/


Tuyệt vời, điều này hoạt động tốt ... trên nhiều trình duyệt! Đã thử nghiệm trên FF và IE.
crmpicco

Tôi đã thực hiện một sửa đổi nhỏ để làm cho nó tuân theo các quy ước jQuery cho .addClass và .removeClass (). ( stackoverflow.com/a/14887517/170456 )
CyberMonk

25

Đây có thể là một giải pháp khác:

if ($('html').attr('class').match(/m320|m768/)) {  
  // do stuff   
}  

theo jsperf.com, nó cũng khá nhanh.


Rất tốt, nhanh hơn nhiều!
Philip

9
Điều này cũng sẽ phù hợp với lớp 'ZZZm320WWW' và tương tự. Hãy thử ... khớp (/ \ b (m320 | m768) \ b /) trong đó \ b khớp với phần đầu và phần cuối của một từ.
Juan Lanus

chỉ để theo dõi (7 năm sau :)). Điều này hoạt động tốt nhưng nếu phần tử html bạn xác định không có bất kỳ lớp nào - nó sẽ gây ra lỗi "Không thể đọc thuộc tính" khớp "của không xác định". Nếu đúng như vậy, hãy kiểm tra xem phần tử thậm chí có thuộc tính 'class' hay không (hoặc kiểm tra để đảm bảo thuộc tính 'class' không rỗng).
Sanya

5

Đối với bất kỳ ai thắc mắc về một số khía cạnh hiệu suất khác nhau với tất cả các tùy chọn khác nhau này, tôi đã tạo một trường hợp jsperf ở đây: jsperf

Tóm lại, sử dụng element.hasClass('class')là nhanh nhất.

Đặt cược tốt nhất tiếp theo là sử dụng elem.hasClass('classA') || elem.hasClass('classB'). Một lưu ý về điều này: vấn đề đặt hàng! Nếu lớp 'classA' có nhiều khả năng được tìm thấy hơn, hãy liệt kê nó trước! Câu lệnh điều kiện HOẶC trả về ngay sau khi một trong số chúng được đáp ứng.

Hiệu suất tồi tệ nhất cho đến nay là sử dụng element.is('.class').

Cũng được liệt kê trong jsperf là chức năng của CyberMonkgiải pháp của Kolja .


Thật sự thú vị! Tôi không biết gì về jsperf. Cảm ơn vì đã minh họa tất cả các biến thể khác nhau.
Danny Englander

3

Đây là một biến thể nhỏ về câu trả lời do jfriend00 cung cấp:

$.fn.hasAnyClass = function() {
    var classes = arguments[0].split(" ");
    for (var i = 0; i < classes.length; i++) {
        if (this.hasClass(classes[i])) {
            return true;
        }
    }
    return false;
}

Cho phép sử dụng cùng một cú pháp như .addClass () và .removeClass (). ví dụ: .hasAnyClass('m320 m768') Cần chống đạn, tất nhiên, vì nó giả định ít nhất một đối số.


0
var classes = $('html')[0].className;

if (classes.indexOf('m320') != -1 || classes.indexOf('m768') != -1) {
    //do something
}

1
Nếu bạn định làm điều đó, tại sao lại phải sử dụng jquery để lấy phần tử?
James Montagne

Tôi sẽ không, nhưng ít nhất nó chỉ nhận được các lớp học một lần? Nó có vẻ rất buồn tẻ nếu không có một chút jQuery, vì vậy tôi đã thay thế getElementsByTagName bằng một số phép thuật jQ dành riêng cho bạn!
adeneo

0

Phương thức hasClass sẽ chấp nhận một mảng tên lớp làm đối số, bạn có thể làm như sau:

$(document).ready(function() {
function filterFilesList() {
    var rows = $('.file-row');
    var checked = $("#filterControls :checkbox:checked");

    if (checked.length) {
        var criteriaCollection = [];

        checked.each(function() {
            criteriaCollection.push($(this).val());
        });

        rows.each(function() {
            var row = $(this);
            var rowMatch = row.hasClass(criteriaCollection);

            if (rowMatch) {
                row.show();
            } else {
                row.hide(200);
            }
        });
    } else {
        rows.each(function() {
            $(this).show();
        });
    }
}

    $("#filterControls :checkbox").click(filterFilesList);
    filterFilesList();
});

0

Đây là trường hợp bạn cần có mặt cả hai lớp. Đối với một trong hai hoặc logic chỉ cần sử dụng ||

$('el').hasClass('first-class') || $('el').hasClass('second-class')

Hãy tối ưu hóa khi cần thiết


1
Cái này sai. Ví dụ đầu tiên bạn đưa ra hoạt động chỉ vì phương thức có đầu vào kém vệ sinh và nghĩ rằng toàn bộ chuỗi là một tên lớp. Nó không hoạt động nếu các lớp có thứ tự khác nhau, hoặc không nằm ngay cạnh nhau. Xem ví dụ: jsfiddle.net/0d57ekty
MightyPork

@MightyPork cảm ơn bạn đã kiểm tra. bạn nói đúng, nó chỉ nên được sử dụng cho mỗi lớp
qwerty_igor

-1

Thử đi:

if ($('html').hasClass('class1 class2')) {

// do stuff 

}

Chào mừng bạn đến với Stack Overflow! Vui lòng thêm một số giải thích về lý do tại sao mã này giúp OP. Điều này sẽ giúp cung cấp câu trả lời mà người xem trong tương lai có thể học hỏi. Xem Cách trả lời để biết thêm thông tin.
Heretic Monkey
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.