3-1 Background

Document tree and DOM

When a web browser loads an HTML page from a web server, it converts the HTML code into a tree data structure known as document tree. All user interactions in the client-side of a web app are done through this DOM tree.

The Document Object Model standard (online ref) defines a programming interface to access the document tree. Each HTML element is represented by a node in the tree. DOM defines the properties, methods and events for these nodes, and the nodes are accessible to JavaScript as objects. In summary, DOM defines how JavaScript code can access and manipulate nodes in a document tree.

The example p300-a.html shows some common tasks in a web app. In this app, the user enters two numbers in text input boxes, presses a button to calculate the sum, and displays the result inside the web page.

  • document tree in JavaScript: document
  • search a node using id of the element: let numA = document.getElementById('numA')
  • each element is an object (with properties and methods)
  • change a property of the node object: ans.innerText = 'something'
<!doctype html>
<html>
<head>
  <title>First example</title>
</head>
<body>
  <div id="app">
    <p>This example adds two numbers.</p>
    <p>a: <input type="text" id="numA" value='3' /></p>
    <p>b: <input type="text" id="numB" value='5' /></p>
    <p><button type='button' id="btnAdd">Calculate!</button></p>
    <p>a+b = <span id="ans"></span></p>
  </div>
  
  <!-- embedded JavaScript program -->
  <script>
  const numA = document.getElementById('numA');
  const numB = document.getElementById('numB');
  const ans = document.getElementById('ans');
  const btnAdd = document.getElementById('btnAdd');
  
  btnAdd.addEventListener('click', function() {
    ans.innerHTML = parseFloat(numA.value) + parseFloat(numB.value)
  });
  </script>
</body>
</html>

MVVM and Vue

The above example demonstrates document tree manipulation, a common style of programming during the early day of client-side programming. When some data changes, the program has to update different parts of the document tree. The programmer has to keep track of which parts of the document tree are affected by which piece of data.

Although it can be facilitated with some higher level JavaScript library like jQuery, document tree manipulation does not scale well when web applications and their user interface become more complicated. In order to handle such complexity, web developers have adopted another approach known as MVVM (Model-view-viewmodel). Several popular JavaScript framework (e.g. React, AngularJS and Vue) implement MVVM (or a similar framework).

In this chapter, we’ll use Vue.js to illustrate the MVVM approach in client-side programming. The following example p300-b.html is a rewrite of p300-a.html using Vue.

  <div id="app">
    <p>This example adds two numbers.</p>
    <p>a: <input type="text" v-model.number="a" /></p>
    <p>b: <input type="text" v-model.number="b" /></p>
    <p><button type='button' @click="ans=a+b" >Calculate!</button></p>
    <p>a+b = <span id="ans">{{ ans }}</span></p>
  </div>

  <!-- loading the Vue v3.2 JavaScript library from CDN -->    
  <script src="https://unpkg.com/vue@3.2"></script>
  <script>
  const options = { 
    data() { 
      return { a: 3, b: 5, ans:3+5 }
    }
  };
  const vm = Vue.createApp(options).mount('#app');
  </script> 

This example shows some differences in the Vue.js application:

  • define a view model (the return value of data()), which is a JavaScript data structure that encapsulates the state of the current view in the web interface
  • write a template to render the data in html (the HTML code at #app). Usually a html template contains placeholders that bind to some data property. When a data property changes value, Vue updates the view efficiently.

A note on loading JavaScript code

We use the following HTML code to load the Vue library (which is a JavaScript file) from a CDN. You can also load a JavaScript file locally (from the same site as your web app). In case you use several third-party JavaScript libraries and/or develop complicated JavaScript code yourself, it is even better to use a JavaScript bundler to combine the JavaScript files into a few compressed files. This gives a faster load page.

<script src="https://unpkg.com/vue@3.2"></script>

After loading the Vue library, we can load our own code. You can save the code in a separate js file and load with a syntax similar to above. Alternatively, you can embed the code within a <script> element, as in our example.

We embed JavaScript code in many of our example for sake of simplicity. However, in production code, it is generally recommended to remove JavaScript code from HTML file and move them to external JavaScript file.