Javascript удалить, не удаляя все элементы

Пожалуйста, обратитесь к скрипту - http://jsfiddle.net/fkwwyvz8/

x = document.getElementsByClassName("buddy_blocks");
for(i=0;i<x.length;i++)
    x[i].remove();

Нажмите на последнюю кнопку, и он должен был удалить все остальные кнопки, но это не так, а удаляет только некоторые из них, не знаю, почему? И как убрать все эти кнопки?


person nikhil rao    schedule 04.02.2015    source источник
comment
потому что когда вы удаляете элементы из dom, вы меняете исходный массив x   -  person Kirill Pisarev    schedule 04.02.2015
comment
как убрать все кнопки?   -  person nikhil rao    schedule 04.02.2015
comment
Пожалуйста, разместите весь соответствующий код в своем вопросе. Вопросы, где необходимые части кода находятся ТОЛЬКО во внешних ссылках, здесь, на StackOverflow, не рассматриваются. Это связано с тем, что внешние ссылки имеют тенденцию исчезать или изменяться со временем, что делает вопрос бесполезным со временем, а не полезной ссылкой.   -  person jfriend00    schedule 04.02.2015


Ответы (5)


Поскольку в вашем коде уже есть jQuery, вы можете просто использовать это, чтобы удалить все кнопки:

$(".buddy_blocks").remove();

Ваша попытка не сработала по двум причинам:

  1. document.getElementsByClassName() возвращает динамический список узлов, который меняется под вами каждый раз, когда вы удаляете элемент, из-за чего вы пропускаете элементы в своей итерации.
  2. Потому что элемент DOM не имеет метода .remove() (во всяком случае, в большинстве браузеров — это предлагаемый метод, но он еще не широко доступен). У родителя есть метод .removeChild(), который вы можете использовать вместо него.

В простом Javascript вы можете настроить свою итерацию в обратном порядке, чтобы при удалении элементов и изменении динамической коллекции HTMLCollection это не испортило вашу итерацию, потому что изменения будут элементами, которые вы уже прошли. И переключитесь на использование .removeChild() следующим образом:

function f() {
    var x = document.getElementsByClassName("buddy_blocks");
    for(var i = x.length - 1; i >= 0; i--) {
        x[i].parentNode.removeChild(x[i]);
    }
}

Кроме того, пожалуйста, используйте var для всех переменных, которые должны быть локальными для вашей функции, чтобы вы не создавали "случайные глобальные переменные", которые затруднят обнаружение ошибок в будущем.

person jfriend00    schedule 04.02.2015
comment
document.getElementsByClassName(buddy_blocks).remove() будет делать в JS? не работает. какая-то синтаксическая ошибка? - person nikhil rao; 04.02.2015
comment
@nikhilrao - нет, это не сработает, потому что у nodeList или HTMLCollection нет метода .remove(), который работает со всей коллекцией. - person jfriend00; 04.02.2015
comment
@nikhilrao - я добавил простой способ JS. - person jfriend00; 04.02.2015
comment
@КириллПисарев - исправлено. - person jfriend00; 04.02.2015
comment
@nikhilrao - я исправил ошибку в своем ответе. .remove() также не является методом DOM. Вы должны использовать .removeChild() для простого Javascript. - person jfriend00; 04.02.2015

При переборе массива и его изменении начинайте с последнего индекса, чтобы избежать побочных эффектов для текущей позиции индекса при удалении элементов.

$("#c").click(function() {
  f();
});

function f() {
  x = document.getElementsByClassName("buddy_blocks");
  for(i=x.length-1;i>=0;i--)
    x[i].remove();
}
person kindasimple    schedule 04.02.2015

Вы зацикливались на элементах.

x = document.getElementsByClassName("buddy_blocks");
for(i=0;i<x.length;i++)
    x[i].remove();

x - это NodeList, а не массив. Это просмотр текущих элементов в режиме реального времени, который соответствует элементам этого класса. Поэтому, когда вы удаляете первый элемент, то, что было первым элементом, больше не находится в списке, а второй элемент теперь является первым элементом. Но вы перешли к тому, что было третьим элементом, но теперь это новый второй элемент.

Конечным результатом является удаление только половины элементов.

Рассмотрим либо это:

//remove the first item from the NodeList until there is nothing left
x = document.getElementsByClassName("buddy_blocks");
while(x.length > 0) {
    x[0].remove();
}

or:

//remove from the end of the list, which won't cause other elements to change position
x = document.getElementsByClassName("buddy_blocks");
for(i=x.length-1;i>=0;i--) {
    x[i].remove();
}
person Nicholas Daley-Okoye    schedule 04.02.2015

jQuery способ удалить все элементы с классом 'buddy_blocks':

$(".buddy_blocks").remove();

скрипка

простой способ javascript:

var elems = document.getElementsByClassName('buddy_blocks'),
    elem;
while(elems.length){
    elem = elems.item(0);
    elem.parentNode.removeChild(elem);
}

скрипка

person Kirill Pisarev    schedule 04.02.2015
comment
с помощью JS есть способ? - person nikhil rao; 04.02.2015

Причиной такого поведения является то, что переменная, содержащая элемент DOM "x", указывает на активный элемент DOM. Таким образом, каждый раз, когда вы удаляете один элемент, «x» содержит новую структуру DOM. Поэтому нам нужно использовать цикл while ниже и продолжать удалять 1-й дочерний элемент из DOM.

$("#c").click(function() {
  f();
});
function f() {
   x = document.getElementsByClassName("buddy_blocks");
//for(i=0;i<x.length;i++)
//x[i].remove();
    var i = 0;
    while(x.length) {
     x[0].remove();
        i++;
    }
}

person sidrocks    schedule 04.02.2015