รับรายการคลาสสำหรับองค์ประกอบด้วย jQuery


657

มีวิธีใน jQuery ที่จะวนซ้ำหรือกำหนดให้กับอาเรย์ทั้งหมดของคลาสที่กำหนดให้กับองค์ประกอบหรือไม่?

อดีต

<div class="Lorem ipsum dolor_spec sit amet">Hello World!</div>

ฉันจะมองหาคลาส "พิเศษ" ดังเช่นใน "dolor_spec" ด้านบน ฉันรู้ว่าฉันสามารถใช้ hasClass () แต่ชื่อคลาสจริงอาจไม่เป็นที่รู้จักในเวลานั้น


หากคุณไม่ทราบชื่อชั้นเรียนในเวลานั้นทำให้คุณไม่สามารถใช้ hasClass () คุณตั้งใจจะรู้ได้อย่างไรว่าชื่อใดในอาเรย์นั้น?
doomspork

ฉันกำลังออกแบบฟอร์มที่ฉันทำการตรวจสอบเบื้องต้นกับ jQuery ฉันกำลังผนวกรหัสขององค์ประกอบอินพุตต่อท้ายรายการคลาสของ div ข้อผิดพลาดหากมีการสร้างขึ้น ฉันทำให้มันเป็นไปได้ที่จะคลิกที่ div ข้อผิดพลาดเพื่อมุ่งเน้นองค์ประกอบการป้อนข้อมูลที่ผิดพลาด สคริปต์นี้จะใช้มากกว่าหนึ่งรูปแบบ ดังนั้นฉันไม่ต้องการรหัสยากรหัสในสคริปต์
Buggabill

1
ใช่ฉันเข้าใจว่าทำไมคุณไม่ต้องการให้ฮาร์ดโค้ด แต่ถ้าคุณใช้เวลาสักครู่เพื่อดูตัวอย่างของ redsquare คุณจะเห็นว่าคุณต้อง hardcode 'someClass' ลงในบล็อก if วิธีใดก็ตามที่คุณสามารถทำได้ด้วยตัวแปร
doomspork

แทนที่จะใช้แอ็ตทริบิวต์คลาสคุณสามารถมีตัวแปรรายการข้อผิดพลาดภายในเนมสเปซของคุณซึ่งมีการอ้างอิง DOM กับองค์ประกอบที่มีข้อผิดพลาด ดังนั้นไม่จำเป็นต้องดึงรายการแอตทริบิวต์ในแต่ละครั้งวนซ้ำค้นหาองค์ประกอบ DOM และโฟกัส
doomspork

คำตอบ:


732

คุณสามารถใช้document.getElementById('divId').className.split(/\s+/);เพื่อรับอาร์เรย์ของชื่อคลาส

จากนั้นคุณสามารถทำซ้ำและค้นหาสิ่งที่คุณต้องการ

var classList = document.getElementById('divId').className.split(/\s+/);
for (var i = 0; i < classList.length; i++) {
    if (classList[i] === 'someClass') {
        //do something
    }
}

jQuery ไม่ได้ช่วยคุณที่นี่จริงๆ ...

var classList = $('#divId').attr('class').split(/\s+/);
$.each(classList, function(index, item) {
    if (item === 'someClass') {
        //do something
    }
});

4
นั่นคือสิ่งที่ฉันได้ทำไปแล้ว แต่ฉันไม่แน่ใจว่ามีการสร้างในฟังก์ชัน jQuery ที่ให้คอลเลกชันของคลาสแก่คุณหรือไม่
Sander

36
FYI: jQuery ใช้ className.split (/ \ s + /)
kͩeͣmͮpͥͩ

70
เพิ่มปลั๊กอิน jQuery ด้วยตัวคุณเอง:$.fn.classList = function() {return this[0].className.split(/\s+/);};
ripper234

1
หรือจากนั้นคุณสามารถ: if ($.inArray("someclass",classList)>=0) { /* hasClass someclass*/ }
sambomartin

ไม่ใช่ผู้เชี่ยวชาญด้าน Javascript ที่นี่ คุณช่วยบอกฉันได้ไหมว่า split (/ \ s + /) ดีกว่าแค่แยก ("")? มันทำงานเหมือนกันสำหรับฉันใน FF23 / Chrome28 / IE8
Roberto Linares

288

ทำไมจึงไม่มีใครอยู่ในรายการ

$(element).attr("class").split(/\s+/);

แก้ไข: @MarkAmery ชี้ให้เห็นคุณไม่สามารถทำได้เพียง.split(' ')เพราะชื่อคลาสสามารถคั่นด้วยช่องว่างใด ๆ


6
นั่นเป็นส่วนหนึ่งของคำตอบที่ยอมรับได้ ... ฉันต้องการชั้นเรียนทั้งหมดที่ใช้กับองค์ประกอบ
Buggabill

54
เพราะมันผิด! ชั้นเรียนสามารถคั่นด้วยช่องว่างใด ๆ (เช่นคุณสามารถห่อแอตทริบิวต์คลาสยาวใน HTML ของคุณลงในหลายบรรทัด) แต่คำตอบนี้ไม่สามารถอธิบายได้ ลองวาง$('<div class="foo bar baz">').attr("class").split(' ')ลงในคอนโซลของเบราว์เซอร์ของคุณ (มีอักขระแท็บอยู่ในนั้น); คุณจะได้รับแทนของรายการระดับที่ถูกต้องของ["foo", "bar baz"] ["foo", "bar", "baz"]
Mark Amery

2
@ MarkAmery ถูกต้อง หากคุณมี a class="foo <lots of spaces here> bar"คุณจะได้อาร์เรย์ที่มีองค์ประกอบสตริงว่าง
Jacob van Lingen

4
ฉันคิดว่าใน 99% ของกรณีวิธีนี้มีประสิทธิภาพคือให้คุณควบคุม HTML ฉันไม่สามารถนึกถึงเหตุผลใด ๆ ที่เราจะต้องสนับสนุนความเป็นไปได้ของแท็บหรือหลายช่องว่างระหว่างชื่อชั้นแม้ว่ามาตรฐาน HTML อนุญาตนี้
Gordon Rouse

5
@GordonRouse พื้นที่พิเศษที่กำลังคืบคลานเข้าสู่รายการของคลาสเป็นเรื่องปกติโดยเฉพาะอย่างยิ่งถ้าตรรกะบางอย่างกำลังเขียนรายการของคลาส
Eric

142

ในการรองรับเบราว์เซอร์คุณสามารถใช้classListคุณสมบัติขององค์ประกอบ DOM

$(element)[0].classList

มันเป็นวัตถุที่คล้ายกับอาร์เรย์ที่แสดงรายการคลาสทั้งหมดที่มีอยู่

หากคุณต้องการสนับสนุนเบราว์เซอร์เวอร์ชันเก่าที่ไม่สนับสนุนclassListคุณสมบัติหน้า MDN ที่เชื่อมโยงจะมี shim อยู่ด้วยถึงแม้ว่า shim จะไม่ทำงานบน Internet Explorer เวอร์ชันต่ำกว่า IE 8


คำตอบที่สะอาดและไม่รวมล้อเลื่อน
Marco Sulla

@Marco Sulla: นี่เป็นข้อบกพร่องอื่น ๆ นอกเหนือจากการสนับสนุนซอฟต์แวร์ที่ล้าสมัย .classListไม่ใช่อาร์เรย์ที่แท้จริงและวิธีการต่าง ๆ ที่ใช้.indexOf(⋯)ไม่ได้ มันเป็นเพียง“ วัตถุที่มีลักษณะคล้ายอาร์เรย์” ในขณะที่.className.split(/\s+/).indexOf(⋯)(จากคำตอบที่ยอมรับ) ใช้งานได้
Incnis Mrsi

คุณสามารถแปลง iterable ใด ๆ เป็นการArrayใช้[...iterable]หรือArray.from(iterable)
Marco Sulla

142

นี่คือปลั๊กอิน jQuery ซึ่งจะส่งคืนอาร์เรย์ของคลาสทั้งหมดที่องค์ประกอบที่ตรงกันมี

;!(function ($) {
    $.fn.classes = function (callback) {
        var classes = [];
        $.each(this, function (i, v) {
            var splitClassName = v.className.split(/\s+/);
            for (var j = 0; j < splitClassName.length; j++) {
                var className = splitClassName[j];
                if (-1 === classes.indexOf(className)) {
                    classes.push(className);
                }
            }
        });
        if ('function' === typeof callback) {
            for (var i in classes) {
                callback(classes[i]);
            }
        }
        return classes;
    };
})(jQuery);

ใช้มันเหมือน

$('div').classes();

ในกรณีของคุณกลับมา

["Lorem", "ipsum", "dolor_spec", "sit", "amet"]

นอกจากนี้คุณยังสามารถส่งฟังก์ชั่นไปยังวิธีการที่จะเรียกในแต่ละชั้นเรียน

$('div').classes(
    function(c) {
        // do something with each class
    }
);

นี่คือ jsFiddle ที่ฉันตั้งค่าเพื่อสาธิตและทดสอบ http://jsfiddle.net/GD8Qn/8/

จาวาสคริปต์ขนาดเล็ก

;!function(e){e.fn.classes=function(t){var n=[];e.each(this,function(e,t){var r=t.className.split(/\s+/);for(var i in r){var s=r[i];if(-1===n.indexOf(s)){n.push(s)}}});if("function"===typeof t){for(var r in n){t(n[r])}}return n}}(jQuery);

เหมาะอย่างยิ่งสำหรับFullCalendarเมื่อคัดลอกคลาสลงในแอตทริบิวต์classNameของกิจกรรม
Dan Power

78

คุณควรลองอันนี้:

$("selector").prop("classList")

ส่งคืนอาร์เรย์ของคลาสปัจจุบันทั้งหมดขององค์ประกอบ


นี่เป็นสิ่งที่ดีมากที่คำตอบที่ยอมรับมีเหตุผลใดที่จะไม่ใช้วิธีนี้หรือไม่?
RozzA

5
ฉันไม่รู้ แต่นี่เป็นวิธีที่เหมาะสมในการรับคุณสมบัติจากองค์ประกอบ DOM และ "classList" เป็นคุณสมบัติดังกล่าวที่ให้อาเรย์ของคลาส css ที่ใช้กับองค์ประกอบ
P.Petkov

@RozzA อาจจะไม่สามารถใช้งานได้ในตอนนี้ แต่ฉันจะบอกว่านี่เป็นวิธีที่เหมาะสมที่สุด ณ ตอนนี้ถ้าคุณไม่ได้ใช้ jQuery ซึ่งวิธีง่ายๆ.classListคือวิธีแก้ปัญหา - คุณเพียงแค่ต้องใส่ใจกับความไม่สอดคล้องกันและ / หรือการสนับสนุนเบราว์เซอร์ที่หายไป ..
Dennis98

@ Dennis98 โทรดีฉันลืมบางครั้งคุณสมบัติใหม่ที่ออกมาเร็ว ๆ นี้ ฉันได้ทำ js แบบธรรมดา.classListแล้วมันทำงานได้ค่อนข้างดีในเบราว์เซอร์สมัยใหม่
RozzA

1
โปรดทราบว่าclassListคุณสมบัติไม่ทำงานบน IE 10/11 สำหรับองค์ประกอบ SVG (แม้ว่าจะใช้งานได้กับองค์ประกอบ HTML) ดูdeveloper.mozilla.org/en-US/docs/Web/API/Element/classList
Métoule


7

ปรับปรุง:

@Ryan Leonard ชี้ให้เห็นอย่างถูกต้องคำตอบของฉันไม่ได้แก้ไขจุดที่ฉันทำเอง ... คุณจำเป็นต้องตัดแต่งและลบช่องว่างสองครั้งด้วย string.replace (/ + / g, "") .. หรือคุณสามารถแบ่ง el.className แล้วลบค่าว่างด้วย (ตัวอย่าง) arr.filter (Boolean)

const classes = element.className.split(' ').filter(Boolean);

หรือทันสมัยกว่า

const classes = element.classList;

เก่า:

ด้วยคำตอบที่ได้รับทั้งหมดคุณไม่ควรลืมที่จะใช้. trim () (หรือ $ .trim ())

เนื่องจากคลาสได้รับการเพิ่มและลบออกมันสามารถเกิดขึ้นได้ว่ามีหลายช่องว่างระหว่างสตริงคลาส .. เช่น 'class1 class2 class3' ..

สิ่งนี้จะเปลี่ยนเป็น ['class1', 'class2', '', '', '', 'class3'] ..

เมื่อคุณใช้การตัดแต่งหลาย ๆช่องว่างจะถูกลบออก ..


2
สิ่งนี้ไม่ถูกต้อง (และไม่ใช่คำตอบ) ทั้ง String.trim () และ $ .trim () ลบช่องว่างนำหน้าและต่อท้ายทั้งหมดและปล่อยให้ส่วนที่เหลือของสตริงอยู่คนเดียว jsconsole.com /?% 22% 20% 20a% 20% 20b% 20% 20% 22.trim ()
Ryan Leonard

คุณเคยดูคำตอบไหม? ทั้งหมดการแก้ JS พื้นเมืองไม่ได้ตรวจสอบชั้นนำและต่อท้ายช่องว่างจึงทำให้รายการระดับความผิดพลาดในขณะที่จะมีการเรียนที่ว่างเปล่าในอาร์เรย์ .. jQuery ไม่เหมือนกันภายในตัดกับเมื่อมันอ่านการเรียน
DutchKevv

2
ฉันเห็นคำตอบอื่นและยอมรับว่าควรลบช่องว่างระหว่างชื่อชั้น ฉันชี้ให้เห็นว่า a) นี่ควรเป็นความเห็นเกี่ยวกับโซลูชันอื่น ๆ เนื่องจากไม่ใช่คำตอบที่สมบูรณ์ b) .trim () ไม่ได้ลบช่องว่างหลายช่องเพื่อให้ได้สิ่งที่คุณต้องการ
Ryan Leonard

1
คุณถูกต้องทั้งหมดแน่นอน ... ขออภัยสำหรับความคิดเห็นที่รวดเร็วของฉัน .. มันไม่ได้ลบช่องว่างระหว่าง ... s.trim (). แทนที่ (/ + / g, "") หรืออะไรก็ตามที่จำเป็น เพื่อลบช่องว่างหลายทั้งหมดในระหว่างเรียน .. ถัดไปนั้น el.classList เกือบจะได้รับการสนับสนุนอย่างกว้างขวางแก้ไขมันทั้งหมดที่ฉันคิดว่า ..
DutchKevv

1
ไม่มีปัญหาเลย. upvoted อย่างมีความสุข.classListเป็นวิธีที่สะอาดกว่ามาก!
Ryan Leonard

7
$('div').attr('class').split(' ').each(function(cls){ console.log(cls);})

2
นี่คือการละเมิดที่น่ากลัวของ.map; ใช้.eachถ้าคุณไม่ต้องการ.mapค่าส่งคืน แยกในช่องว่างมากกว่าช่องว่างใด ๆ เสียยัง - ดูความคิดเห็นของฉันในstackoverflow.com/a/10159062/1709587 แม้ว่าจะไม่มีประเด็นเหล่านี้เป็นจริง แต่สิ่งนี้จะไม่เพิ่มสิ่งใหม่ในหน้าเว็บ -1!
Mark Amery

3

อาจช่วยคุณได้เช่นกัน ฉันใช้ฟังก์ชั่นนี้เพื่อรับคลาสขององค์ประกอบ childern ..

function getClickClicked(){
    var clickedElement=null;
    var classes = null;<--- this is array
    ELEMENT.on("click",function(e){//<-- where element can div,p span, or any id also a class
        clickedElement = $(e.target);
        classes = clickedElement.attr("class").split(" ");
        for(var i = 0; i<classes.length;i++){
            console.log(classes[i]);
        }
        e.preventDefault();
    });
}

ในกรณีที่คุณต้องการระดับ doler_ipsum u calsses[2];สามารถทำเช่นนี้ในขณะนี้


2

ขอบคุณสำหรับสิ่งนี้ - ฉันมีปัญหาที่คล้ายกันเนื่องจากฉันพยายามเชื่อมโยงวัตถุโดยทางโปรแกรมจะมีชื่อคลาสแบบลำดับขั้นแม้ว่าชื่อเหล่านั้นอาจไม่รู้จักสคริปต์ของฉันก็ตาม

ในสคริปต์ของฉันฉันต้องการ<a>แท็กเพื่อเปิดข้อความช่วยเหลือ / ปิดโดยการให้<a>แท็ก[some_class]บวกระดับของแล้วให้ข้อความช่วยเหลือมันของชั้นเรียนของtoggle [some_class]_toggleรหัสนี้ประสบความสำเร็จในการค้นหาองค์ประกอบที่เกี่ยวข้องโดยใช้ jQuery:

$("a.toggle").toggle(function(){toggleHelp($(this), false);}, function(){toggleHelp($(this), true);});

function toggleHelp(obj, mode){
    var classList = obj.attr('class').split(/\s+/);
    $.each( classList, function(index, item){
    if (item.indexOf("_toggle") > 0) {
       var targetClass = "." + item.replace("_toggle", "");
       if(mode===false){$(targetClass).removeClass("off");}
       else{$(targetClass).addClass("off");}
    }
    });
} 

ขอบคุณอลันฉันทำสิ่งที่คล้ายกันฉันประหลาดใจที่ไม่มีวิธีการที่ง่ายกว่านี้
Eric Kigathi

- 1 - tl; dr, ดับไปแทนเจนต์ซึ่งไม่เกี่ยวข้องกับคำถามโดยตรง
Mark Amery

2

ลองสิ่งนี้ คุณจะได้รับชื่อคลาสทั้งหมดจากองค์ประกอบทั้งหมดของเอกสาร

$(document).ready(function() {
var currentHtml="";
$('*').each(function() {
    if ($(this).hasClass('') === false) {
        var class_name = $(this).attr('class');
        if (class_name.match(/\s/g)){
            var newClasses= class_name.split(' ');
            for (var i = 0; i <= newClasses.length - 1; i++) {
                if (currentHtml.indexOf(newClasses[i]) <0) {
                    currentHtml += "."+newClasses[i]+"<br>{<br><br>}<br>"
                }
            }
        }
        else
        {
            if (currentHtml.indexOf(class_name) <0) {
                currentHtml += "."+class_name+"<br>{<br><br>}<br>"
            }
        }
    }
    else
    {
        console.log("none");
    }
});
$("#Test").html(currentHtml);

});

นี่คือตัวอย่างการทำงาน: https://jsfiddle.net/raju_sumit/2xu1ujoy/3/


1

ฉันมีปัญหาที่คล้ายกันสำหรับองค์ประกอบของภาพประเภท ฉันต้องการตรวจสอบว่าองค์ประกอบดังกล่าวเป็นคลาสที่แน่นอนหรือไม่ ก่อนอื่นฉันลองด้วย:

$('<img>').hasClass("nameOfMyClass"); 

แต่ฉันได้ดี "ฟังก์ชั่นนี้ไม่สามารถใช้ได้สำหรับองค์ประกอบนี้"

จากนั้นฉันตรวจสอบองค์ประกอบของฉันใน DOM explorer และฉันเห็นคุณลักษณะที่ดีมากที่ฉันสามารถใช้: className มันมีชื่อของคลาสทั้งหมดขององค์ประกอบของฉันคั่นด้วยช่องว่าง

$('img').className // it contains "class1 class2 class3"

เมื่อคุณได้รับสิ่งนี้เพียงแค่แบ่งสตริงตามปกติ

ในกรณีของฉันนี้ใช้งานได้:

var listOfClassesOfMyElement= $('img').className.split(" ");

ฉันสมมติว่าสิ่งนี้จะใช้ได้กับองค์ประกอบอื่น ๆ (นอกเหนือจาก img)

หวังว่ามันจะช่วย


0

javascript จัดเตรียมคุณลักษณะ classList สำหรับองค์ประกอบโหนดใน dom เพียงแค่ใช้

  element.classList

จะส่งคืนวัตถุของฟอร์ม

  DOMTokenList {0: "class1", 1: "class2", 2: "class3", length: 3, item: function, contains: function, add: function, remove: function…}

วัตถุนั้นมีฟังก์ชั่นเช่นมี, เพิ่ม, ลบซึ่งคุณสามารถใช้ได้


ซ้ำซ้อนน้อยกว่าของstackoverflow.com/a/5457148/1709587ซึ่งโพสต์เมื่อ 3 ปีก่อน; -1
Mark Amery

-3

สายไปหน่อย แต่การใช้ฟังก์ชั่นขยาย () ช่วยให้คุณเรียก "hasClass ()" ในองค์ประกอบใด ๆ เช่น:
var hasClass = $('#divId').hasClass('someClass');

(function($) {
$.extend({
    hasClass: new function(className) {
        var classAttr = $J(this).attr('class');
        if (classAttr != null && classAttr != undefined) {
            var classList = classAttr.split(/\s+/);
            for(var ix = 0, len = classList.length;ix < len;ix++) {
                if (className === classList[ix]) {
                    return true;
                }
            }
        }
        return false;
    }
}); })(jQuery);

10
นั่นไม่ใช่คำถาม
โทมัส

5
นอกจากนี้ jQuery ยังมีฟังก์ชันนี้ในตัวตั้งแต่รุ่น 1.2
แอนดรู

-3

คำถามคือสิ่งที่ Jquery ออกแบบมาให้ทำ

$('.dolor_spec').each(function(){ //do stuff

และทำไมไม่มีใครได้รับ. find ()เป็นคำตอบ

$('div').find('.dolor_spec').each(function(){
  ..
});

นอกจากนี้ยังมี classList สำหรับเบราว์เซอร์ที่ไม่ใช่ IE:

if element.classList.contains("dolor_spec") {  //do stuff

3
- 1; ท่ามกลางปัญหาอื่น ๆ โค้ดสองรายการแรกของคุณไม่เกี่ยวข้องกับคำถามที่ถามและข้อมูลโค้ดสุดท้ายของคุณเป็นข้อผิดพลาดทางไวยากรณ์
Mark Amery

-4

ที่นี่คุณไปเพียงแค่ปรับคำตอบของreadsquareเพื่อส่งกลับอาร์เรย์ของคลาสทั้งหมด:

function classList(elem){
   var classList = elem.attr('class').split(/\s+/);
    var classes = new Array(classList.length);
    $.each( classList, function(index, item){
        classes[index] = item;
    });

    return classes;
}

ผ่านองค์ประกอบ jQuery ไปยังฟังก์ชันเพื่อให้การเรียกตัวอย่างเป็น:

var myClasses = classList($('#myElement'));

3
เหตุใดจึงวนซ้ำผ่านอาร์เรย์ classList เพิ่มอิลิเมนต์ทั้งหมดในคลาสอาเรย์และส่งคืนอาเรย์คลาส เพียงแค่ส่งคืน classList ควรทำแบบเดียวกันใช่ไหม?
Martijn

Nope เนื่องจากเราอ้างถึงสถานการณ์ที่มีคลาสจำนวนมากสำหรับองค์ประกอบเดียวกัน ถ้ามันเป็นเรื่องง่ายมากที่เราไม่ได้ที่นี่ในหัวข้อนี้ :)
Gregra

8
หัวข้อนี้เป็นเรื่องเกี่ยวกับการกลับรายการของการเรียนและก็กลับมา$(elem).attr('class').split(/\s+/)ไม่ว่า บางทีฉันอาจเข้าใจผิด แต่ฉันไม่เห็นเหตุผลที่จะทำซ้ำผ่านคอลเลกชันคัดลอกเนื้อหาไปยังคอลเลกชันใหม่และส่งกลับคอลเลกชันใหม่
Martijn

-4

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ก็ยัง

<div id="specId" class="Lorem ipsum dolor_spec sit amet">Hello World!</div>

var className=".dolor_spec" //dynamic

หากคุณต้องการจัดการองค์ประกอบ

$("#specId"+className).addClass('whatever');

ถ้าคุณต้องการตรวจสอบว่าองค์ประกอบมีคลาสหรือไม่

 $("#specId"+className).length>0

ถ้าหลายคลาส

//if you want to select ONE of the classes
var classNames = ['.dolor_spec','.test','.test2']
$("#specId"+classNames).addClass('whatever');
$("#specId"+classNames).length>0
//if you want to select all of the classes
var result = {className: ""};
classNames.forEach(function(el){this.className+=el;},result);
var searchedElement= $("#specId"+result.className);
searchedElement.addClass('whatever');
searchedElement.length>0

1
ตัวอย่างเหล่านี้ไม่ได้ตอบคำถามที่ถามเลย -1
Mark Amery
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.