I'm trying to move away from jQuery into plain javascript, but am having difficulty traversing the DOM as I did with jQuery. I'm getting an "Uncaught TypeError: html.parentNode is undefined" error, after writing to the DOM, when trying to move back up the DOM structure. Here's the code:
Javascript
let html = 'change to this';
let eA = document.querySelector('.startA');
eA.parentNode
.querySelector('.target1A .target2A')
.innerHTML = html
.parentNode
.querySelector('.target1A')
.classList
.remove('hidden');
HTML
<div id="top">
<div class="startA">
<div class="target1A hidden">
<div class="target2A">target 1</div>
</div>
</div>
</div>
I can't seem to figure out why this is happening. I think I'm not completely understanding how to move through the DOM yet. Any help is greatly appreciated.
Thanks
The assignment operator has low precedence. Your code is equivalent to:
const result = html
.parentNode
.querySelector('.target1A')
.classList
.remove('hidden');
eA.parentNode
.querySelector('.target1A .target2A')
.innerHTML = result;
Which doesn't work - you can't chain the assignment operator like you're trying to do. Select the element after inserting the HTML, as a separate statement.
You also don't need to select target1A
, since it's already the parent of the target2A
.
const target = eA.parentNode.querySelector('.target1A .target2A');
target.innerHTML = html;
target.parentNode
.classList
.remove('hidden');
const eA = document.querySelector('.startA');
const target = eA.parentNode.querySelector('.target1A .target2A');
target.innerHTML = 'foobar';
target.parentNode
.classList
.remove('hidden');
<div id="top">
<div class="startA">
<div class="target1A hidden">
<div class="target2A">target 1</div>
</div>
</div>
</div>
If you wanted to do this in a chainable fashion, and since your question is tagged with jQuery, you can use that:
$('.startA')
.find('.target1A .target2A')
.html(html)
.parent()
.removeClass('hidden');
$('.startA')
.find('.target1A .target2A')
.html('foobar')
.parent()
.removeClass('hidden');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="top">
<div class="startA">
<div class="target1A hidden">
<div class="target2A">target 1</div>
</div>
</div>
</div>