I'm trying to run this code and extract all headings with the option to show "doesn't exist" when certain headings well... doesn't exist, but it's not reading the else statement somehow and would be great if you could point me to the right direction.
function headingsEx() {
let h = ["h1", "h2", "h3", "h4", "h5", "h6"];
for (let i of h) {
if (document.getElementsByTagName(i)) {
let foundHs = document.querySelectorAll(i)
for (let c of foundHs) {
console.log({ [i]: c.textContent })
};
} else {
console.log([i] " doesn't exist");
}
}
}
headingsEx();
CodePudding user response:
According to the docs, document.getElementsByTagName(i)
returns a live HTMLCollection. No where in the docs does it say it returns anything other than that. So it is safe to say that document.getElementsByTagName(i)
will always be truthy (i.e. not null
or false
). You can instead check the length
member. It will be greater than 0
if at least one of the element exists.
function headingsEx() {
let h = ["h1", "h2", "h3", "h4", "h5", "h6"];
for (let i of h) {
if (document.getElementsByTagName(i).length) {
let foundHs = document.querySelectorAll(i)
for (let c of foundHs) {
console.log({ [i]: c.textContent })
};
} else {
console.log([i] " doesn't exist");
}
}
}
headingsEx();
CodePudding user response:
Since you asked about alternative approaches:
This example grabs all the heading elements using querySelectorAll
, and then uses map
to create a new array of node names. You can then iterate over the headings array and check to see if each element is included in the nodeNames
array, and then log the result accordingly.
const arr = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
const headings = document.querySelectorAll(arr.join(','));
const nodeNames = [...headings].map(heading => {
return heading.nodeName.toLowerCase();
});
arr.forEach(el => {
if (nodeNames.includes(el)) {
console.log(`${el}: exists.`)
} else {
console.log(`${el}: does not exist.`)
}
});
<h1>Hi</h1>
<h3>Hi</h3>
<h4>Hi</h4>
<h6>Hi</h6>
CodePudding user response:
An empty array is truthy (usually anyway) so even when getElementsByTagName(i)
finds nothing and returns an empty array, the "then" block is still the one that gets executed.
console.log('is [] true?');
if ([]) {
console.log('yes');
} else {
console.log('no');
}
console.log('---');
console.log('is [99] true?');
if ([99]) {
console.log('yes');
} else {
console.log('no');
}
If you're wondering why I said "usually", see https://xavierchow.github.io/2015/12/15/js-coercion/ but don't worry if you can't follow it. It was news to me as well.