Categories
HTML JavaScript

Introducing the Page Visibility API

Since most modern browsers are tabbed, it’s possible that a webpage may reside in a tab that stays in the background and not visible to the user.

The Page Visibility API can provide us with insight as to whether a page is visible to the user.

In this article, we’ll look at the Page Visibility API, its use cases, and how to use it.

Visibility Change Event

When a user minimizes the window or switches to another tab, the Page Visibility API sends a visibilitychange event to let listeners know that the state of the page has changed.

We can handle the event when it’s triggered and do something according to the visibility state. For example, we can pause the video when the page is hidden from view.

The visibility state of an iframe is the same as the parent document that the iframe is in. Hiding an iframe with CSS doesn’t trigger visibility events or change the state of the document contained within the iframe .

Use Cases

There’re many use cases for using the API. Some of them include the following:

  • pausing an image carousel when the page is hidden
  • stop polling the server for information when the page is hidden
  • prerendering a page to keep an accurate count of page views
  • switch off the sound when the page is not being viewed

Without the Page Visibility API, developers resort to imperfect solutions like listening to the blur or focus events of the window to help detect whether the page is visible or not.

They don’t tell if they’re hidden or not, just whether they’re in focus or not.

Policies that Help Background Page Performance

Most browsers do a few things to help save resources when a page isn’t in view.

requestAnimationFrame callback won’t be called to improve performance and battery life when a page is in the background.

setTimeout and other timers are throttles in the background or inactive tabs to improve performance.

Throttling is also done in browsers to limit CPU usage by background tabs.

Each background tab has its own time budget between -150ms and 50ms.

Browser windows are subjected to throttling after 30 seconds in Firefox and 10 seconds in Chrome.

Timer tasks are only permitted when the time budget is non-negative.

Once the timer’s code finishes running, the duration it takes to execute is subtracted from the time budget.

The budget regenerates at a rate of 10ms per second in both Firefox and Chrome.

Some processes ate exempt from throttling behavior. Tabs that are playing audio are considered foreground tabs and aren’t subject to throttling.

Code that uses real-time network connections goes unthrottled to prevent the closing of these connections.

IndexedDB processes are also left unthrottled to avoid timeouts.

The Page Visibility API can let us stop these things manually if we want to do so.

Using the Page Visibility API

The Page Visibility API is part of the document object.

We can use it by checking the document.hidden property or the document.visibilityState property. They’re both read-only.

To watch for changes in both, we can listen to the visibilitychange event.

To do this we can use the following example. Our example will pause a video when we switch to a different tab. First, we add the HTML code for the video as follows:

<video controls src='[https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4'](https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4%27)></video>

Then in our JavaScript code, we can listen to the visibilitychange event as follows:

const video = document.querySelector('video');

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState !== 'visible') {
    video.pause();
  }
})

In our event listener callback, we pause the video when the visibilityState isn’t ‘visible’ , which means the user can’t see the tab either by navigating away from the tab or window, minimizing the window, or turned the screen off.

The alternative to this is to set the event handler to the onvisibilitychange property of document.

document.visibilityState can take on these 3 values:

  • visible — the page is visible to the user as a foreground tab
  • hidden — the page isn’t visible to the user, either because it’s in the background, or the minimized or the device’s screen is off.
  • prerender — the page is being prerendered and isn’t visible to the user. A document may start in this state, but will never switch to this state from any other state since it can only prerender once. Not all browsers support prerendering.
  • unloaded — the page is being unloaded from memory. Not all browsers support this.

Compatibility

This API has been supported for a while. Chrome since version 33 supports this API. Edge, Firefox, IE 10 or later, and Safari 7 or later all support this API. Mobile versions of these browsers also support this API.

The Page Visibility API is useful for detecting the visibility state of the page. We can listen to the visibilitychange event and then get the visibility state with document.visibilityState and so what we want with it.

Categories
HTML JavaScript

Introduction to HTML Canvas

One way to display graphics is to use the img element in HTML. However, that only displays static images with a fixed URL. To draw and display dynamic graphics, we can use the HTML canvas element.


Creating a New Canvas

To create a new canvas element:

<canvas style='width: 200px; height: 200px'>
</canvas>

It looks like the img element, but it has no src or alt attributes. This is because it’s not a fixed image element.

We can style with CSS as we did above, with width , height , margin, border , padding , etc.

Fallback content

For browsers that don’t support canvas, we can supply fallback content by putting something inside. For example, we can write:

<canvas style='widthL 200px; height: 200px'>
  Your browser doesn't support canvas.
</canvas>

The closing tag </canvas> is required for canvas elements. If it’s not present, the rest of the document will be considered fallback content.


Rendering Context

The canvas element creates a fixed-size drawing surface that exposes one or more rendering contexts — entities to create and manipulate the content drawn.

The most basic is the 2D rendering context. There’s also a 3D rendering context for WebGL and OpenGL ES.

A canvas is initially blank. We have to access the rendering context and draw on it to display something. To do this, we can use the getContext() method of the canvas element. For 2D graphics, we specify '2d' into the getContext() method.

We access the canvas rendering context as follows:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

Checking for Support

We can check for support for the canvas element by checking if the getContext method exists, as follows:

const canvas = document.querySelector('canvas');
if (canvas.getContext) {
  const ctx = canvas.getContext('2d');
}

This should be less of a concern these days since almost all modern browsers support the canvas element.


Basic Code

Put it together and we have the following code. The HTML:

<canvas>
  Your browser doesn't support canvas.
</canvas>

Then we can add the following CSS:

canvas {
  width: 200px;
  height: 200px;
  border: 1px solid black;
}

Finally, we have this JavaScript code:

const canvas = document.querySelector('canvas');
if (canvas.getContext) {
  const ctx = canvas.getContext('2d');
}

A Simple Drawing

The simple drawing is made up of basic 2D shapes, like rectangles. We create three rectangles with different background colors with the following code:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(100, 0, 0)';
ctx.fillRect(5, 5, 40, 40);

ctx.fillStyle = 'rgba(0, 20, 100, 0.5)';
ctx.fillRect(10, 10, 50, 50);

ctx.fillStyle = 'rgba(20, 0, 200)';
ctx.fillRect(25, 25, 95, 90);

It works as follows. After we get the rendering context, we set the background color of the shape with the fillStyle property by setting it a string with the color value. Then we create a rectangle with the coordinates (5, 5) for the top left corner and (40, 40) for the bottom right corner.

The first two arguments are the x and y coordinates of the top-left corner, the last two are the width and height.

The first rectangle is:

ctx.fillStyle = 'rgb(100, 0, 0)';
ctx.fillRect(5, 5, 40, 40);

The color value rgb(100, 0, 0) represents a brownish color.

Likewise, we have:

ctx.fillStyle = 'rgba(0, 20, 100, 0.5)';
ctx.fillRect(10, 10, 50, 50);

This rectangle is to the right and lower than the first. It has a grayish color.

Finally, we have:

ctx.fillStyle = 'rgba(20, 0, 200)';
ctx.fillRect(25, 25, 95, 90);

This one is again to the right and lower than the second rectangle, in blue.

In the end, we get the following:

The drawing is finished once the page with the canvas element has loaded. The coordinates can be outside or inside the rectangle’s dimensions. If it exceeds the dimensions, we won’t see the stuff that’s drawn.

The canvas is useful to draw graphics, whether static or dynamic. We can create a canvas element in HTML, then we can get the canvas element in JavaScript and get the rendering context so we can draw items on it.

We can draw basic shapes on it. We can change the colors of the background with the fillStyle property of the context, then can call the fillRect on it to draw a rectangle.

It takes four arguments: The x, y coordinates of the top left corner for the first two arguments and the x, y coordinates for the bottom right corner for the last two elements.

Categories
HTML

Introduction to the HTML Dialog Element

Dialogs are frequently used in web apps. They’re used for displaying confirmation messages, alerts and other things that are suitable for popups.

Before the existence of the dialog element, we only have alert and confirm functions built into JavaScript to display text-only messages. They can’t be styled and can’t display anything other than text.

Also alert and confirm dialogs can’t have any button other than whatever’s built-in.

To make creating dialogs easier without adding libraries, now we can use the dialog element to create pop-up dialog boxes.

In this article, we’ll take a look at how to add dialog elements to our apps and do something with them.

Photo by Celine Sayuri Tagami on Unsplash

Creating Dialogs

To create dialogs, we’ll add the dialog element as follows:

<dialog open>
  <p>Greetings!</p>
</dialog>

We have a dialog with the open attribute to display the dialog. The default styling depends on the browser.

In Chrome, it looks something like this by default:

We can add any HTML to a dialog element. For example, we can add a form as follows:

<dialog open>
  <form method="dialog">
    <p>
      <label>
        Name:
      </label>
      <input type='type' name='name'>
    </p>

    <p>
      <label>
        Favorite Fruit:
      </label>
      <select name='fruit'>
        <option value='apple' selected>Apple</option>
        <option value='banana'>Banana</option>
        <option value='grape'>Grape</option>
      </select>
    </p>

    <menu>
      <button value="cancel">Cancel</button>
      <button id="confirm-btn" value="default">Confirm</button>
    </menu>
  </form>
</dialog>

<menu>
  <button id="dialog-button">Update Fruit</button>
</menu>

<output></output>

Our dialog has a form element with method set to dialog . This lets us set the return value of the dialog, which we can use after the dialog closes by clicking Confirm.

We also have an input and select element to let us input something into our form.

Also, we have a button with ID dialog-button to open our dialog element

Then in our JavaScript code, we can control the opening and closing of the dialog and get the inputted values as follows:

const dialogButton = document.getElementById('dialog-button');
const dialog = document.querySelector('dialog');
const output = document.querySelector('output');
const input = document.querySelector('input');
const select = document.querySelector('select');
const confirmBtn = document.getElementById('confirm-btn');

dialogButton.addEventListener('click', () => {
  if (typeof dialog.showModal === "function") {
    dialog.showModal();
  }
});

select.addEventListener('change', (e) => {
  confirmBtn.value = [select.value, input.value].join(' ');
});

input.addEventListener('change', (e) => {
  confirmBtn.value = [select.value, input.value].join(' ');
});

dialog.addEventListener('close', () => {
  output.value = dialog.returnValue;
});

To open the dialog we have:

dialogButton.addEventListener('click', () => {
  if (typeof dialog.showModal === "function") {
    dialog.showModal();
  }
});

The showModal method opens the dialog .

Then we have listeners for the select and input to get their values if the user enters anything.

We have:

confirmBtn.value = [select.value, input.value].join(' ');

to get the values from the input and select and set it to the value property of the confirmBtn , which is the Confirm button. This also sets the returnValue of dialog to confirmBtn.value .

Finally, we have:

dialog.addEventListener('close', () => {
  output.value = dialog.returnValue;
});

to get the returnValue , which is obtained from the confirmBtn.value assigned in the input and select listeners.

Then we get:

And once we click Confirm, we get:

Styling the Backdrop

To style the dialog ‘s background, we can select it by using the ::backdrop CSS pseudoelement to and apply styles to it. The backdrop is only drawn when the dialog is shown.

For example, we can style it as follows:

dialog::backdrop {
  background-color: lightblue !important;
}

The code above will change the backdrop color from the default to lightblue .

Then we get the following:

The dialog element saves us some effort when creating pop-up dialogs. We don’t need libraries or lots of code to create simple dialogs.

To set the values of dialog.returnValue when the dialog closes, we set the form element’s method to dialog , and set the confirm button’s value attribute to what we want to set it to.

We can use the ::backdrop pseudoelement to style the backdrop’s color when the dialog is open.

Categories
Bootstrap HTML

Bootstrap 5 — Extending Input Groups

Bootstrap 5 is in alpha when this is written and it’s subject to change.

Bootstrap is a popular UI library for any JavaScript apps.

In this article, we’ll look at how to style input groups with Bootstrap 5.

Multiple Inputs

Input groups can have more than one input added inside it.

For example, we can write:

<div class="input-group">  
  <span class="input-group-text">First and last name</span>  
  <input type="text" class="form-control">  
  <input type="text" class="form-control">  
</div>

to add first and last name inputs in one input group.

Multiple Addons

An input group can have multiple addons added to them.

For example, we can write:

<div class="input-group mb-3">  
  <span class="input-group-text">$</span>  
  <span class="input-group-text">0.00</span>  
  <input type="text" class="form-control">  
</div>
<div class="input-group">  
  <input type="text" class="form-control">  
  <span class="input-group-text">$</span>  
  <span class="input-group-text">0.00</span>  
</div>

We have 2 spans with the input-group-text class to add 2 input addons.

Button Addons

Buttons can be added as input group addons.

For example, we can write:

<div class="input-group mb-3">  
  <button class="btn btn-outline-secondary" type="button">Button</button>  
  <input type="text" class="form-control" placeholder="name">  
</div>

We added a button straight into the input-group to use it as an addon.

We can also add a button to the right side:

<div class="input-group mb-3">  
  <input type="text" class="form-control" placeholder="name">  
  <button class="btn btn-outline-secondary" type="button" id="button-addon2">Button</button>  
</div>

Also, we can add more than one addon.

For instance, we can write:

<div class="input-group mb-3">  
  <button class="btn btn-outline-secondary" type="button">Button</button>  
  <button class="btn btn-outline-secondary" type="button">Button</button>  
  <input type="text" class="form-control" placeholder="name">  
</div>
<div class="input-group">  
  <input type="text" class="form-control" placeholder="name">  
  <button class="btn btn-outline-secondary" type="button">Button</button>  
  <button class="btn btn-outline-secondary" type="button">Button</button>  
</div>

Buttons with Dropdowns

Dropdowns can be added as input group addons.

The Bootstrap JavaScript files are required for the dropdowns.

For example, we can write:

<div class="input-group mb-3">  
  <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">fruit</button>  
  <ul class="dropdown-menu">  
    <li><a class="dropdown-item" href="#">apple</a></li>  
    <li><a class="dropdown-item" href="#">orange</a></li>  
    <li><a class="dropdown-item" href="#">lemon</a></li>  
    <li><hr class="dropdown-divider"></li>  
    <li><a class="dropdown-item" href="#">grape</a></li>  
  </ul>  
  <input type="text" class="form-control">  
</div>

to add a dropdown to the left side.

We add the dropdown-toggle class to create the toggle.

And we have the data-toggle attribute to make it a toggle.

To add one to the right side, we can write:

<div class="input-group mb-3">  
  <input type="text" class="form-control">  
  <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">fruit</button>  
  <ul class="dropdown-menu">  
    <li><a class="dropdown-item" href="#">apple</a></li>  
    <li><a class="dropdown-item" href="#">orange</a></li>  
    <li><a class="dropdown-item" href="#">lemon</a></li>  
    <li>  
      <hr class="dropdown-divider">  
    </li>  
    <li><a class="dropdown-item" href="#">grape</a></li>  
  </ul>  
</div>

And we can add a dropdown to both sides:

<div class="input-group mb-3">  
  <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">fruit</button>  
  <ul class="dropdown-menu">  
    <li><a class="dropdown-item" href="#">apple</a></li>  
    <li><a class="dropdown-item" href="#">orange</a></li>  
    <li><a class="dropdown-item" href="#">lemon</a></li>  
    <li>  
      <hr class="dropdown-divider">  
    </li>  
    <li><a class="dropdown-item" href="#">grape</a></li>  
  </ul>  
  <input type="text" class="form-control">  
  <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">fruit</button>  
  <ul class="dropdown-menu">  
    <li><a class="dropdown-item" href="#">apple</a></li>  
    <li><a class="dropdown-item" href="#">orange</a></li>  
    <li><a class="dropdown-item" href="#">lemon</a></li>  
    <li>  
      <hr class="dropdown-divider">  
    </li>  
    <li><a class="dropdown-item" href="#">grape</a></li>  
  </ul>  
</div>

Segmented Buttons

We can make the dropdown button segmented.

To do that, we can write:

<div class="input-group mb-3">  
  <button type="button" class="btn btn-outline-secondary">fruit</button>  
  <button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown">  
    <span class="sr-only">Toggle Dropdown</span>  
  </button>  
  <ul class="dropdown-menu">  
    <li><a class="dropdown-item" href="#">apple</a></li>  
    <li><a class="dropdown-item" href="#">orange</a></li>  
    <li><a class="dropdown-item" href="#">lemon</a></li>  
    <li>  
      <hr class="dropdown-divider">  
    </li>  
    <li><a class="dropdown-item" href="#">banana</a></li>  
  </ul>  
  <input type="text" class="form-control">  
</div>

We add the split toggle button by adding 2 buttons side by side.

We have the dropdown-toggle and dropdown-toggle-split classes to add the split dropdown button.

Also, we can put the split button and dropdown on the right side:

<div class="input-group mb-3">  
  <input type="text" class="form-control">  
  <button type="button" class="btn btn-outline-secondary">fruit</button>  
  <button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown">  
    <span class="sr-only">Toggle Dropdown</span>  
  </button>  
  <ul class="dropdown-menu">  
    <li><a class="dropdown-item" href="#">apple</a></li>  
    <li><a class="dropdown-item" href="#">orange</a></li>  
    <li><a class="dropdown-item" href="#">lemon</a></li>  
    <li>  
      <hr class="dropdown-divider">  
    </li>  
    <li><a class="dropdown-item" href="#">banana</a></li>  
  </ul>  
</div>

Conclusion

We can add multiple addons, inputs, and dropdowns to an input group.

To make the dropdown display, we need the JavaScript files.

Categories
Bootstrap HTML

Bootstrap 5 — Lists and Images

Bootstrap 5 is in alpha when this is written and it’s subject to change.

Bootstrap is a popular UI library for any JavaScript apps.

In this article, we’ll look at how to style lists and images with Bootstrap 5.

Lists

Bootstrap 5 removes the default list-style and left margin of list items.

This only applies to immediate children list items.

The class has to be added to nested lists.

For example, we can wire:

`<ul class="list-unstyled">  
  <li>Lorem ipsum dolor sit amet</li>  
  <li>`Duis id nunc dignissim`</li>  
  <li>Nulla volutpat aliquam velit  
    <ul>  
      <li>Phasellus iaculis neque</li>  
      <li>` Suspendisse potenti. Aliquam erat volutpat.`</li>  
    </ul>  
  </li>  
  <li>`Pellentesque habitant morbi tristique senectus`</li>  
  <li>Aenean sit amet erat nunc</li>  
  <li>Eget porttitor lorem</li>  
</ul>`

to add a nested list.

We added the list-unstyled class to add an unstyled list.

Inline

We can remove a list’s bullets and apply some light margin with the combination of the .list-inline and .list-inline-item classes:

`<ul class="list-inline">  
  <li class="list-inline-item">`Lorem ipsum dolor sit amet, consectetur adipiscing elit.`</li>  
  <li class="list-inline-item">`Pellentesque quis nunc ultricies enim ullamcorper pretium at cursus tellus.`</li>  
  <li class="list-inline-item">` Ut convallis quis lacus in volutpat. Pellentesque volutpat dui et enim mattis`</li>  
</ul>`

We add the classes to make the items display inline with margins.

Description List Alignment

To make a list with description, we can use the dl , dt , and dd tags with the width styles.

For example, we can write:

`<dl class="row">  
  <dt class="col-sm-3">Description lists</dt>  
  <dd class="col-sm-9">A description list is perfect for defining terms.</dd>  
  
  <dt class="col-sm-3">Euismod</dt>  
  <dd class="col-sm-9">  
    <p>`Lorem ipsum dolor sit amet, consectetur adipiscing elit.`</p>  
    <p>`ellentesque quis nunc ultricies enim ullamcorper pretium at cursus tellus. Curabitur sit amet leo arcu. Integer vitae tincidunt odio. Duis id nunc dignissim.`</p>  
  </dd>  
  
  <dt class="col-sm-3">`Maecenas imperdiet sapien augue, ac malesuada metus ultrices et.`</dt>  
  <dd class="col-sm-9">`Aliquam erat volutpat. Quisque rutrum commodo felis imperdiet fermentum. Integer hendrerit dictum augue dapibus semper. In ac nisi consectetur`.</dd>  
  
  <dt class="col-sm-3 text-truncate">Truncated term is truncated</dt>  
  <dd class="col-sm-9">`Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.`</dd>  
  
  <dt class="col-sm-3">Nesting</dt>  
  <dd class="col-sm-9">  
    <dl class="row">  
      <dt class="col-sm-4">Nested definition list</dt>  
      <dd class="col-sm-8">`Aenean dolor augue, vulputate non mattis eu, lacinia viverra ex.`</dd>  
    </dl>  
  </dd>  
</dl>`

We have the list with the dt and dd tags with the column classes to set the width of them.

Images

We can add responsive images with the img element and the .img-fluid class.

For example, we can write:

`<img src="`http://placekitten.com/200/200`" class="img-fluid" alt="cat">`

Image Thumbnails

To add thumbnails, we use the .img-thumbnail class:

`<img src="`http://placekitten.com/200/200`" class="img-thumbnail" alt="cat">`

Aligning Images

We can align images with the float-left or float-right classes:

<img src="http://placekitten.com/200/200" class="rounded float-left" alt="cat">  
<img src="http://placekitten.com/200/200" class="rounded float-right" alt="cat">

To make it aligned centered horizontally, we can write:

`<img src="`http://placekitten.com/200/200`" class="rounded mx-auto d-block" alt="cat">`

We used the mx-auto class to make the image centered.

Also, we can use the text-center class to do the same thing:

<div class="text-center">  
  <img src="http://placekitten.com/200/200" class="rounded" alt="cat">  
</div>

Picture

The picture element can be used to specify multiple sources of images.

So we can write:

`​<picture>  
  <img src="`http://placekitten.com/200/200`" class="img-fluid img-thumbnail" alt="cat 1">  
  <img src="`http://placekitten.com/201/201`" class="img-fluid img-thumbnail" alt="cat 2">  
</picture>`

We put the img elements in the picture tags.

And we’ve to add the img-* classes ion the img tag rather than the picture tag.

Conclusion

We can style lists and images with Bootstrap 5.

It comes with the classes for us to do so.