Digital humanities


Maintained by: David J. Birnbaum (djbpitt@gmail.com) [Creative Commons BY-NC-SA 3.0 Unported License] Last modified: 2015-12-01T01:02:22+0000


JavaScript exercise 2

Overview

For the second JavaScript assignment, instead of writing your own JavaScript, we’d like to ask you to examine some code that we have written and explain how it works. The HTML output, with functioning JavaScript, is at http://dh.obdurodon.org/javascript2.xhtml. What the JavaScript does is make certain words respond to mouse clicks; if you click on what looks like a link on the page, a popup appears, and you can click on the popup itself to make it disappear.

When we need to do something new in JavaScript, we often look around for examples that do something similar to what we need, and we then need to read and understand the code so that we can adapt it for our purposes. This assignment mimics that strategy, and your task is to answer the questions we ask below about specific features of our JavaScript code. Most of these will be new and unfamiliar, and to make your job easier, we’ve provided some suggestions about where to begin to look for the answers to our questions. Please write all of your answers in a text file and upload to CourseWeb when you’re done. In addition to the links we provide, should you find a good explanation elsewhere, please post about it to the discussion board.

Instructions

Answer all questions below (the challenge questions are optional) in a plain text file (not a word-processor file) and upload your answers to CourseWeb. You can create a plain text file in <oXygen/> (File > New > Text), don’t use a word processor because word processors may convert your straight quotes to curly ones or your hyphens to dashes, and they may introduce hyphenation, all of which can break your code.

HTML questions

Here is our HTML:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>JavaScript Exercise 2</title>
        <script type="text/javascript" src="javascript2.js">//
        </script>
        <link href="http://www.obdurodon.org/css/style.css" rel="stylesheet" type="text/css"/>
        <link rel="stylesheet" type="text/css" href="javascript2.css" />
    </head>
    <body>
        <h1>Big words, eh?</h1>
        <p class="note">Click on the underlined words to see their definitions. Click anywhere inside
            the popup to close the window.</p>
        <p>If you insist in your <span
            data-definition="causing or tending to cause annoyance, frustration, or worry"
            >vexatious</span>
            <span data-definition="the action of foretelling or prophesying future events"
                >prognostications</span> I will be forced to <span
                    data-definition="to cause to become flat or level, parallel to level ground"
                    >horizontalize</span> your <span
                        data-definition="maintaining a standing or upright position; standing up"
                        >perpendicularity</span>.</p>
    </body>
</html>

And here are the questions about the HTML:

  1. The attribute used to hold the text for the definition of each word is @data-definition, which is a new kind of attribute in HTML5. Read more about data attributes at the Mozilla Using data attributes page and explain why we can make up an attribute called @data-definition without rendering our HTML5 invalid, but we can’t make one up called @definition?
  2. Why can’t we use @id instead of @data-definition?
  3. Why can’t we use @class instead of @data-definition?

JavaScript questions

For ease of reference, here is a copy of our javascript2.js with numbered lines:

"use strict";

function init() {
    var spans = document.getElementsByTagName("span");
    for (var i = 0; i < spans.length; i++) {
        spans[i].addEventListener('click', popup, false);
    }
}

function popup(e) {
    if (! this.id) {
        var overlay = document.createElement("div");
        var XMousePos = e.clientX;
        var Ypos = e.clientY + 20;
        var windowWidth = window.innerWidth;
        if (windowWidth - XMousePos > 300) {
            var Xpos = XMousePos;
        } else {
            var Xpos = windowWidth - 330;
        };
        var random = "n" + Math.random();
        
        this.id = random;
        overlay.innerHTML = this.dataset.definition;
        overlay.style.backgroundColor = "pink";
        overlay.style.position = "absolute";
        overlay.style.left = Xpos + "px";
        overlay.style.top = Ypos + "px";
        overlay.style.border = "1px solid black";
        overlay.style.width = "300px";
        overlay.style.margin = "0";
        overlay.style.padding = ".5em";
        overlay.dataset.pointer = random;
        overlay.addEventListener('click', destroy, false);
        document.body.appendChild(overlay);
    }
}

function destroy() {
    var span = document.getElementById(this.dataset.pointer);
    span.removeAttribute("id");
    document.body.removeChild(this);
}

window.onload = init;

Strict mode and initialization

  1. The first line of the JavaScript file contains a "use strict"; directive, which is designed to help developers write more robust JavaScript. Read about this directive on the Mozilla Strict mode page and tell us:

    1. Where can a "use strict"; directive go in a JavaScript file? Where can’t it go?
    2. What are some of the benefits of including the "use strict"; directive in your script? Are there disadvantages?
  2. Explain the connection between the last line in the JavaScript file, which reads

    window.onload = init; 

    and the init() function on lines 3–8.

  3. The function init() on lines 3–8 should look familiar to you after reading our JavaScript piece by piece tutorial. On line 4 we create a variable called spans that is used to refer to all of the <span> elements in the HTML document. Lines 5–7 constitute a loop that will apply the same code to each <span> element in our spans variable.

    1. What does each part of the (var i = 0; i < spans.length; i++) in line 5 do?
    2. How does .addEventListener() in line 6 work?

The popup() function

The function popup() on lines 10–37 is responsible for creating and styling the popup windows that appear when a user clicks on one of the underlined words. The argument e in the function definition on line 10 is a JavaScript idiom for referring to the event that triggered the function. The following questions are about specific features of the popup() function.

  1. Line 11 is an if statement with the condition (! this.id); note that in JavaScript conditionals, the condition being tested has to be wrapped in parentheses. Read about the JavaScript bang operator (the term bang is geek-speak for the exclamation mark character; in this use it is also called logical not operator) at jsforallof.us and explain what it is that we’re testing, and how the test works.

  2. Why have we wrapped everything inside the popup() function definition inside this if statement? What is the effect of the if statement, and how would the program operate differently if it weren’t there? (Hint: you can remove it to experiment, but if you do, you have to remove both the if statement on line 11 and the matching closing curly brace on line 36.)

  3. What is the relationship among lines 12, 24, and 35? You can read about the relationship between the .createElement() and .appendChild() methods at the SitePoint createElement (W3C DOM Core method) page and W3Schools HTML DOM appendChild() Method page, and you can read about accessing data attributes with JavaScript at the Mozilla Using data attributes page. Explain how the .appendChild() method (line 35) works and how the value of @data-definition gets inserted into the <div> (line 24).

  4. You can read about random number generation in Javascript at the W3Schools JavaScript random() Method page. What is the connection between line 23 and line 33 and what do we do with our random variable? For this question in particular you might want to open the JavaScript developer tools in your browser window, expand the elements so that you can see the entire HTML source, and watch what happens when you click on each of the clickable defined words in the main browser display.

The destroy() function

  1. Explain each line of code inside the destroy() function on lines 39-43.
  2. How does line 34 enable the destroy() function to do its work when needed?

Challenge questions

  1. Read about the window.load event at load and about window.DOMContentLoaded at DOMContentLoaded. In line 45 we bootstrap our JavaScript with:

    window.onload = init;

    How is that different from the code we used in earlier examples, which would be:

    window.addEventListener('load',init,false)

    or:

    window.addEventListener('DOMContentLoaded',init,false)
  2. We could have used the HTML @title attribute to create a tool tip (popup) to hold our definition text, and had we done that, we wouldn’t have had to write any JavaScript. Read about the HTML @title attribute at the W3schools HTML title Attribute page and explain how it creates popups without requiring JavaScript. What are the limitations that constrain the HTML @title attribute, and that might therefore persuade us to use JavaScript instead?
  3. In order to make sure that each popup window is linked to the correct word, our script creates matching @id values inside the <span> element and @data-pointer values inside the <div> element each time a word is clicked. We do this by generating a random number with the method Math.random() on line 21, information on which can be found on the W3Schools JavaScript random() Method page. The code on line 21 looks like:

    var random = "n" + Math.random();
    1. What is the plus sign doing here? (Hint: it isn’t arithmetic. Other hint: it does the same thing in lines 27 and 28.)
    2. Why is there an n before our call to the random number method? We know that @id values must be unique within the document, but the random number generator does that for us. Why do we need to include the n? Insights can be found at the SitePoint id (HTML attribute) page.
  4. Line 35 makes the popup visible by inserting it into the DOM, the internal tree model of the document that the browser constructs. Where in the DOM does it appear and why?