การลบองค์ประกอบตามชื่อคลาส?


127

ฉันมีรหัสด้านล่างเพื่อค้นหาองค์ประกอบที่มีชื่อคลาส:

// Get the element by their class name
var cur_columns = document.getElementsByClassName('column');

// Now remove them

for (var i = 0; i < cur_columns.length; i++) {

}

ฉันไม่รู้วิธีลบออก ..... ฉันต้องอ้างอิงผู้ปกครองหรืออะไร? วิธีที่ดีที่สุดในการจัดการสิ่งนี้คืออะไร?

@ Karim79:

นี่คือ JS:

var col_wrapper = document.getElementById("columns").getElementsByTagName("div");
var len = col_wrapper.length;

alert(len);

for (var i = 0; i < len; i++) {
    if (col_wrapper[i].className.toLowerCase() == "column") {
        col_wrapper[i].parentNode.removeChild(col_wrapper[i]);
    }
}

นี่คือ HTML:

<div class="columns" id="columns">
    <div class="column"><input type="checkbox" name="col_list[]" value="cows">cows</div>
    <div class="column"><input type="checkbox" name="col_list[]" value="cows">cows</div>
    <div class="column"><input type="checkbox" name="col_list[]" value="cows">cows</div>
    <div class="column"><input type="checkbox" name="col_list[]" value="cows">cows</div>
    <div name="columnClear" class="contentClear" id="columnClear"></div>
</div>

แก้ไข:จบลงด้วยการใช้ตัวเลือก jQuery


4
จริงๆแล้ววิธีที่ดีที่สุดคือใช้ jQuery ไม่เข้าใจจริงๆว่าทำไมใคร ๆ ก็อยากจัดการ DOM ด้วยมืออีกต่อไป
Tyler Eaves

7
ฉันไม่รู้ฮ่า ๆ .... ฉันแค่รู้สึกว่าฉันรู้สึกสกปรกที่รู้กรอบและไม่มีความรู้เกี่ยวกับความสามารถในการใช้ vanilla JS ได้จริง เนื่องจากฉันไม่ใช่คน JS ขนาดใหญ่ฉันจึงลองใช้รหัสวานิลลา JS เมื่อฉันใช้ดังนั้นฉันจะไม่ลืมสิ่งต่าง ๆ ฮ่า ๆ
Brett

20
ขวา. ใครในโลกที่ต้องการเป็นนักพัฒนาที่มีความรู้และรอบรู้ ไร้สาระ!
user113716

1
แน่นอนว่าเป็นแนวทางที่ดี แต่เพียงเพราะคุณใช้ jQuery ไม่ได้หมายความว่าคุณต้องยอมแพ้ในการทำความเข้าใจวิธีการทำงานหรือสิ่งที่ DOM เสนอ คุณอาจซ่อมรถได้ถ้าคุณต้องการ (DOM) แต่ช่างของคุณน่าจะมีประสบการณ์มากกว่า (ทีม jQuery)
Lior Cohen

2
@ ลิออร์: ใช่ช่างของฉันไม่จำเป็นต้องช่วยฉันหมุนกุญแจหรือม้วนหน้าต่างลง ; o)
user113716

คำตอบ:


189

การใช้ jQuery (ซึ่งคุณสามารถใช้ในกรณีนี้ได้) คุณสามารถทำได้ดังนี้:

$('.column').remove();

มิฉะนั้นคุณจะต้องใช้พาเรนต์ของแต่ละองค์ประกอบเพื่อลบออก:

element.parentNode.removeChild(element);

41
+0.75 สำหรับการใช้ jQuery, +0.25 สำหรับการให้โซลูชันที่ไม่ใช่ jQuery: p
ThiefMaster

9
+0.01 สำหรับการใช้ jQuery, +0.99 สำหรับการให้โซลูชันที่ไม่ใช่ jQuery: p
Alex Pyzhianov

186

หากคุณไม่ต้องการใช้ JQuery:

function removeElementsByClass(className){
    var elements = document.getElementsByClassName(className);
    while(elements.length > 0){
        elements[0].parentNode.removeChild(elements[0]);
    }
}

1
มีโซลูชันที่ไม่ได้ผลมากมายที่น่าแปลกใจ นี่คือสิ่งที่ถูกต้อง ขอบคุณ!
penguinsource

12
หากใครสงสัยว่าทำไมเขาถึงลบองค์ประกอบแรก (ดัชนี 0) ออกเสมอนั่นเป็นเพราะเมื่อคุณลบองค์ประกอบมันจะทำให้elementsอาร์เรย์หดตัวลงด้วย
Jefferson Lima

แล้วดัชนีอื่น ๆ (ยอมรับดัชนี 0) ล่ะ?
ofir_aghai

2
@ofir_aghai ขณะที่ @JeffersonLima ชี้ว่าgetElementsByClassNameเป็นคอลเลกชันสด developer.mozilla.org/en-US/docs/Web/API/NodeList
Veikko Karsikko

2
ข้อสังเกตที่ดีเกี่ยวกับความจริงที่ว่าอาร์เรย์องค์ประกอบหดตัว
ferralucho

34

การใช้ES6คุณสามารถทำได้ดังนี้:

const removeElements = (elms) => elms.forEach(el => el.remove());

// Use like:
removeElements( document.querySelectorAll(".remove") );
<p class="remove">REMOVE ME</p>
<p>KEEP ME</p>
<p class="remove">REMOVE ME</p>


หากต้องการใช้ประโยชน์เพิ่มเติมจาก ES6 ให้ทำอย่างไร: var removeElements = (elms) => [... elms] .forEach (el => el.remove ());
Calculuswhiz

1
คำตอบที่ดีที่สุดขอบคุณ!
Francesco

25

ใน Javascript แท้โดยไม่มี jQuery หรือ ES6 คุณสามารถทำได้:

const elements = document.getElementsByClassName("my-class");

while (elements.length > 0) elements[0].remove();

2
คำตอบที่ชัดเจนที่สุดโดยไม่ต้องใช้ jQuery และ ES6
Eric

2
บางทีคำตอบของคุณอาจจะมาในภายหลัง - ควรเป็นคำตอบที่ยอมรับได้เพราะ jQuery ไม่ได้ขึ้นอยู่กับ โดยทั่วไปควรใช้ vanilla-js ดีกว่าไม่ใช่หรือ?
Luckyfella

คำตอบที่ดีที่สุดโดยไม่ต้องใช้ jQuery ที่ไม่จำเป็นและมีน้ำหนักมาก พูดว่าไม่กับ jQuery ใช่น้ำแข็งวานิลลา!
Thanasis


10

เบร็ท - คุณทราบว่าgetElementyByClassNameการสนับสนุนจาก IE 5.5-8 คือไม่ได้มีตาม quirksmode ? คุณจะดีกว่าถ้าทำตามรูปแบบนี้หากคุณสนใจเกี่ยวกับความเข้ากันได้ข้ามเบราว์เซอร์:

  • รับองค์ประกอบคอนเทนเนอร์ตาม ID
  • รับองค์ประกอบย่อยที่จำเป็นตามชื่อแท็ก
  • วนซ้ำเด็กทดสอบคุณสมบัติ className ที่ตรงกัน
  • elements[i].parentNode.removeChild(elements[i]) เหมือนที่คนอื่น ๆ พูด

ตัวอย่างด่วน:

var cells = document.getElementById("myTable").getElementsByTagName("td");
var len = cells.length;
for(var i = 0; i < len; i++) {
    if(cells[i].className.toLowerCase() == "column") {
        cells[i].parentNode.removeChild(cells[i]);
    }
}

นี่คือตัวอย่างสั้น ๆ

แก้ไข: นี่คือเวอร์ชันคงที่เฉพาะสำหรับมาร์กอัปของคุณ:

var col_wrapper = document.getElementById("columns").getElementsByTagName("div");

var elementsToRemove = [];
for (var i = 0; i < col_wrapper.length; i++) {
    if (col_wrapper[i].className.toLowerCase() == "column") {
        elementsToRemove.push(col_wrapper[i]);
    }
}
for(var i = 0; i < elementsToRemove.length; i++) {
    elementsToRemove[i].parentNode.removeChild(elementsToRemove[i]);
}

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

ลองดูที่นี่


ขอบคุณสำหรับสิ่งนั้น - แม้ว่าจะไม่ใช่ปัญหาใหญ่เนื่องจากเป็นส่วนของผู้ดูแลระบบดังนั้นจะมีคนใช้งานจริงๆเพียงคนเดียว .... แต่จะยังคงนำความคิดเห็นของคุณมาพิจารณาด้วย
Brett

@Brett - ทำต่อไป! ใช้เวลาไม่กี่นาทีคุณจะได้รับรางวัลพิเศษที่ออฟฟิศ :)
karim79

โอเคฉันลองแล้ว ... มันรายงานจำนวนองค์ประกอบที่ถูกต้องเมื่อฉันทำการแจ้งเตือน แต่มีเพียงสองในสี่ที่มีชื่อคลาสนั้นและฉันได้รับข้อผิดพลาดนี้: col_wrapper [i] ไม่ได้กำหนด ฉันจะอัปเดตโพสต์ของฉันด้วยรหัสที่ฉันใช้
Brett

@Brett - หากคุณสนใจฉันแก้ไขรหัสที่อัปเดตแล้วและแสดงความคิดเห็นเกี่ยวกับปัญหา
karim79

ผู้ชายคนนี้ช่วยฉันได้มากกว่าที่คุณจะจินตนาการได้ด้วยปัญหาที่ฉันนิ่งงันในช่วงสองชั่วโมงที่ผ่านมา ขอบคุณ!
Zoolander

4

ฉันชอบใช้forEachover for/ whilelooping ในการใช้งานจำเป็นต้องแปลงHTMLCollectionเป็นArrayอันดับแรก:

Array.from(document.getElementsByClassName("post-text"))
    .forEach(element => element.remove());

ให้ความสนใจไม่ใช่วิธีที่มีประสิทธิภาพสูงสุด สง่างามมากขึ้นสำหรับฉัน


4

หนึ่งบรรทัด

document.querySelectorAll(".remove").forEach(el => el.remove());

ตัวอย่างเช่นคุณสามารถทำได้ในหน้านี้เพื่อลบ userinfo

document.querySelectorAll(".user-info").forEach(el => el.remove());


1

คุณสามารถใช้ไวยากรณ์นี้: node.parentNode

ตัวอย่างเช่น:

someNode = document.getElementById("someId");
someNode.parentNode.removeChild(someNode);

2
คำถามนี้ขอให้ลบโดย className
JoeTidee

1

ฟังก์ชันเรียกซ้ำอาจช่วยแก้ปัญหาของคุณได้ดังต่อไปนี้

removeAllByClassName = function (className) {
    function findToRemove() {
        var sets = document.getElementsByClassName(className);
        if (sets.length > 0) {
            sets[0].remove();
            findToRemove();
        }
    }
    findToRemove();
};
//
removeAllByClassName();

1
ฮ่าฮ่าหลีกเลี่ยงการวนซ้ำ <3
Ivan Ivković

0

ในกรณีที่คุณต้องการลบองค์ประกอบที่เพิ่มแบบไดนามิกให้ลองทำดังนี้:

document.body.addEventListener('DOMSubtreeModified', function(event) {
    const elements = document.getElementsByClassName('your-class-name');
    while (elements.length > 0) elements[0].remove();
});

0
const elem= document.getElementsByClassName('column')

for (let i = elem.length; 0 < i ; )
    elem[--i].remove();

หรือ

const elem= document.getElementsByClassName('column')

while (elem.length > 0 )
    elem[0].remove();

0

มันง่ายมากหนึ่งซับโดยใช้ตัวดำเนินการกระจาย ES6 เนื่องจาก document.getElementByClassName ส่งคืนคอลเล็กชัน HTML

[...document.getElementsByClassName('dz-preview')].map(thumb => thumb.remove());

-1

ข้อผิดพลาดขององค์ประกอบการข้ามในสิ่งนี้ (โค้ดจากด้านบน)

var len = cells.length;
for(var i = 0; i < len; i++) {
    if(cells[i].className.toLowerCase() == "column") {
        cells[i].parentNode.removeChild(cells[i]);
    }
}

สามารถแก้ไขได้โดยเพียงแค่รันลูปย้อนกลับดังต่อไปนี้ (เพื่อไม่ต้องใช้อาร์เรย์ชั่วคราว)

var len = cells.length;
for(var i = len-1; i >-1; i--) {
    if(cells[i].className.toLowerCase() == "column") {
        cells[i].parentNode.removeChild(cells[i]);
   }
}

นี่เป็นบิตที่ซับซ้อน ทำไมไม่ใช้ while cycle แทนล่ะ? (ดูคำตอบของฉัน)
tocqueville

@tocqueville คำถามที่โพสต์ใช้สำหรับวนซ้ำ ฉันเป็นเพียงการชี้ให้เห็นวิธีแก้ไขข้อบกพร่องโดยมีการเปลี่ยนแปลงโค้ดของเขาเพียงเล็กน้อย
shao.lo

-3

คุณสามารถใช้วิธีง่ายๆเพียงแค่เปลี่ยนคลาสตัวกรองคอลเล็กชัน HTML ได้รับการอัปเดต:

var cur_columns = document.getElementsByClassName('column');

for (i in cur_columns) {
   cur_columns[i].className = '';
}

อ้างอิง: http://www.w3.org/TR/2011/WD-html5-author-20110705/common-dom-interfaces.html


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