My goal is, using Jquery or vanilla JS, to clear the inner text only of a div and each of its child elements while keeping all elements intact after the fact. In the example below, the div is student_profile
.
Answers on SO have recommended the functions .html('')
and .text('')
but, as my example shows below, this completely removes the child element from the DOM (my example shows only one function but both actually remove the element). Is there a function that would remove all of the text from the current div and child divs while keeping the elements themselves intact?
Any advice here would be appreciated!
function cleardiv() {
console.log(document.getElementById("student_name"));
$('#student_profile').html('');
console.log(document.getElementById("student_name"));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='student_profile'>
<h1 id="student_name">Foo Bar</h1>
<p id="student_id">123</p>
<p id="studen_course">math</p>
<p id="last_reported">2021-01-01</p>
</div>
<button onclick="cleardiv()">Clear</button>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
One option is to select all text node descendants and .remove()
them, leaving the actual elements intact:
const getTextDecendants = (parent) => {
const walker = document.createTreeWalker(
parent,
NodeFilter.SHOW_TEXT,
null,
false
);
const nodes = [];
let node;
while (node = walker.nextNode()) {
nodes.push(node);
}
return nodes;
}
function cleardiv() {
for (const child of getTextDecendants($('#student_profile')[0])) {
child.remove();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='student_profile'>
<h1 id="student_name">Foo Bar</h1>
<p id="student_id">123</p>
<p id="studen_course">math</p>
<p id="last_reported">2021-01-01</p>
</div>
<button onclick="cleardiv()">Clear</button>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You can try the selector #student_profile *
to include all the child elements.
function cleardiv() {
console.log(document.getElementById("student_name"));
$('#student_profile *').text('');
console.log(document.getElementById("student_name"));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='student_profile'>
<h1 id="student_name">Foo Bar</h1>
<p id="student_id">123</p>
<p id="studen_course">math</p>
<p id="last_reported">2021-01-01</p>
</div>
<button onclick="cleardiv()">Clear</button>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
If it's only direct children you're looking to affect, you can iterate the childNodes
of the parent element. This will clear both element nodes as well as non-element nodes such as text nodes. Here using the NodeList#forEach()
method provided by the returned NodeList.
function cleardiv() {
document.getElementById('student_profile')
.childNodes
.forEach((node) => (node.textContent = ''));
console.log(document.getElementById('student_name'));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='student_profile'>
<h1 id="student_name">Foo Bar</h1>
<p id="student_id">123</p>
<p id="studen_course">math</p>
<p id="last_reported">2021-01-01</p>
</div>
<button onclick="cleardiv()">Clear</button>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>