Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Timers and the DOM

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at the built-in properties of window and the DOM.

The window.setTimeout() and window.setInterval() Methods

We can use the window.setTimeout and window.setInterval methods to schedule the execution of some JavaScript code.

setTimeout lets us run some code after a delay.

For instance, we can write:

function foo() {  
  alert('foo');  
}  
setTimeout(foo, 2000);

It returns the ID of the timer.

We can use the ID to call clearTimeout to cancel the timer.

For example, we can write:

function foo() {  
  alert('foo');  
}  
const id = setTimeout(foo, 2000);  
clearTimeout(id);

then the alert will never be shown because clearTimeout before the 2 seconds are up.

We can use the setInterval method to schedule foo to run every 2 seconds.

For instance, we can write:

function foo() {  
  console.log('foo');  
}  
const id = setInterval(foo, 2000);

We can call clearInterval to cancel the timer by writing:

clearInterval(id);

Scheduling a function in some amount of milliseconds isn’t a guarantee that it’ll execute exactly at that time.

Most browsers don’t have millisecond resolution time.

Also, the browser maintains a queue of what we expect them to do.

100ms means adding to the queue after 100 ms.

But the queue may be delayed by something slow.

Most recent browsers have the requestAnimationFrame function which is better than timeout functions because we ask the browser to run or function whenever it has the resources.

The schedule isn’t defined in milliseconds.

For instance, we can write:

function animateDate() {  
  requestAnimationFrame(() => {  
    console.log(new Date());  
    animateDate();  
  });  
}  
animateDate();

to log the latest date whenever the browser can run the code.

The window.document Property

The window.document property is a BOM object that refers to the currently loaded document or page.

DOM

The DOM represents an XML or an HTML document as a tree of nodes.

We can use DOM methods and properties to access any element on the page.

Also, we can use them to modify or remove elements.

It’s a language-independent API that can be implemented in any language.

We can view the DOM tree within the Elements tab of the browser.

For example, we should see that a p element is created by the HTMLParagraphElement constructor.

And the head tag is created by the HTMLHeadElement constructor.

Core DOM and HTML DOM

The core DOM forms the most basic parts of the DOM specification.

And the HTML DOM specification builds on top of the core DOM.

The following constructors are in the core DOM:

  • Node — any node on the tree
  • Document — the document object
  • Element — tags in the tree
  • CharacterData — constructor for dealing with texts
  • Text — text node in a tag
  • Comment — a comment in the document
  • Attr — an attribute of a tag
  • NodeList — list of nodes, which is an array-like object with a length property
  • NamedNodeMap — same as NodeList but the nodes can be accessed by name rather than numeric index.

The HTML DOM has the following constructors:

  • HTMLDocument — an HTML specific version of the document object
  • HTMLElement — parent constructor of all HTML elements
  • HTMLBodyElement — element representing the body tag
  • HTMLLinkElement — an a element
  • HTMLCollection — a NamedNodeMap that’s specific to HTML

We can use them to access DOM nodes, and modify, create, and remove nodes.

Conclusion

An HTML document is represented by the DOM.

We can get and manipulate the nodes in the DOM tree to do what we want.

window has timer methods to let us schedule code to run.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Styles and Nodes

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at the DOM and inserting and copying nodes.

Modifying Styles

We can change the styles of an element.

For instance, we can write:

const p = document.getElementById('closer');
p.style.border = "1px solid green";

then we set the border of the p element to green.

We can also set the font-weight with the fontWeight property:

p.style.fontWeight = 'bold';

We can set styles with the cssText property:

p.style.cssText; "border: 1px solid green; font-weight: bold;"

The styles can be changed with some string manipulating:

p.style.cssText += " border-style: dashed";

Forms

We can manipulate forms by getting the form element.

For example, we can write:

const input = document.querySelector('input[type=text]');

to get the first input with type attribute set to text.

Then we can get the name property with input.name .

We can set the value entered into the box with:

input.value = 'abc';

And we can get the button for the form with:

document.querySelector("button")

Creating New Nodes

We can create new nodes with the createElement method.

For example, we can write:

const p = document.createElement('p');
p.innerHTML = 'foo';

to create a p element with content 'foo' .

We can get the style with the style property:

p.style

And we can assign new styles to it:

p.style.border = '2px dotted green';

Then we can attach it to a node like the body:

document.body.appendChild(p);

appendChild attaches the node as the last child node of body.

DOM-Only Method

We can also use DOM methods to add text nodes and styling.

For instance, we can use createTextNode to create the text node:

const p = document.createElement('p');
const text = document.createTextNode('something'); p.appendChild(text);

We created a p element and attached the text node 'something' to it.

We can also call appendChild with a text node to add it as a child node:

const str = document.createElement('strong');
str.appendChild(document.createTextNode('bold'));

We created a strong element and added the text bold to it,

The cloneNode() Method

We can clone a node with the cloneNode method.

For instance, we can write:

const el = document.querySelector('p');
document.body.appendChild(el.cloneNode(false));

We get a p element, cloned it with cloneNode , and then attached it to the body.

A shallow copy is done without any children. The false argument will make the copy shallow.

To make a deep copy with all the child nodes copied, we can change the argument of cloneNode to true :

const el = document.querySelector('p');
document.body.appendChild(el.cloneNode(true));

The insertBefore() Method

We can use the insertBefore method to add a child node before a given node.

For instance, we can write:

document.body.insertBefore(
  document.createTextNode('first node'),
  document.body.firstChild
);

We called inserBefore to insert a text node before the first child of the body .

Conclusion

We can add and remove nodes with various methods.

Their styles can be changed with the style property.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Proxies, Functions, and Built-in Objects

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at JavaScript metaprogramming with proxies and built-in browser objects.

Proxies and Function Traps

We can intercept function calls with the get and apply operations.

For instance, we can create a handler by writing:

const person = {
  name: "james",
  foo(text) {
    console.log(text);
  }
}

const proxy = new Proxy(person, {
  get(target, propKey, receiver) {
    const propValue = target[propKey];
    if (typeof propValue !== "function") {
      return propValue;
    } else {
      return function(...args) {
        return propValue.apply(target, args);
      }
    }
  }
});

proxy.foo('james')

We have the person object that we control with the get method.

target is the object we’re controlling.

In this case, it’s the person object.

propKey is the property key.

We check if the property is a function.

If it’s not, we return whatever value it has.

Otherwise, we call the function with this being target with the arguments.

And we return the result.

The Browser Environment

The browser environment is controlled with JavaScript.

It’s the natural host for JavaScript programs.

Including JavaScript in an HTML Page

We can include JavaScript in an HTML page with the script tag.

For instance, we can write:

<!DOCTYPE>
<html>

<head>
    <title>app</title>
    <script src="script.js"></script>
  </head>

  <body>
    <script>
      let a = 1;
      a++;
    </script>
  </body>

</html>

We have a script tag with src set to script.js .

And we also have an inline script with JavaScript code inside it.

BOM and DOM

JavaScript code on a page has access to various objects.

They include core ECMAScript objects, which are ones like Array , Object , etc.

DOM are objects that have to do with the current page.

BOM has objects that deal with everything outside the page like the browser window and desktop screen.

The DOM is standardized in various W3C specs.

But the BOM isn’t in any standard.

BOM

The BOM is a collection of objects that gives us access to the browser and the computer screen.

The objects are accessible through the global window object.

The window Object

The window object is a global object provided by the browser environment.

For instance, we can add a global variable by writing:

window.foo = 1;

Then foo is 1.

Some core JavaScript functions are part of the window object.

For instance, we can write:

parseInt('123');

then we get 123.

It’s the same as:

window.parseInt('123');

These can vary from one browser to another, but they’re implemented consistently and reliably across all major browsers.

The window.navigator Property

The navigator property has some information about the browser and its capabilities.

One is the navigator.userAgent property.

For instance, we can write:

window.navigator.userAgent

then we get the user agent string.

We may get a string like:

"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36 Edg/84.0.522.52"

returned.

We can use this to check for which browser.

For instance, we can write:

if (navigator.userAgent.indexOf('MSIE') !== -1) {
  //...
} else {
  //...
}

to check if a script is running in Internet Explorer.

But it’s a bad way to check for browser features since the user agent can be spoofed.

We can just check for the feature we want directly:

if (typeof window.addEventListener === 'function') {
  // ...
} else {
  // ...
}

Conclusion

Browsers have various built-in objects we can use.

Also, we can use proxies to control functions.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Properties of Window

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at the built-in properties of window .

The window.screen Property

The window.screen property lets get information about the browser’s screen.

We can get the color depth with:

window.screen.colorDepth;

And we can get the screen’s width with:

screen.width;
screen.availWidth;

width is the whole screen and availableWidth subtracts the widths of the menus and scrollbars, etc.

We can get the heights the same way with:

screen.height;
screen.availHeight;

Some devices also have the devicePixelRatio property:

window.devicePixelRatio

which tells us the trio between the physical pixels and device pixels in retina displays.

window.open()/close() Method

The window.open method lets us open a new browser window.

Various policies and settings of the browser may prevent us from opening popups to curb popup ads.

But we should be able to open a new window if it’s initiated by the user.

If we try to open a window when the page loads, it’ll probably be blocked since the user didn’t open the window.

The window.open() method takes a few parameters.

The first is the URL to load in a new window.

The name of the new window can be used as the value of the form’s target attribute.

A comma-separated list of features are also arguments, which include resizable to indicates whether the popup is resizable.

The width is the width of the popup window.

status is indicates whether the status bar should be visible.

For instance, we can write:

const win = window.open('http://www.example.com', 'example window',
'width=300,height=300,resizable=yes');

We call the open method with the URL, the title, and a string with the window size and whether it’s resizable.

win has the close method to let us close the window.

The window.moveTo() and window.resizeTo() Methods

The window.moveYo method lets us move the browser window to the given screen coordinates of the top-left corner.

For instance, we can write:

window.moveTo(100, 100)

to move the window.

We can also call the moveBy method to move the window by the given number of pixels across and down from its current location.

For instance, we can write;

window.moveBy(10, 10):

to move a window right and down by 10 pixels.

We can also pass in negative numbers to move in the opposite direction.

The window.resizeTo and window.resizeBy methods accept the same parameter as the move methods.

But they resize the window instead of moving it.

The window.alert(), window.prompt(), and window.confirm() Methods

alert is a method that takes a string and shows the alert with the text we pass in.

confirm lets us create a dialog box with the text we want to display.

The user can click OK or Cancel to dismiss the dialog box.

The value will be returned by the confirm function.

It’ll return true if we click OK and false otherwise.

So we can write:

const answer = confirm('Are you sure?');

Then we can get the answer after the user clicks on the button.

It’s handy for confirming user actions.

So we can write:

if (confirm('Are you sure?')) {
  // ...
} else {
  // ...
}

The prompt lets us show a dialog with some question text and let the user enter something into an input.

The inputted value will be returned as a string.

If it’s empty then it returns an empty string.

It returns null if the user clicks cancel, X, or press the Esc key.

We can use it by writing:

const answer = prompt('Are you sure?');

answer has the answer that’s entered.

Conclusion

window has many methods we can use.

They include methods to open a window, open alerts and prompts, and more.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Metaprogramming and Proxies

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at JavaScript metaprogramming with proxies.

Metaprogramming and Proxies

Metaprogramming is a programming method where a program is aware of its structure and manipulating itself.

There’re multiple ways to do metaprogramming.

One is introspection. This is where we have read-only access to the internals of a program.

Self-modification is making structural changes to the program.

Intercession is where we change language semantics.

In JavaScript, we can do this with proxies.

They let us control how objects are accessed and set.

Proxy

We can use proxies to determine the behavior of an object.

The object being controlled is called the target.

We can define custom behaviors for basic operations on an object like property lookup, function call, and assignment.

A proxy needs 2 parameters,

One is the handler, which is an object with methods to let us change the behavior of object operations.

Target is the target that we want to change the operations to.

For instance, we can create a proxy to control an object by writing:

const handler = {
  get(target, name) {
    return name in target ? target[name] : 1;
  }
}
const proxy = new Proxy({}, handler);
proxy.a = 100;

console.log(proxy.a);
console.log(proxy.b);

We created a proxy with handler with the handler object.

The get method lets us control how properties are retrieved.

target is the object that we’re controlling.

The name is the property name we want to access.

In the get method, we check if the name proxy exists.

If it does we return the target value, otherwise we return 1.

Then we create a proxy with the Proxy constructor.

A first argument is an empty object.

handler is our handler for controlling the operations.

proxy.a is defined, so its value is returned.

Otherwise, we return the default value.

Also, we can use proxies to validate values before setting them to an object.

For instance, we can trap the set handler by writing:

const ageValidator = {
  set(obj, prop, value) {
    if (prop === 'age') {
      if (!Number.isInteger(value)) {
        throw new TypeError('age must be a number');
      }
      if (value < 0 || value > 130) {
        throw new RangeError('invalid age range');
      }
    }
    obj[prop] = value;
  }
};
const p = new Proxy({}, ageValidator);
p.age = 100;
console.log(p.age);
p.age = 300;

We have the set method with the obj , prop , and value parameters.

obj is the object we want to control.

prop is the property key.

value is the property value we want to set.

We check if prop is 'age' so that we validate the assignment of the age property.

Then we check if it’s an integer and if it’s not we throw an error.

We also throw an error if it’s out of range.

Then we create a proxy with the Proxy constructor with the ageValidator as the handler and an empty object to control.

Then if we try to set p.age to 300, we get a RangeError .

Conclusion

Proxies let us control how object properties are retrieved and set.