Advanced JS Fundamentals to jQuery & Pure DOM Scripting Exercise 18: Implementing the next() method
Transcript from the "Exercise 18: Implementing the next() method" Lesson
>> Alexis: We have the ability to look for elements by themselves in the DOM. We have the ability to look for elements within those elements in the DOM. And then modify either collection to our choosing, which is really, really nice, but there's a lot of situations. Let's say we're gonna build a tab's widget like we are later today.
[00:00:27] We probably wanna modify some other element based on your location in the DOM. Maybe you wanna find an element that's next to you or you're wrapped within an element, you want to find that parent element. There's a bunch of different ways. A bunch of different properties we have at our disposal to make this possible.
[00:00:48] We're all gonna cover this in our traversals. So let's take a look at our little dummy set of DOM here. We have a basic unordered list with some items. But let's assume right now we're our elements that we care about is this li in red. This is the one we currently have access to.
[00:01:09] Maybe we've done some kind of query selector or wrapped this in a jQuery object already. And based on this location, we want to find other elements in the DOM. This is what we have access to. So we have a childNodes property. We've seen a little bit of this when we're building our text helper.
[00:01:27] This is gonna give us access to all the nodes within this li. We have firstChild, which will give us just the, that's strange. Why has it become black on the projector?
>> Alexis: Let's reload that animation. There you go. We have the firstChild, which will just give us the absolute firstChild node we have.
[00:01:54] We have lastChild, which will give us the last node in our children. We have nextSibling. So for this next li, the next DOM node following it would be this bottom li. This will be available via nextSibling. previousSibling, which will give us the prior DOM node. We have parentsNode, which will give us our wrapping or containing elements.
[00:02:45] Maybe it's a fancy hover menu drop down kind of thing. You wanna manipulate your child in some state and you don't really care about manipulating the text nodes. So up until now we've had to filter out text nodes. But with the new children property, the browser will just give this to you.
[00:03:03] This will give us all childNodes all the child DOM nodes, make sense? Okay, so we're about to build a few helpers. Specifically, we're gonna build the next helper based on our current position. We're gonna try to grab the next element in the DOM, our nextSibling element in the DOM.
[00:03:26] But we still want that same chain ability. There's a couple things we want to return a jQuerycollection. Because you don't just want the next elements for academic reasons, you probably want to change its HTML. Maybe you want to add some text to that element. If right now, it's an empty li, you wanna modify it somehow.
[00:03:47] So we want this to be possible. So we're gonna take our current collection. I'm gonna walk you through this, so I'll give you a little bit of pseudocode for this. Be able to traverse to using a nextSibling to get the next node. Now here's the little gotcha and this hints down below.
[00:04:11] Children is kind of our nice thing that ignores text nodes. But nextSibling and, subsequently, previousSibling as well, do not. If you hit nextSibling and the next. Let's say you have a div and then some text and then another div and you hit nextSibling. What jQuery wants to give you is, you're looking for that div.
[00:04:32] They'll skip the text nodes. nextSibling will not. It's explicit. It will give you the next node of whatever type. So when we're doing this helper, we wanna be able to check for that. So let's write this out. Let's write part of this out. We'll scroll down to our next, okay?
>> Alexis: So the first thing,
>> Alexis: We're gonna need to do. We have to do something similar here. Because if you have a bunch of divs on the page and you want to say dollar. You wanna do something like this, $('div').next(). This is gonna return an array, a collection of elements.
[00:05:22] Because there could be many divs and you're gonna get the nextSibling of each one of those divs and return that as a collection. So to make this possible, we're gonna need our accumulator once again, our accumulator array. This is where we're gonna store all the elements we found through the course of this function.
[00:05:46] And then at the end of this, we're going to need to return and an instance of our jQuery library and pass in our accummlate. Very similar to what we just did. We're going to need to go through each element. Again, if we found many divs, we would wanna get the nextSibling for each element in our collection.
[00:06:22] We're gonna need to go through and we're gonna add things to our accumulator but only in the specific case. We want to check or we can say if elements is not a text node,
>> Alexis: Add to our accumulator.
>> Alexis: This is the basic set up for what we wanna do.
[00:06:55] Also, excuse me, if this is not a text node, just add it right then. We've hit the next div. We've hit the next li. This is what we care about. Throw in the accumulator and we can move on, however.
>> Alexis: If it is a text node, If element is a text node,
>> Alexis: Is there anyone who what we wanna do in the scenario? What if we have a div and some text and then another div? When we say the first div.next, we wanna get that last a div, how do we get there?
>> Alexis: Does anyone know? Anyone think of what we might wanna do?
[00:07:41] nextSibling will give us the text. So we really probably wanna do is call our element .nextSibling, .nextSibling, .nextSibling. Let's say forever until we get to that actual next node. But we can't do that directly. So we probably want to recurse to next,
>> Alexis: Node. We wanna keep moving down our nextSibling chain until we hit a node that is a DOM node.
>> Alexis: And there is one last case that we should handle, what if nothing is found? What if we're at the last element on the page or the last element in our parent and we say nextSibling. What should we return?
>> Alexis: In jQuery's case, it'll return an empty collection.
[00:08:47] So we should handle something like this, too. If no element Is found. If we recursed and we're at the end of our chain and nextSibling is null then,
>> Alexis: Return empty the clipboard. Just don't add any, rather, don't add anything, do nothing. Because we won't add anything to our accumulator in this case.
[00:09:12] And then our constructor will take care of our empty array because accumulator will be empty. Does this all makes sense,
>> Alexis: Without giving too much away?
>> Alexis: Okay, let's take, let's see.
>> Alexis: Let's take ten minutes. Yes, question?
>> Speaker 2: There's a couple things that were little bit reboard.
[00:09:44] Are we gonna go over DOM eventstoday?
>> Alexis: Yes, we are going over DOM events after right after this. There's gonna be a couple sections and elements we have to get through, traversal and then layout. And then we'll be touching DOM events towards the end of this. It will be a nice section for events.
[00:10:03] Events are very important, so we're not leaving that out.
[00:10:22] That's why we have call and apply being called different things, but you do have the concept. You're still creating an API. So the DOM is gonna give us its API that we're using internally here. And even though arguments could be anything. You can pass nothing to a function.
[00:10:38] You can pass a ton of arguments to a function that has nothing defined. So it's not signatures in the strict sense where it's like a strongly typed language where. If it requires two arguments, you have to give it two arguments. Not in that sense, but it is in the sense where you could do a function.length.
[00:10:56] I don't know if you guys have ever done this, like var foo equals function and you say foo.length. That's actually gonna give you the number of arguments that you have defined in that function. Which is kind of a nice little shortcut if you're trying to guarantee some length of arguments or optional arguments.