1. innerText vs. textContent
Code:
const box = document.getElementById('text-sample');
document.getElementById('innerText-output').textContent = box.innerText;
document.getElementById('textContent-output').textContent = box.textContent;
Result:
First visible line
Hidden words
Second visible line
innerText
textContent
The hidden span uses display: none. innerText skips it; textContent still reads it.
2. getAttribute vs. dataset
Code:
const button = document.getElementById('dataset-button');
const result = [
`button.getAttribute('DATA-author'): ${button.getAttribute('DATA-author')}`,
`button.dataset.AUTHOR: ${button.dataset.AUTHOR}`,
`button.dataset.author: ${button.dataset.author}`,
`button.getAttribute('data-article-author'): ${button.getAttribute('data-article-author')}`,
`button.dataset.articleAuthor: ${button.dataset.articleAuthor}`,
`button.dataset['article-author']: ${button.dataset['article-author']}`
].join('\n');
document.getElementById('dataset-output').textContent = result;
Result:
3. getElementById vs. querySelector
Code:
const id = document.getElementById('id-input').value;
const lines = [];
lines.push(`getElementById('${id}')`);
lines.push(String(document.getElementById(id)));
try {
lines.push(`querySelector('#${id}')`);
lines.push(String(document.querySelector(`#${id}`)));
} catch (error) {
lines.push(error.name + ': ' + error.message);
}
document.getElementById('selector-output').textContent = lines.join('\n');
Result:
4. append vs. appendChild
Code:
const stage = document.getElementById('append-stage');
stage.textContent = '';
const node1 = document.createElement('span');
node1.className = 'chip';
node1.textContent = 'node 1';
const node2 = document.createElement('span');
node2.className = 'chip';
node2.textContent = 'node 2';
stage.append(node1, ' plain string ', node2);
try {
stage.appendChild(' plain string ');
} catch (error) {
document.getElementById('append-output').textContent =
`appendChild(' plain string ') -> ${error.name}`;
}
Result:
append() accepts multiple nodes and strings. appendChild() accepts one Node, so passing a string throws.
5. scrollIntoView vs. scrollIntoViewIfNeeded
Code:
const frame = document.getElementById('scroll-frame');
const target = document.getElementById('scroll-target');
document.getElementById('scrollIntoView-button').onclick = () => {
target.scrollIntoView({
block: 'center',
behavior: 'smooth'
});
};
document.getElementById('scrollIfNeeded-button').onclick = () => {
if (target.scrollIntoViewIfNeeded) {
target.scrollIntoViewIfNeeded(true);
} else {
const frameRect = frame.getBoundingClientRect();
const targetRect = target.getBoundingClientRect();
const visible = targetRect.top >= frameRect.top && targetRect.bottom <= frameRect.bottom;
if (!visible) {
target.scrollIntoView({
block: 'center',
behavior: 'auto'
});
}
}
};
Result:
Scroll area starts here
Target Element
More content below
scrollIntoView() can use smooth scrolling and precise alignment. The fallback shown here mimics scrollIntoViewIfNeeded(true) when the browser does not support it.
6. Quick Rule of Thumb
Code:
const summary = [
'Use textContent when you need raw text, including hidden text.',
'Use dataset with camelCase for data-* properties.',
'Use getElementById when the value is an ID, especially if it may contain selector syntax.',
'Use append when adding multiple nodes or strings.',
'Use scrollIntoView when you need configurable scrolling.'
];
document.getElementById('summary-output').innerHTML =
summary.map(item => `<li>${item}</li>`).join('');
Result: