1
00:00:02,230 --> 00:00:04,590
I want to start with innerHTML

2
00:00:04,660 --> 00:00:11,260
and for that, let's select this section again and let's say we want to entirely change its content.

3
00:00:11,320 --> 00:00:16,480
So for this, we can use this section element which you already have selected here,

4
00:00:16,480 --> 00:00:22,540
so I do already select section here and store it in a constant in my app.js file, this is also available

5
00:00:22,540 --> 00:00:25,670
here in this console as you can see if I type section here,

6
00:00:25,840 --> 00:00:33,460
that's the section element and there, as on every element node, you have an innerHTML property.

7
00:00:33,970 --> 00:00:38,540
You saw text content before which in the end gives you access to all text in there,

8
00:00:38,560 --> 00:00:43,030
by the way that might be interesting, you see this is all the text of all the list items,

9
00:00:43,030 --> 00:00:52,090
so not just direct child text but any nested text and you can also set new text content here, like this

10
00:00:52,150 --> 00:00:55,990
which by the way will also replace any existing HTML content in there

11
00:00:55,990 --> 00:01:00,970
if you now inspect this, so that's also interesting to see. Text content can also be used to set new

12
00:01:00,970 --> 00:01:07,540
content but only text content, if you want to set new elements and so on, you use innerHTML and now

13
00:01:07,540 --> 00:01:13,690
you can reset this equal to a string that contains HTML code, like for example a h2 tag, a new

14
00:01:13,690 --> 00:01:19,800
title and important here is that this works as you can tell,

15
00:01:19,810 --> 00:01:26,560
now we have this h2 element in there but it will always replace all the old HTML content, so any

16
00:01:26,560 --> 00:01:35,560
previous nodes between the section tags and not just direct child nodes but any descendants will be entirely

17
00:01:35,560 --> 00:01:38,170
replaced with this new HTML code.

18
00:01:38,320 --> 00:01:45,160
So that's what innerHTML does, it really just swaps the entire nested HTML structure, all nested

19
00:01:45,160 --> 00:01:47,630
nodes with your new content.

20
00:01:47,710 --> 00:01:53,530
Sometimes that is exactly what you need and want, then this is great but sometimes you just want to add

21
00:01:53,590 --> 00:02:00,460
a single new element and keep the old content and then innerHTML is not that great.

22
00:02:00,670 --> 00:02:05,830
Now one workaround you might come up with is that you append content to innerHTML.

23
00:02:06,160 --> 00:02:13,270
Let's say here we select the unordered list and store it in a list constant with query selector ul and

24
00:02:13,270 --> 00:02:20,320
now I want to keep my existing list elements, so all existing three list elements and just add a new one.

25
00:02:20,320 --> 00:02:29,770
Now you could do that by setting list innerHTML equal to and now list.innerHTML plus

26
00:02:29,790 --> 00:02:34,750
and now a new content, right?

27
00:02:34,760 --> 00:02:39,740
So now I add a string with a new list item here where I say item four.

28
00:02:39,860 --> 00:02:45,050
This should in the end take the existing innerHTML content which is that structure we already

29
00:02:45,050 --> 00:02:48,160
have here and just add a new list item at the end

30
00:02:48,160 --> 00:02:53,930
that should be rendered. If we hit enter, this indeed works, the other three items are there and the new

31
00:02:53,930 --> 00:02:54,940
one was added

32
00:02:54,980 --> 00:02:57,920
but this approach has a major downside,

33
00:02:57,920 --> 00:03:03,260
it becomes clear if we go to elements here and open my console here.

34
00:03:03,260 --> 00:03:08,040
Now here I'll just repeat that code here just with item 5.

35
00:03:08,180 --> 00:03:16,240
Now don't watch the console, also don't watch the part on the left, instead let's now watch this unordered

36
00:03:16,240 --> 00:03:19,870
list here in this tree structure here in the elements tab

37
00:03:19,960 --> 00:03:27,330
as I hit enter. Did you see that? It all flashed and this indicates that's how the chrome dev tools behave,

38
00:03:27,600 --> 00:03:33,410
that all the items that flashed indeed changed and were kind of re-rendered.

39
00:03:33,450 --> 00:03:39,060
So what happened here in the end is when we do that, we replace the entire HTML the content of the unordered

40
00:03:39,060 --> 00:03:45,300
list with brand new content which yes is based on the old one but still everything gets re-rendered.

41
00:03:45,360 --> 00:03:47,490
This has two important implications,

42
00:03:47,490 --> 00:03:50,450
for one it's not great for performance.

43
00:03:50,490 --> 00:03:57,600
You are forcing the browser to re-parse and re-render a lot of HTML which didn't change at all.

44
00:03:57,600 --> 00:04:01,850
Now of course for a short list on a simple page like this one, it doesn't really matter

45
00:04:01,980 --> 00:04:08,040
but if you're working with bigger web sites, bigger applications, that might be super bad and really hurt

46
00:04:08,070 --> 00:04:10,160
the user experience.

47
00:04:10,170 --> 00:04:16,940
Now in addition if you would do this to some other element, let's say this input and I can even show

48
00:04:16,940 --> 00:04:23,850
this, then you'll face a totally different problem because let's say here in our index.html file, that

49
00:04:23,850 --> 00:04:27,210
input would be inside of a div.

50
00:04:27,210 --> 00:04:33,670
So I added a simple div, the only div I have on this page and I move my input in there.

51
00:04:33,750 --> 00:04:42,400
So of course I can now get access to that div here if I reload by using document query selector div

52
00:04:43,390 --> 00:04:47,710
and then let's say for some reason I want to change its content, so I reach out to innerHTML and

53
00:04:47,710 --> 00:04:55,480
I set this equal to div.innerHTML plus let's say a paragraph which I want to add below it.

54
00:04:55,480 --> 00:05:00,280
Something went wrong because the user entered something incorrect into the input let's say and you want

55
00:05:00,280 --> 00:05:01,360
to tell the user,

56
00:05:01,480 --> 00:05:01,720
right?

57
00:05:01,780 --> 00:05:05,670
So we're rendering this paragraph and we're keeping all the original content,

58
00:05:05,680 --> 00:05:07,170
we don't change this.

59
00:05:07,330 --> 00:05:15,340
Now let's say I entered something here into the input, so I changed a text and now I execute this command.

60
00:05:15,340 --> 00:05:17,680
Now what you'll see is that my input is lost

61
00:05:17,830 --> 00:05:22,850
and the reason for that is that as I just explained, all the content which you swapped with innerHTML

62
00:05:22,900 --> 00:05:29,100
is re-rendered, even if it's based on old content. A brand new element is rendered here and therefore

63
00:05:29,220 --> 00:05:30,820
the user input is lost,

64
00:05:30,820 --> 00:05:33,330
so that's the other downside of using that.

65
00:05:33,370 --> 00:05:40,690
So innerHTML is useful whenever you want to change everything, all the HTML content of an element,

66
00:05:41,200 --> 00:05:42,440
it's not so good

67
00:05:42,550 --> 00:05:48,510
if you only want to add something to the existing content, that's one thing to keep in mind. Therefore

68
00:05:48,550 --> 00:05:56,920
a better way of updating this, to keep the user input here which I just typed would be to use div insert

69
00:05:57,010 --> 00:05:58,800
adjacent HTML,

70
00:05:59,770 --> 00:06:07,540
this allows you to target a position and then define which HTML you want to enter. For that as so often,

71
00:06:07,540 --> 00:06:15,100
it's good to Google for js insert adjacent HTML and find the respective MDN article and there

72
00:06:15,100 --> 00:06:21,400
you find the different values for position where this should be inserted, before the element, just inside

73
00:06:21,430 --> 00:06:27,640
before the first child, at the end of the element just after the last child or after the element itself

74
00:06:27,640 --> 00:06:31,810
and here you also see a visual representation of where stuff is entered.

75
00:06:31,840 --> 00:06:36,710
So we basically have four values - before begin, after begin, before end and after end

76
00:06:36,940 --> 00:06:42,100
and hence here, we could say before end,

77
00:06:42,120 --> 00:06:46,550
so inside of the element, inside of the div but after its last child,

78
00:06:46,560 --> 00:06:51,730
so after the input in this case, I want to enter this paragraph,

79
00:06:51,840 --> 00:06:54,540
something went wrong.

80
00:06:54,630 --> 00:07:01,230
So now the same HTML code as before but inserted with insert adjacent HTML. The result is

81
00:07:01,230 --> 00:07:02,580
if I now it enter,

82
00:07:02,580 --> 00:07:04,260
this is kept and not reset,

83
00:07:04,260 --> 00:07:08,850
instead we just added this new paragraph, in this case after the last paragraph which I entered with

84
00:07:08,850 --> 00:07:14,510
this code here and now this does not re-render everything but really just insert this code and render

85
00:07:14,510 --> 00:07:15,510
this new code

86
00:07:15,630 --> 00:07:22,020
since you explicitly tell Javascript and the browser that this should be added next to the existing

87
00:07:22,020 --> 00:07:22,590
content.

88
00:07:23,160 --> 00:07:30,570
So this is one way of adding new content to an existing element with some HTML code which you write

89
00:07:30,630 --> 00:07:34,520
in Javascript and this is therefore a great way of manipulating this.

90
00:07:34,560 --> 00:07:40,930
Still whilst this might seem perfect, there are scenarios where you don't want to do it like this.
