Using removeChild with HTMLCollection
Consider this code:
xr = document.querySelectorAll('.material-tooltip'); // NodeList
console.log(xr.length); // 50
for (ya of xr)
ya.parentNode.removeChild(ya);
zu = document.querySelectorAll('.material-tooltip');
console.log(zu.length); // 0
This works as expected, it removes all of the found elements. Now consider this code:
xr = document.getElementsByClassName('material-tooltip'); // HTMLCollection
console.log(xr.length); // 50
for (ya of xr)
ya.parentNode.removeChild(ya);
zu = document.getElementsByClassName('material-tooltip');
console.log(zu.length); // 25
It is only removing half of the found elements. What is causing this?
Answer
querySelectorAll
returns a non-live NodeList
. getElementsByClassName
returns a live HTMLCollection
. The former behaves like any array: you go through the array, then do something for each element. But a live HTMLCollection
is different - its contents reflect the current situation in the DOM at any time; if you remove an element from DOM, it disappears in xr
, and if you add an element to DOM that fits the selector, it will appear in xr
, even after you run getElementsByClassName
.
Let's do the first iteration of ya
being 0
. You remove xr[0]
, and it disappears from the list. Now the element 1 is xr[0]
; ya
becomes 1
; and you remove xr[1]
(element 2), with the element 1 being skipped. You then remove xr[2]
(element 3), and skip element 4... etc.
Whenever you are operating on a live HTMLCollection
, either go from back to front so that disappearing elements don't mess you up, or clone the HTMLCollection
to fix its elements in place, or just do a loop removing xr[0]
until xr
is empty.
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM