-
Notifications
You must be signed in to change notification settings - Fork 35
/
05-javascript.html
155 lines (153 loc) · 10.8 KB
/
05-javascript.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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<title>Software Carpentry: JavaScript</title>
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap-theme.css" />
<link rel="stylesheet" type="text/css" href="css/swc.css" />
<link rel="alternate" type="application/rss+xml" title="Software Carpentry Blog" href="http://software-carpentry.org/feed.xml"/>
<meta charset="UTF-8" />
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body class="lesson">
<div class="container card">
<div class="banner">
<a href="http://software-carpentry.org" title="Software Carpentry">
<img alt="Software Carpentry banner" src="img/software-carpentry-banner.png" />
</a>
</div>
<div class="row">
<div class="col-md-10 col-md-offset-1">
<h1 class="title">JavaScript</h1>
<h2 class="subtitle">Feeding a cat</h2>
<div id="learning-objectives" class="objectives panel panel-warning">
<div class="panel-heading">
<h2><span class="glyphicon glyphicon-certificate"></span>Learning Objectives</h2>
</div>
<div class="panel-body">
<ul>
<li>Linking to a JavaScript file</li>
<li>Passing HTML element tags to JavaScript</li>
<li>Manipulating HTML elements using JavaScript</li>
</ul>
</div>
</div>
<p>We've learned how to integrate text and graphical objects into our page and we also know how to publish it. So far, we might as well just create a plot elsewhere and publish it as an image. But wouldn't it be much better, if the user could interact with the data? To do that, we need to learn a little scripting, and, again, HTML provides a scripting environment. Everything between <script> and </script> within the body will be interpreted as JavaScript code. Since the code we write in the HTML file is executed sequentially, we need to make sure that whenever we refer to an element on the page, this element already exists. An easy way to ensure this is to include scripts just before the end of the body element. Just like we did with styles, we can outsource our code into a separate file with the extension <code>.js</code>.</p>
<p>So, let's go back to using the cat image for now. We want the cat to acknowledge that we click on it. First we need to create our <code>interaction.js</code> file and link to it in the HTML body.</p>
<pre class="sourceCode html"><code class="sourceCode html"><span class="kw"><script</span><span class="ot"> src=</span><span class="st">"interaction.js"</span><span class="kw">></script></span></code></pre>
<p>We need to introduce the script to the HTML element, using these basic steps:</p>
<ul>
<li>Set up a link between HTML and the script by giving the HTML element we want to interact with a unique ID.</li>
<li>Retrieving the element and assigning it to a variable in the script that we can work with.</li>
<li>Detect the action we are interested in, i.e. button click using an event listener.</li>
<li>Do things.</li>
</ul>
<p>The ID is an attribute we can set for the image:</p>
<pre class="sourceCode html"><code class="sourceCode html"><span class="kw"><div</span><span class="ot"> class=</span><span class="st">'image'</span><span class="kw">></span>
<span class="kw"><img</span><span class="ot"> id=</span><span class="st">"cat"</span><span class="ot"> src=</span><span class="st">"img/cat.jpg"</span><span class="kw">></span>
<span class="kw"></div></span></code></pre>
<p>Using <code>getElementById</code>, we can grab the element from <code>document</code> (a magical object representing the entire page) and work with it in the JavaScript file.</p>
<pre class="js"><code>var cat_image = document.getElementById('cat');</code></pre>
<p>Now we want to detect if someone clicks on the cat image. Event listeners help us by constantly checking if someone performs a certain action.</p>
<pre class="js"><code>var cat_image = document.getElementById('cat');
cat_image.addEventListener("click", meow);</code></pre>
<p>Our event listener takes two arguments: the type of event and what we want it to do. We want to execute a function called <code>meow()</code>, which will open a pop-up window. We can use the JavaScript function alert().</p>
<pre class="js"><code>function meow() {
alert("Meow!");
};</code></pre>
<p>If we want to execute a sequence of functions, we can also create something that's called <code>inline</code> function, that is only defined in the scope of this specific callback. Within this function, we can call <code>meow()</code>, but also othe functions, like <code>purr()</code> (which doesn't exist, yet).</p>
<pre class="js"><code>var cat_image = document.getElementById('cat');
cat_image.addEventListener("click", function() {
meow();
purr();
});</code></pre>
<p>Obviously, we can also drop the <code>meow()</code> function, if we don't want to use it ever again:</p>
<pre class="js"><code>var cat_image = document.getElementById('cat');
cat_image.addEventListener("click", function() {
alert("Meow!");
purr();
});</code></pre>
<div id="debugging-in-a-browser" class="callout panel panel-info">
<div class="panel-heading">
<h2><span class="glyphicon glyphicon-pushpin"></span>Debugging in a browser</h2>
</div>
<div class="panel-body">
<p>If we right click anywhere on our page and select "Inspect Element", the browser takes us to the developer tools. Here, we have different tabs. The three most important ones are:</p>
<ul>
<li>Console - The console alerts us to things going wrong in out code by showing us an error and telling us in what line the error ocurred. We can also display the values of variables by including <code>colsole.log(x)</code> in our code.</li>
<li>Elements - If we want to know if our HTML elements are all in the right spot, this is where we need to look. Hovering over any part of the page will highlight the according element and we can look at how they are styled and temporarily change attributes.</li>
<li>Sources - Here, we can look at the files that are used by our page. And even better, if we navigate to the JavaScript file, we can add breakpoints that stay in place when we reload the page. This allows us to investigate values of variables on the spot.</li>
</ul>
</div>
</div>
<div id="feed-your-pet-cat" class="challenge panel panel-success">
<div class="panel-heading">
<h2><span class="glyphicon glyphicon-pencil"></span>Feed your pet cat</h2>
</div>
<div class="panel-body">
<p>Create a button using the <button> element to feed the cat using the steps outlined earlier. Use the alert() function to have the cat thank you.</p>
</div>
</div>
<p>The next step to having a fully interactive page is to change HTML elements using JavaScript. We've created a button in the HTML file and are calling a function when it is clicked. The goal now is to make the cat put on a little bit of weight when we feed it. We have to link to both the cat element and the food button so that both files know what we're talking about.</p>
<p>We're setting the width by stringing a few words together: 'cat_image.style.width'. We can think of 'cat_image' as having an attribute called 'style', which in turn has an attribute called 'width'. Let's add a couple of grams. We have to retrieve the current object width. Our 'cat_image' object also has a attribute called 'offsetWidth'. This will give us the current width as a number (as opposed to the string '200px'). Google is your friend here. Use it to find out these handy functions. Lastly we have to append the new value with 'px'.</p>
<pre class="js"><code>var cat_image = document.getElementById('cat');
var feed_button = document.getElementById('feed_button');
feed_button.addEventListener("click", feed);
function feed() {
cat_image.style.width = (cat_image.offsetWidth + 30.0) + 'px';
};</code></pre>
<p>We could also pass an argument into the <code>feed</code> function by writing it in the brackets. We might, for example, want the user to be able to decide the meal size the cat eats.</p>
<p>We can also return a value and assign it to a variable (just like we do with any function we used so far, e.g. var element = document.getElementById("someID");):</p>
<pre class="js"><code>var new_width = feed(10);
function feed(mealsize) {
cat_image.style.width = (cat_image.offsetWidth + parseInt(mealsize)) + 'px';
return cat_image.style.width;
};</code></pre>
<p>In JavaScript there are two main data types: strings (text, everything in quotes) and numbers. It's important to remember that you can't do maths with strings or append numbers together.</p>
<p>For example: <code>5+5 = 10</code> but <code>'5'+'5' = '55'</code></p>
<p>If one of the arguments is a string, the other one gets converted, too: <code>5 + '5' = '55'</code></p>
<p>We've also just used that, when we concatenated <code>(cat_image.offsetWidth + 30.0) + 'px'</code>.</p>
<div id="other-event-listeners-that-might-come-in-handy" class="callout panel panel-info">
<div class="panel-heading">
<h2><span class="glyphicon glyphicon-pushpin"></span>Other event listeners, that might come in handy</h2>
</div>
<div class="panel-body">
<ul>
<li>dblclick - Double click</li>
<li>contextmenu - Right click</li>
<li>mouseover - Mouse moved over an element</li>
<li>keypress - Key pressed on keyboard</li>
</ul>
</div>
</div>
<div id="let-the-cat-work-out" class="challenge panel panel-success">
<div class="panel-heading">
<h2><span class="glyphicon glyphicon-pencil"></span>Let the cat work out</h2>
</div>
<div class="panel-body">
<p>Create a second button 'run around the block', that makes the cat slimmer again.</p>
</div>
</div>
<p>By the end of this lesson, your page should look something like this:</p>
<iframe src="code/meow.html" width="1000" height="250"></iframe>
</div>
</div>
<div class="footer">
<a class="label swc-blue-bg" href="http://software-carpentry.org">Software Carpentry</a>
<a class="label swc-blue-bg" href="https://github.com/swcarpentry/lesson-template">Source</a>
<a class="label swc-blue-bg" href="mailto:[email protected]">Contact</a>
<a class="label swc-blue-bg" href="LICENSE.html">License</a>
</div>
</div>
<!-- Javascript placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="css/bootstrap/bootstrap-js/bootstrap.js"></script>
</body>
</html>