Animation and Keyboard Events¶
This reading covers two separate things: animation and keyboard events.
Animation can be done with the jQuery
.animate method, which is one place
that jQuery exceeds raw JavaScript. (That's not literally true, since
jQuery is implemented in raw JavaScript, but with animate
, the added
value is enormous.)
Keyboard events are another useful way to react to user input; this time, not by clicking the mouse, but by using the keyboard.
Keyboard Events¶
There are three keyboard events that you might potentially be interested in:
keydown
keyup
keypress
The first two are events tied to the physical key going up and down
(e.g. the shift key). The last is only for real characters, not
modifiers like shift or control. The keypress
event is officially
deprecated
in favor of device-independent events, but it's likely to be supported
for a long time. (deprecated
is jargon in the computer science
community meaning that, even though a feature exists, you should not
use it.)
We will use keyup
.
The event listener is invoked with an event object, and that object
will contain a code
property that is the number of that key on the
keyboard. For more detail, see
KeyboardEvent.code
Note that the code
for a key is not the same as the code for a
character. So, for example, the "a" key has the same code
whether the
"shift" key is up or down. If you care about "a" versus "A"; you want the
key
property instead. See
KeyboardEvent.key
To add a keyup
event handler using jQuery, we can do the following:
$(document).on('keyup', function (eventObj) {
console.log(eventObj.code);
}
Note. The .code
property was added to jQuery in version 3, so
when you load jQuery, use something like this:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
Doing that ensures that the jQuery event object includes the ".code" property. If you copy the template-jq file, you'll get version 3 of jQuery.
In particular, I've added the following keyup
handler to this page,
so you can open the JS console, type a few keys, and see the
results. Try WASD, since you'll use those keys in the assignment. You
can also try the four arrow keys. The event handler prints three
properties of the jQuery event object: code
, key
and which
. The
last is something that jQuery created to be consistent across all
browsers. Open the JS console and try some keys, including shift keys,
control keys, arrow keys and regular character keys (a-z).
Note that when you first open the JS console, keystrokes go to the console (understandably), so you need to click on the browser window in order to focus that window and get the event handler to work.
$(document).on('keyup', function (eventObj) {
eventObj.preventDefault();
eventObj.stopPropagation();
console.log('code:', eventObj.code,
'key:',eventObj.key,
'which:', eventObj.which);
});
You've probably also noticed that the keyup event handler is added to
document
, rather than to some particular element. That's standard
practice.
You can ignore the stopPropagation()
method for now; we will talk
about it later in the course.
jQuery Animations¶
jQuery provides an easy way to do animations that is compatible with older browsers, since the animations are done by jQuery. You can read the details here: jQuery animate() method (optional).
The animate
method is very easy to use, but first let's see it in
action. Try clicking on the following box. You can click it again (and
again) to re-run the animation.
Essentially, the animation effect is to successively (frame by frame)
change the height
and font-size
CSS properties from their initial
values (height:50px
and font-size:10px
) to their final values
(height:200px
and font-size:20px
).
So, let's see how the JQ code does that. Here's the complete code; we'll break it down afterward.
$("#box1")
.one()
.click(function () {
$("#box1")
.one()
.css({height: "50px", "font-size": "10px"})
.animate({height: "200px", "font-size": "20px"},
2000);
});
Now let's break that down. The click handler is the following function:
function () {
$("#box1")
.one()
.css({height: "50px", "font-size": "10px"})
.animate({height: "200px", "font-size": "20px"},
2000);
}
Almost all of it is a sequence of two operations on the element
#box1
, the .css()
method and the .animate()
method.
The first operation is to reset two CSS property-value pairs to some
initial values. This happens instantly. (Not that it takes zero
time, but the effect is not stretched over time like an animation is.)
The argument to the .css
method is a JS object literal that is a
collection of CSS property-value pairs.
.css({height: "50px", "font-size": "10px"})
(The font-size
property has to be in quotation marks because it has
a hyphen in the name of the property. The quotation marks are optional
for height
, because it works as a JS identifier, but I could have
used them.)
The second operation, namely the .animate()
method, is to
gradually change those values to their final values. The gradual
changes take 2000 milliseconds (2 seconds). That uses the JQ
.animate
method. The .animate()
method's first argument is a JS
object literal that contains a collection of target CSS values, just
like the .css()
method. The second argument says how many
milliseconds it should take to achieve that change.
.animate({height: "200px", "font-size": "20px"},
2000);
Note that I could have specified the initial CSS using CSS style rules
instead of JQ's .css()
method, but I like using the same medium for
specifying both the starting and ending values. It also makes it easy to
re-run the animation as many times as you want.
Animate and CSS¶
I want to emphasize that it is not necessary to precede the
.animate()
method with the .css()
method. I did that for the demo
above so that you can re-run it as many times as you want, with just a
single button. We could instead separate things and have two buttons:
Here's the HTML for the second demo:
<div id="box2" class="box">Turned glorious summer...</div>
<button id="run2">run animation</button>
<button id="reset2">reset</button>
and the CSS:
.box {
border: 1px solid blue;
background-color: #ccccff;
width: 30%;
height: 50px;
font-size: 10px;
}
and the JS:
$("#run2")
.one()
.click( () => $("#box2").one().animate({height: "200px", "font-size": "20px"}, 2000));
$("#reset2")
.one()
.click( () => $("#box2").one().css({height: "50px", "font-size": "10px"}));
What Can be Animated¶
Note that we animated height
and font-size
, both of which are
measured by single numbers. Any CSS property that can be measured by a
single number ("linear" properties) is easy to animate using jQuery.
Other properties cannot be easily animated. For example, how would you animate a solid line turning into a dotted line? How about Times New Roman turning into Verdana? What about purple turning into green? While it's possible that you can come up with an algorithm (and some people have), those kinds of properties can't be animated in jQuery without additional code.
Modifying a Value¶
In JavaScript, Python and most modern languages, there is an update assignment operator that allows you to modify a variable up or down by some amount. For example, in JavaScript:
x += 200; // increase by 200
y -= 100; // decrease by 100
By analogy, jQuery's animate
method allows you to increase or
decrease a linear property by some amount. (That gives us a different
way to specify the target value, or the amount of change.) The above
example increased the width from 50px to 200px, an increase of
150px. Similarly, it increased the font size from 10px to 20px, an
increase of 10px. The following code using +=
is equivalent (there's
also a -=
operator). Note that the "value" is a string that includes
the operator as well as the amount.
$("#box2")
.one()
.click(function () {
$("#box2")
.one()
.css({height: "50px", "font-size": "10px"})
.animate({height: "+=150px", "font-size": "+=10px"},
2000);
});
Here it is in action:
This is a useful trick in several assignments.