JQuery .hasClass für mehrere Werte in einer if-Anweisung


81

Ich habe eine einfache if-Aussage als solche:

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

// do stuff 

}

Dies funktioniert wie erwartet. Ich möchte jedoch weitere Klassen hinzufügen, um if statementzu überprüfen, ob eine der Klassen im <html>Tag vorhanden ist. Ich brauche es, damit es nicht alle sind, sondern nur die Anwesenheit von mindestens einer Klasse, aber es kann mehr sein.

Mein Anwendungsfall ist , dass ich Klassen (zB m320, m768) hinzugefügt für verschiedene Darstellungsbreiten so dass ich nur bestimmte JQuery ausgeführt werden soll , wenn es sich um eine bestimmte Breite (Klasse) ist.

Folgendes habe ich bisher versucht:

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 

    }

Keines davon scheint jedoch zu funktionieren. Ich bin mir nicht sicher, was ich falsch mache, aber höchstwahrscheinlich meine Syntax oder Struktur.


1
Anstatt zu erraten, wie eine API funktioniert, sollten Sie die Dokumente lesen. api.jquery.com/hasclass Außerdem sollte die Konsole Ihres Entwicklers während der Entwicklung griffbereit sein.
Klippen des Wahnsinns

Antworten:


74

Sie hatten gerade einige durcheinandergebrachte Klammern in Ihrem zweiten Versuch.

var $html = $("html");

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

  // do stuff 

}

6
Sie sollten wirklich $('html')eine Variable zwischenspeichern, anstatt sie mehrmals nachschlagen zu müssen.
Epascarello

1
@epascarello Sehr wahr, die Antwort für die Nachwelt zu aktualisieren.
James Montagne

161

Sie könnten is()anstelle von verwenden hasClass():

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

3
Ja, hasClass()ist wahrscheinlich schneller, aber die is()meiste Zeit viel bequemer
elclanrs

1
BTW hier können wir die Performance - Benchmarks sehen für is()undhasClass()
Jignesh Gohel

1
Es ist also viel langsamer, aber insgesamt auch superschnell. Wenn nur wenige Elemente gescannt werden, scheint dies für viel saubereren Code keine große Sache zu sein.
Jerclarke

27

Zum Spaß habe ich eine kleine jQuery-Add-On-Methode geschrieben, die nach einem von mehreren Klassennamen sucht:

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

Dann könnten Sie in Ihrem Beispiel Folgendes verwenden:

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

// do stuff 

}

Sie können so viele Klassennamen übergeben, wie Sie möchten.


Hier ist eine erweiterte Version, mit der Sie auch mehrere Klassennamen übergeben können, die durch ein Leerzeichen getrennt sind:

$.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 
}

Arbeitsdemo: http://jsfiddle.net/jfriend00/uvtSA/


Hervorragend, das funktioniert gut ... auch browserübergreifend! Getestet auf FF und IE.
Crmpicco

Ich habe eine leichte Modifikation vorgenommen, um sie an die jQuery-Konventionen für .addClass und .removeClass () anzupassen. ( stackoverflow.com/a/14887517/170456 )
CyberMonk

25

Dies kann eine andere Lösung sein:

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

laut jsperf.com ist es auch ziemlich schnell.


Sehr schön, viel schneller!
Philip

9
Dies entspricht auch der Klasse 'ZZZm320WWW' und dergleichen. Versuchen Sie ... match (/ \ b (m320 | m768) \ b /), wobei die \ b mit dem Anfang und dem Ende eines Wortes übereinstimmen.
Juan Lanus

nur um nachzufolgen (7 Jahre später :)). Dies funktioniert gut, aber wenn das von Ihnen definierte HTML-Element keine Klassen hat, wird der Fehler "Übereinstimmung kann nicht gelesen werden" mit undefiniertem Fehler ausgelöst. Wenn dies der Fall ist, testen Sie, ob das Element überhaupt das Attribut 'class' hat (oder stellen Sie sicher, dass das Attribut 'class' nicht null ist).
Sanya

5

Für alle, die sich über einige der verschiedenen Leistungsaspekte mit all diesen verschiedenen Optionen wundern, habe ich hier einen jsperf-Fall erstellt: jsperf

Kurz gesagt, die Verwendung element.hasClass('class')ist am schnellsten.

Die nächstbeste Wette ist die Verwendung elem.hasClass('classA') || elem.hasClass('classB'). Ein Hinweis zu diesem Thema: Ordnung ist wichtig! Wenn die Klasse 'classA' eher gefunden wird, listen Sie sie zuerst auf! ODER-Bedingungsanweisungen werden zurückgegeben, sobald eine davon erfüllt ist.

Die mit Abstand schlechteste Leistung war die Verwendung element.is('.class').

Ebenfalls im jsperf aufgeführt sind die Funktion von CyberMonk und die Lösung von Kolja .


Wirklich interessant! Ich hatte keine Ahnung von jsperf. Vielen Dank für die Veranschaulichung der verschiedenen Variationen.
Danny Englander

3

Hier ist eine kleine Variation der Antwort von jfriend00:

$.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;
}

Ermöglicht die Verwendung derselben Syntax wie .addClass () und .removeClass (). zB, .hasAnyClass('m320 m768') braucht natürlich kugelsicher, da es mindestens ein Argument voraussetzt.


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

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

1
Wenn Sie das tun, warum sollten Sie sich überhaupt die Mühe machen, jquery zu verwenden, um das Element zu erhalten?
James Montagne

Nun, ich würde nicht, aber zumindest bekommt es die Klassen nur einmal? Es schien einfach so langweilig ohne ein wenig jQuery, also habe ich getElementsByTagName durch etwas jQ-Magie nur für dich ersetzt!
Adeneo

0

Die hasClass-Methode akzeptiert ein Array von Klassennamen als Argument. Sie können Folgendes tun:

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

Versuche dies:

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

// do stuff 

}

Willkommen bei Stack Overflow! Bitte fügen Sie eine Erklärung hinzu, warum dieser Code dem OP hilft. Dies wird dazu beitragen, eine Antwort zu geben, von der zukünftige Zuschauer lernen können. Siehe Wie Antwort für weitere Informationen.
Heretic Monkey

0

Ich habe mehrere Klassen in einem Parameter der hasClass-Methode getestet und es funktioniert wie erwartet.

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

Dies ist für den Fall, dass beide Klassen vorhanden sein müssen. Verwenden Sie für entweder oder Logik einfach ||

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

Fühlen Sie sich frei, nach Bedarf zu optimieren

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.