Advanced JS Fundamentals to jQuery & Pure DOM Scripting Exercise 16: Solution
Transcript from the "Exercise 16: Solution" Lesson
>> Justin Meyer: If you remember, we're going to loop through every item first, so I'm going to set up my loop return $ each with this. This is going to get my item and my elements, and then for each element, I'm going to set the innerHTML.
>> Justin Meyer: To empty strings to clear it out, so that when I append my text node, it's the only node inside the element.
[00:00:40] So I'm gonna create a text node.
>> Justin Meyer: With the new text.
>> Justin Meyer: And then I'm going to append it to the element with append child. So, the DOM has methods where you can, two methods, really, append child and insert before that let you add nodes to the children of other nodes.
[00:01:13] The appendChild always adds at the end, to the child nodes array. So we're gonna append the text node.
>> Justin Meyer: So that, I'm gonna just check that out and make sure it works.
>> Justin Meyer: Why is my? There we go. So, I should be able to get my UL and change its text to something that includes HTML, just to make sure it's not, it's actually giving a text node back.
[00:02:00] And you can see input shows up instead of an input element. Any questions about this? Yeah.
>> Speaker 2: So how come the creation of the text node needs to be within each, as opposed to right before or outside?
>> Justin Meyer: So, if you did it outside, the problem would be, that's a good, we can.
[00:02:27] Can anybody take a guess what the problem would be? Be awesome. Start answering our own. Anybody else? The scope isn't a problem, this text. Again, it will just walk up the closure and find this text and use that, so that text will work, but there's another problem. Yeah.
>> Speaker 5: [INAUDIBLE]
>> Justin Meyer: Yes, you're only creating one text node so that if you did this on multiple LIs, let's say you try to set the text on multiple LIs to some text, it would only create only one text node and append that text node to every single ally, if that makes sense.
[00:03:20] Let me show you what the result is, the actual result is you only see, well, I'll show you what the result is, it's kind of easier to show than explain.
>> Justin Meyer: This one. Yeah. Okay. So, let me do with all the LI's.
>> Justin Meyer: Someone, how do I get rid of this again?
[00:03:48] Someone told me. Escape. It's just escape? Okay. Cool. So if I were to change the text of each LI to, just say input, what you want is to see three inputs in the page then. Three of not input elements, but three of this text in the page. But you're only gonna see one.
[00:04:11] The reason is, how do I? Elements. Get out of here. The reason is because if we were to walk through this, it's adding that text node to this first LI, but whenever you append an element that's already in the DOM, it implicitly removes it from whatever its current parent is, and inserts it in its new position.
[00:04:39] So what we really need is three text nodes, one for each LI, we need to be creating three. So, if I showed this happening, it might be kind of cool just to watch taking place here.
>> Justin Meyer: I gotta hit my Console here.
>> Justin Meyer: Okay, so, let me put some watches so we can see what we've got.
[00:05:20] Here is the text node, and I should write text node parent.
>> Justin Meyer: Parent node. Right now the text doesn't belong to any parents, then I'm gonna do element that child nodes. Actually, I wish we could get to UL. I'm just going to write the UL so we can see it, URL 0.child nodes.
[00:05:55] That's gonna get the, it's just going to show me all the URLs, child nodes, so I can see each LI. Actually, better might just be to do, I'll just get each LI, okay. So here's each LI, here's the current text node. What it's going to do is you can see it's going to take the first text node, and it's going to say, right now it's got all these child nodes, it's got its anchor.
[00:06:25] What it's going to do is blow them away, child nodes is now zero, and then it's going to append our text node. So now our text node has that first LI as a a parent. But then this loop is gonna come again on this LI, and you can see it's got childNodes 1.
[00:06:44] It's gonna clear that out, make it childNodes 0, but here's the crazy part. This first one still has this text node as a child. All right, that's the text node. And this, the text node has it as a parent. But the second we append that text node to a new LI, it's going to change its parent, even though we didn't really see it, you can see this first LI, now it has no child nodes.
[00:07:13] So, it's just kind of appending it, but then removing it with the next append. So, the fix to this is, to fix this is to create the text node each and every time, really good question. Any others? All right, so now we're going to work on the setter.
[00:07:41] The setter, as I said before, is going to have to you, if we're calling on this you will. It's going to have to recurs through all the different text nodes, starting with the UL's text nodes, than the LI's text nodes, and then the anchors text nodes. Essentially, accumulate them all and then add them all together, or add them while it's going and return that to the user, but for only the first element.
[00:08:06] So, I'm gonna give some skeleton code that helps with this. What's helpful when you're doing recursive functions is to sometimes, you need another function that will call itself. I'm not gonna make text call itself, instead, I'm gonna have text call a function that can call itself.
>> Justin Meyer: In the L's case, what I'm gonna do is if I'm gonna be really good with jQuery, I'm gonna do something like return this, as long as there's a zero element, I'm going to call a getText function with this zero.
[00:08:48] So I'm gonna make getText able to give in an element. It's going to go through all the elements child nodes, find the text nodes, the ones that are text nodes, and add them up, but then also call any normal nodes. It's going to call getText on those to get their text.
[00:09:06] Which will create this recursion where this function getText will be called on every single node from whatever element. This is down to all of its deeply nested child nodes. Is there a question that someone had?
>> Speaker 3: With referring to online 115, can we call this .innerHTML instead?
>> Justin Meyer: I forgot to mention that, that's a great one with a little short cut.
[00:09:31] Maybe save. And it wouldn't really save time, but just to be cool in meta [LAUGH] would be to do just this .HTML, and then this will go through on every element and set its innerHTML to empty. So, you don't actually need to do this. Yeah, forgot to mention that.
[00:09:48] You can absolutely do that. That's kind of cool, start using your own stuff to implement bigger functionality. So, back to this this getText function. Maybe let's implement this together, cuz this one is kinda hard. And we've got a lot of other things, but I'm going to have you guys talk me through it.
[00:10:09] So, this getText, I'm just gonna put this right here. And this is gonna take an element, and it needs to return that element, the text, the accumulated text of all of that element's child nodes,
>> Justin Meyer: So, I'm going to give a little hint to start here. I'm gonna start with some text, just some starting text that I'm gonna add to, and at the end of this, I'm gonna return some text, return the text.
[00:10:44] And in between here, this is where all the magic is gonna happen.
>> Justin Meyer: So, the first thing I need to do is iterate through all of this element's text nodes. First, sorry, not all of its text nodes, all of its child nodes. We'll include text nodes and non text nodes, normal elements.
[00:11:08] How can I iterate through this element's child nodes? What's a good way? How would someone write that?
>> Speaker 4: Dollar each.
>> Justin Meyer: And what would I iterate through?
>> Speaker 2: You said all the child nodes, right?
>> Justin Meyer: Uh-huh, for the element.
>> Speaker 2: [INAUDIBLE] .childnodes?
>> Justin Meyer: Close. It's the elements.child nodes.
[00:11:42] And this would get called with a function that would have each, the index and each child node. Okay. So now what I need to do is if that child node is a text node, I'm just going to add its text to text. How can I tell if an element is a text node or a normal HTML elements, does anybody know?
[00:12:11] I haven't explained it yet, but I'm about to if no one knows.
>> Justin Meyer: Anybody? So, how would you guys maybe figure this out? If you came across this problem and didn't have the Internet to quickly look it up. [LAUGH] How could you tell? Maybe just with debugging skills.
[00:12:35] Here's what I would do, when I get lost especially when I'm in situations where there's not a good answer on Stack Overflow. Look, open your debugger, and just look at the elements and its properties and see if there's something there. All right? So, one thing that I might do is, there's sometimes a lot of properties, unfortunately.
[00:12:54] But it's still a good place to start. So, for instance, a normal node, I could get one of my LI's like this, and I can, if you reveal it in the elements panel, you can see all of the properties on an LI, right? And there's a lot of different things, so I'm kind of gonna go right to the one that is the important one.
[00:13:23] You'd be, there's a node type one, that's weird. It's got node type one, type of a node? That's weird. And what I might do is then say maybe there's a difference between that and a, if I created a, let me not type down there. Sorry. If I created a text node, maybe that has a different node type, it does, it has a three.
[00:13:54] So, this sometimes, if you were to situate, this would totally be something you should would search for and kinda find the answer yourself how to tell the difference between different roads. But sometimes you will be in a situation you're just, I have no idea how to get this value.
[00:14:09] What's it called isn't helping. I've many times just kind of been okay, is there something that helps me on these elements? Know what I'm supposed to do. So, node type is how you can distinguish between a text node, which has node type of three, and a normal node, an LI that has a node type of one.