Useful Things You Missed in the JavaScript Window Object: documentURI, embeds, and fonts
Tags: webdev, javascript, tutorial, beginners
Published: 2020-01-26 23:57:33

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

**Follow me on Twitter at https://twitter.com/AuMayeung**

**Many more articles at https://medium.com/@hohanga**

**Even more articles at http://thewebdev.info/**

The `window` object is a global object that has the properties pertaining to the current DOM document, which is the things that are in the tab of a browser.

In this article, we’ll look at some `window.document` object and how to use them, including the `documentURI`, `embeds`, and the `fonts` properties.

window.document.documentURI
===========================

The `documentURI` is a string property that returns the document location. It was originally a read/write property, but now it’s read-only. For example, if we have:

```javascript
console.log(document.documentURI);
```

We get something like:

```
"https://developer.mozilla.org/en-US/docs/Web/API/Document/documentURI"
```

from the `console.log` output.

window.document.embeds
======================

The `embeds` property is a read-only property that returns a list of embedded `object` elements within the document. For example, if we have the following `embed` element to add a video to our web page:

```html
<embed type="video/webm" src="https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4" width="250" height="200">

```

Then in the script file, we can use write the following code to get our embed element:

```javascript
console.log(document.embeds);
```

Then we get an HTMLCollection array-like object, which has our `embed` element for our video. An HTMLCollection object has an `item` method that lets us get the DOM element in the HTMLCollection object by its index. Also, since it’s an array-like object, we can use it with the `for...of` loop like in the following code:

```javascript
for (const el of document.embeds) {  
  console.log(el);  
}
```

If we run the code above, we get back the `embed` elements that are in our web page. We can also get the properties of the `embed` element like in the following code:

```javascript
for (const el of document.embeds) {  
  const {  
    height,  
    src,  
    type,  
    width  
  } = el;  
  console.log(height, src, type, width);  
}
```

We should get something like:

```
200 https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4 video/webm 250
```

if we have the `embed` element above. Those values are the same as the values of the attributes we passed in. We can replace the `for...of` by getting the element by index with the `item` method available to the HTMLCollection object instead:

```javascript
console.log(document.embeds);  
for (let i = 0; i < document.embeds.length; i++) {  
  const {  
    height,  
    src,  
    type,  
    width  
  } = document.embeds.item(i);  
  console.log(height, src, type, width);  
}
```

window.document.fonts
=====================

The `fonts` property returns a `FontFaceSet` object that has various properties and events that let us handle the loading of fonts. For example, if we have the following code:

```javascript
console.log(document.fonts);
```

We get the `FontFaceSet` object. The `FontFaceSet` object has the following properties. It has the `status` read-only property, which is a string, that indicates the loading status of the document’s fonts. The value can be `'loading'` or `'loaded'`.

Another property of the `FontFaceSet` is the `ready` read-only property, which is a promise which resolves once fonts are loaded and the layout operations are completed. For example, we can write the following to log ‘fonts loaded’ once all the fonts are loaded:

```javascript
(async () => {  
  await document.fonts.ready;  
  console.log('fonts loaded');  
})()
```

The `document.fonts` property also has 3 events — the `onloading` event, `onloadingdone` event, and the `onloadingerror` event. The `onloading` event handler is called when the loading event is fired, which indicates that the font has started loading.

The `onloadingdone` event handler is called whenever an event of type `loadingdone` is fired, which means that the font face set has successfully loaded. The `onloadingerror` event handler is called whenever a `loadingerror` type is fired, which indicates that the error occurred while loading a font face set.

For example, we can use the event handlers like in the following code:

```javascript
document.fonts.onloading = () => {
  console.log('Font is loading');
}
document.fonts.onloadingdone = () => {
  console.log('Font successfully loaded');
}
document.fonts.onloadingerror = () => {
  console.log('Error loading font');
}
(async () => {
  await document.fonts.load("12px Roboto", "A");
})();
```

And in the HTML file, we add:

```html
<link href='https://fonts.googleapis.com/css?family=Roboto:400,700' rel='stylesheet' type='text/css'>
```

Then we should get ‘Font is loading’ and ‘Font successfully loaded’ logged when we run the code since we loaded the font from the Google Font CDN by first including the font in our web page with the `link` tag and then we attached the event listeners to the font loading events.

Then finally, we ran the `document.fonts.load` method which does the loading of the Roboto font, which will trigger the `onloading` event and `onloadingdone` event handlers since we have the font loaded from the Google CDN which should be available for loading.

The `load` method that we used above returns a promise and takes 2 string arguments. The first is the string that represents the font size and name using CSS value syntax as we have above.

The second argument is the text that limits the font loading to the characters in the string we have above. The range should be one of the characters in the text. The second argument is optional.

In addition to the `load` method, there are a few more methods in the `document.fonts` object. It includes the `add` method which adds a font to the font set.

It takes one argument, which is the `FontFace` object. We create the `FontFace` object by using the `FontFace` constructor, which takes 2 arguments.

The first argument is the string of the font face name, and the second argument is the URL of the font face, which should be expressed like URLs in the CSS code.

For example, to add a font to our document with the `add` method, we can write:

```javascript
const fontFace = new FontFace('Bitter', 'url(https://fonts.gstatic.com/s/bitter/v7/HEpP8tJXlWaYHimsnXgfCOvvDin1pK8aKteLpeZ5c0A.woff2)');
document.fonts.add(fontFace);
```

The `FontFace` object as a `loaded` property, which returns a promise that resolves when the font designated in the `FontFace` constructor is loaded. For example, we can write:

```javascript
const fontFace = new FontFace('Bitter', 'url(https://fonts.gstatic.com/s/bitter/v7/HEpP8tJXlWaYHimsnXgfCOvvDin1pK8aKteLpeZ5c0A.woff2)');
document.fonts.add(fontFace);
(async () => {
  await document.fonts.load("12px Bitter", "A");
  const loadedFontFace = await fontFace.loaded;
  console.log(loadedFontFace);
})()
```

In the code above, we added the Bitter font with the `add` method and use the `load` method to load the newly added font. Then at the end, we logged the font face, we get the properties of the `FontFace` object, which should have something like the following output:

```
display: "auto"  
family: "Bitter"  
featureSettings: "normal"  
loaded: Promise {<resolved>: FontFace}  
status: "loaded"  
stretch: "normal"  
style: "normal"  
unicodeRange: "U+0-10FFFF"  
variant: "normal"  
weight: "normal"
```

To check if a font has been loaded and is available, we can use the `check` method, which returns a boolean and takes up to 2 arguments.

The first is a string with the font name with its properties in CSS value syntax.

The second argument is the text that limits the font loading to the characters in the string we have above.

The range should be one of the characters in the text. The second argument is optional. For example, we can use it as in the following code:

```javascript
console.log(document.fonts.check("12px Roboto", "a"));  
console.log(document.fonts.check("12px Arial", "a"));
```

The first `console.log` should output `false` since we didn’t load the Roboto font by writing any code. The second `console.log` should be `true` since it’s a font that is loaded without having to add any code to load it externally.

The `clear` method removes all the fonts from the font set. It takes no arguments. For example, we can use it as in the following code:

```javascript
const fontFace = new FontFace('Bitter', 'url(https://fonts.gstatic.com/s/bitter/v7/HEpP8tJXlWaYHimsnXgfCOvvDin1pK8aKteLpeZ5c0A.woff2)');
document.fonts.add(fontFace);
(async () => {
  await document.fonts.load("12px Bitter", "A");
  console.log(document.fonts.check("12px Bitter", "A"));
  const loadedFontFace = await fontFace.loaded;
  document.fonts.clear();
  console.log(document.fonts.check("12px Bitter", "A"));
})()
```

In the code above, we first load the font with the `load` method and then unloaded it with the `clear` method, so the first `console.log` should log `true` since loaded the font with the `load` method and the second one should log `false` since we called the `clear` method to unload it.

Finally, there’s the `delete` method which removes a font from the font set. It takes a `FontFace` object as its only argument. For example, we can use it as in the following code:

```javascript
const fontFace = new FontFace('Bitter', 'url(https://fonts.gstatic.com/s/bitter/v7/HEpP8tJXlWaYHimsnXgfCOvvDin1pK8aKteLpeZ5c0A.woff2)');
document.fonts.add(fontFace);
(async () => {
  await document.fonts.load("12px Bitter", "A");
  console.log(document.fonts.check("12px Bitter", "A"));
  const loadedFontFace = await fontFace.loaded;
  document.fonts.delete(loadedFontFace);
  console.log(document.fonts.check("12px Bitter", "A"));
})()
```

In the code above, we first load the font with the `load` method and then unloaded it with the `delete` method with the `loadedFontFace` passed in, so the first `console.log` should log `true` since loaded the font with the `load` method and the second one should log `false` since we called the `delete` method with the `loadedFontFace` passed in to unload it.

We continued from Part 5 of this series and looked at more properties of the `window.document` object which includes `documentURI`, `embeds` and the `fonts` properties. The `documentURI` property gets us the URL of the currently loaded document.

The `embeds` property get us all the `embed` DOM elements in our document and let us see the attributes. The `fonts` properties have many properties that let us get the status of the fonts we loaded, and it also has methods that let us load and unload fonts as we want them.

It also lets us check the status of the font you want to load. It’s very handy for loading custom fonts that aren’t normally built into operating systems and usable by browsers without loading.