-
Notifications
You must be signed in to change notification settings - Fork 0
/
14_dom.html
163 lines (135 loc) · 5.18 KB
/
14_dom.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<!-- BUILD A TABLE
An HTML table is built with the following tag structure -->
<table>
<tr>
<th>name</th>
<th>height</th>
<th>place</th>
</tr>
<tr>
<td>Kilimanjaro</td>
<td>5895</td>
<td>Tanzania</td>
</tr>
</table>
<!--
For each row, the <table> tag contains a <tr> tag. Inside of these <tr> tags, we
can put cell elements: either heading cells (<th>) or regular cells (<td>).
Given a data set of mountains, an array of objects with name, height, and place
properties, generate the DOM structure for a table that enumerates the
objects. It should have one column per key and one row per object, plus a header
row with <th> elements at the top, listing the column names.
Write this so that the columns are automatically derived from the objects, by
taking the property names of the first object in the data.
Add the resulting table to the element with an id attribute of "mountains" so
that it becomes visible in the document.
Once you have this working, right-align cells that contain number values by
setting their style.textAlign property to "right".
-->
<h1>Mountains</h1>
<div id="mountains"></div>
<script>
const MOUNTAINS = [
{name: "Kilimanjaro", height: 5895, place: "Tanzania"},
{name: "Everest", height: 8848, place: "Nepal"},
{name: "Mount Fuji", height: 3776, place: "Japan"},
{name: "Vaalserberg", height: 323, place: "Netherlands"},
{name: "Denali", height: 6168, place: "United States"},
{name: "Popocatepetl", height: 5465, place: "Mexico"},
{name: "Mont Blanc", height: 4808, place: "Italy/France"}
];
// Your code here
let table = document.createElement('table');
// head row
let head = document.createElement('tr');
for (let key of Object.keys(MOUNTAINS[0])) {
let headname = document.createElement('th');
let data = document.createTextNode(key);
headname.appendChild(data);
head.appendChild(headname);
}
table.appendChild(head)
// data rows
MOUNTAINS.forEach((obj) => {
let row = document.createElement('tr');
for (let prop in obj) {
let el = document.createElement('td');
let text = document.createTextNode(obj[prop]);
if (! isNaN(obj[prop]) )
el.style.textAlign = "right";
el.appendChild(text);
row.appendChild(el);
}
table.appendChild(row);
});
let mountainsDiv = document.getElementById('mountains');
mountainsDiv.appendChild(table);
</script>
<!-- Elements by tag name -->
<!-- The document.getElementsByTagName method returns all child elements with a
given tag name. Implement your own version of this as a function that takes a
node and a string (the tag name) as arguments and returns an array containing
all descendant element nodes with the given tag name. -->
<!-- To find the tag name of an element, use its nodeName property. But note
that this will return the tag name in all uppercase. Use the toLowerCase or
toUpperCase string methods to compensate for this. -->
<h1>Heading with a <span>span</span> element.</h1>
<p>A paragraph with <span>one</span>, <span>two</span>
spans.</p>
<script>
function byTagName(node, tagName) {
// Your code here.
let result = [];
function loop(node, tagName) {
if (node.nodeType === Node.ELEMENT_NODE) {
for (let i = 0; i < node.childNodes.length; i++) {
if (node.childNodes[i].nodeName === tagName.toUpperCase()) {
result.push(node.childNodes[i]);
}
loop(node.childNodes[i], tagName.toUpperCase());
}
}
}
loop(node, tagName);
return result;
}
console.log(byTagName(document.body, "h1").length);
// → 1
console.log(byTagName(document.body, "span").length);
// → 3
let para = document.querySelector("p");
console.log(byTagName(para, "span").length);
// → 2
</script>
<!-- THE CAT’S HAT
<!-- Extend the cat animation defined earlier so that both -->
<!-- the cat and his hat (<img src="img/hat.png">) orbit at opposite sides -->
<!-- of the ellipse. -->
<!-- Or make the hat circle around the cat. Or alter the animation in some -->
<!-- other interesting way. -->
<!-- To make positioning multiple objects easier, it is probably a good -->
<!-- idea to switch to absolute positioning. This means that top and left -->
<!-- are counted relative to the top left of the document. To avoid using -->
<!-- negative coordinates, which would cause the image to move outside of -->
<!-- the visible page, you can add a fixed number of pixels to the position -->
<!-- values. -->
<style>body { min-height: 200px }</style>
<img src="img/cat.png" id="cat" style="position: absolute">
<img src="img/hat.png" id="hat" style="position: absolute">
<script>
let cat = document.querySelector("#cat");
let hat = document.querySelector("#hat");
let angle = 0;
let lastTime = null;
function animate(time) {
if (lastTime != null) angle += (time - lastTime) * 0.001;
lastTime = time;
cat.style.top = (Math.sin(angle) * 40 + 40) + "px";
cat.style.left = (Math.cos(angle) * 200 + 230) + "px";
// Your extensions here.
hat.style.top = (Math.sin(angle + Math.PI) * 40 + 40) + "px";
hat.style.left = (Math.cos(angle + Math.PI) * 200 + 230) + "px";
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
</script>