Categories
Quasar

Developing Vue Apps with the Quasar Library — Spacers, Spinners, Split Screens

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Spacer

We can add the q-space component to add a spacer to fill any space.

For instance, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-toolbar class="bg-primary text-white">
            <q-btn flat round dense icon="menu"></q-btn>

            <q-space></q-space>

            <q-btn flat round dense icon="more_vert"></q-btn>
          </q-toolbar>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We add the q-space component between the q-btn s to keep them apart.

The q-btn s will be displayed at the ends of the toolbar.

Spinners

We can add a spinner by using the q-spinner component.

For example, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-spinner color="primary" size="3em" :thickness="10"> </q-spinner>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We set the diameter with the size prop.

And thickness sets the thickness of the edge of the spinner.

color sets the color of the edge.

Now we should see the spinner with a thick edge.

Quasar comes with many other spinners. For example, we can show animated squares for the loading indicator by writing:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-spinner-cube color="primary" size="3em" :thickness="10">
          </q-spinner-cube>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

Other spinners include:

  • q-spinner-audio
  • q-spinner-ball
  • q-spinner-clock
  • q-spinner-comment
  • q-spinner-dots
  • q-spinner-facebook
  • q-spinner-gears
  • q-spinner-grid
  • q-spinner-hearts
  • q-spinner-hourglass
  • q-spinner-infinity
  • q-spinner-oval
  • q-spinner-pie
  • q-spinner-puff
  • q-spinner-radio
  • q-spinner-rings
  • q-spinner-tail

Split Screen

We can split the browser screen with the q-splitter component.

For example, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-splitter v-model="splitterModel" style="height: 400px;">
            <template v-slot:before>
              <div class="q-pa-md">
                <div class="text-h4 q-mb-md">Before</div>
                <div v-for="n in 20" :key="n" class="q-my-md">
                  {{ n }}. Lorem ipsum
                </div>
              </div>
            </template>

            <template v-slot:after>
              <div class="q-pa-md">
                <div class="text-h4 q-mb-md">After</div>
                <div v-for="n in 20" :key="n" class="q-my-md">
                  {{ n }}. Quis praesentium
                </div>
              </div>
            </template>
          </q-splitter>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          splitterModel: 50
        }
      });
    </script>
  </body>
</html>

to add the component to add 2 side by side panels.

splitterModel sets the percentage of the screen that the left panel takes up.

It’s bound to v-model to let us set the size of the left panel.

The before slot has the content for the left panel.

And the after slot has the content for the right panel.

Conclusion

We can add spacers, spinners, and split-screen panels into our Vue app with Quasar.

Categories
JavaScript

Introducing the JavaScript Window Object — PointerLockElement and More

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. The document property of the window object has the DOM document and associated nodes and methods that we can use to manipulate the DOM nodes and listen to events for each node. Since the window object is global, it’s available in every part of the application. When a variable is declared without the var , let or const keywords, they’re automatically attached to the window object, making them available to every part of your web app. This is only applicable when strict mode is disabled. If it’s enabled, then declaring variables without var , let , or const will be stopped an error since it’s not a good idea to let us declare global variables accidentally. The window object has many properties. They include constructors, value properties and methods. There’re methods to manipulate the current browser tab like opening and closing new popup windows, etc.

In a tabbed browser, each tab has its own window object, so the window object always represent the state of the currently opened tab in which the code is running. However, some properties still apply to all tabs of the browser like the resizeTo method and the innerHeight and innerWidth properties.

Note that we don’t need to reference the window object directly for invoking methods and object properties. For example, if we want to use the window.Image constructor, we can just write new Image() . In this article, we continue to look at what’s in the window object. In the previous sections, we looked at the constructors and some of the properties of the window object, including using the customElements to build a Web Component, and the crypto object to do cryptography on the client using symmetric and asymmetric encryption algorithms. In this article, we will look at the pointerLockElement property, the styleSheets property and the onfullscreenchange event handler.

window.document.pointerLockElement

The pointerLockElement property is a read-only property that provides the Element object that set as the target for mouse events when the pointer is locked. It’s null if the lock is pending, the pointer is unlocked, or the target is in another document. For example, if we have the following HTML:

<!DOCTYPE html>
<html>
  <head>
    <title>Full Screen</title>
  </head>
  <body>
    <img
      src="https://images.unsplash.com/photo-1537498425277-c283d32ef9db?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=757&q=80"
      id="img"
    />
    <script src="main.js"></script>
  </body>
</html>

and the following JavaScript code in main.js :

const img = document.getElementById("img");
img.addEventListener("click", async () => {
  await img.requestPointerLock();
});

document.addEventListener(
  "pointerlockchange",
  () => {
    console.log(window.document.pointerLockElement);
  },
  false
);

Then we can lock the mouse pointer to the element that called the requestPointerLock method and succeeded in securing the pointer lock. In the code above, we have an img element that we attached an click event listener by passing in an event handler function to let our code request the pointer lock by calling the requestPointerLock method. We called this method on the img element object. Once we clicked on the image. The pointer is locked to the img element, and the pointerlockchange will be triggered. Once that triggers the event handler function that we passed into the document.addEventListener is called, which will then log the window.document.pointerLockElement object, which will log the img object that secured the pointer lock and where the mouse pointer is locked in. There’s also a pointerlockerror event to handle the case when the pointer lock didn’t get secured successfully.

window.document.styleSheets

We can get all the style sheet link elements with the styleSheets property. It’s a read-only property that returns a StyleSheetList or CSSStyleSheet objects. These objects are array-like objects, so we can loop through them with a for loop or a for...of loop. However, array methods aren’t available for these objects. The list of style sheets in the StyleSheetList or CSSStyleSheet object returned are order in a specific way. The StyleSheet objects that are retrieved from the link headers are placed first sorted in the same order as in the head tag, then StyleSheet objects are retrieved from the DOM are placed after the ones in the head , and these ones are sorted in tree order. The DOM tree is traversed in a preorder, depth-first way, so the root will be traversed, then the browser will go through left most nodes and then go down the tree and move to the right afterward. For example, if we have the following code in the HTML file:

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet">

Then we can loop through it in the JavaScript by getting the StyleSheet objects with the document.styleSheets property and the loop through it with the for...of like in the following code:

for (const sheet of document.styleSheets) {
  console.log(sheet);
}

Alternatively, we can use the for loop to do the same thing:

for (let i = 0; i < document.styleSheets.length; i++) {
  console.log(document.styleSheets[i]);
}

A StyleSheet object has the properties which reflect the attributes of the link tag and more. These are the properties of a StyleSheet object:

  • disabled — A boolean property that represents whether the current style sheet has been applied or not
  • href —A read-only string property that represents the location of the style sheet.
  • media — A read-only MediaList that represents the intended destination medium for style information
  • ownerNode — A read-only Node object that associates the style sheet with the current document
  • parentStyleSheet — A read-only property that returns the parent StyleSheet object including this one, if any and returns null if they don’t exist.
  • title — A read-only string property that represents the advisory title of the current style sheet.
  • type —A read only string property that represents the style sheet language for this style sheet.

window.document.onfullscreenchange

The onfullscreenchange property is an event handler that we can set to handle the fullscreenchange event. The fullscreenchange event is fired immediately when the document transitions in and out of full screen mode. The onfullscreenchange event handler will run when the fullscreenchange event is triggered. For example, if we have the following HTML code:

<!DOCTYPE html>
<html>
  <head>
    <title>Full Screen</title>
  </head>
  <body>
    <img
      src="https://images.unsplash.com/photo-1537498425277-c283d32ef9db?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=757&q=80"
      id="img"
    />
    <script src="main.js"></script>
  </body>
</html>

and the following JavaScript code in main.js :

const img = document.getElementById("img");
document.addEventListener("click", async () => {
  await img.requestFullscreen();
});

document.onfullscreenchange = event => {
  console.log("onfullscreenchange");
  console.log(window.document.fullscreenElement);
};

Then when we click on the web page, we will see the onfullscreenchange event handler being run since the fullscreenchange event has been triggered as we click the page to go full screen. Likewise, if we press the Esc key to close the full screen mode, the onfullscreenchange event handler function is run again since the fullscreenchange event is triggered again. In the example, we attached an event handler to the click event of the document object, which is the web page, by using the addEventListener method. Then we passed in the event handler function to the addEventListener method, which then runs the img.requestFullscreen() method to request full-screen mode when the web page is clicked. Once it succeeds, then the onfullscreenchange event handler function we assigned to it is called, and when we exited out of full-screen mode, it’s called again. To check if we’re in full-screen mode, we can use the window.document.fullscreenElement object. If we are in full screen, then there should be an object logged which is the HTML Element that we presented in full screen. If we exited out of full-screen mode, then window.document.fullscreenElement should be null .

The pointerLockElement property let us get the element that the cursor is in when pointer lock is activated. If we want to look at the style sheets in our JavaScript file, the styleSheets property will get us the style sheets in the form of JavaScript objects that we can enable and disable and also get the attributes and values we defined. The onfullscreenchange event handler let us handle the fullscreenchange event which is triggered when we go in and out of full-screen mode. We can check for full-screen mode with the window.document.fullscreenElement property, which should have an Element if we’re in full-screen mode and null otherwise.

Categories
JavaScript

Introducing the JavaScript Window Object — URL and activeElement

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. The document property of the window object has the DOM document and associated nodes and methods that we can use to manipulate the DOM nodes and listen to events for each node. Since the window object is global, it’s available in every part of the application. When a variable is declared without the var , let or const keywords, they’re automatically attached to the window object, making them available to every part of your web app. This is only applicable when strict mode is disabled. If it’s enabled, then declaring variables without var , let , or const will be stopped an error since it’s not a good idea to let us declare global variables accidentally. The window object has many properties. They include constructors, value properties and methods. There’re methods to manipulate the current browser tab like opening and closing new popup windows, etc.

In a tabbed browser, each tab has its own window object, so the window object always represent the state of the currently opened tab in which the code is running. However, some properties still apply to all tabs of the browser like the resizeTo method and the innerHeight and innerWidth properties.

Note that we don’t need to reference the window object directly for invoking methods and object properties. For example, if we want to use the window.Image constructor, we can just write new Image() . In this article, we continue to look at what’s in the window object. In the previous sections, we looked at the constructors and some of the properties of the window object, including using the customElements to build a Web Component, and the crypto object to do cryptography on the client using symmetric and asymmetric encryption algorithms. In this article, we will explore the URL , activeElement and the fullscreenElement properties.

window.document.URL

We can use the URL property to get the URL of the currently loaded page as a string. It is a read-only property. For example, we can write:

console.log(window.document.URL);

Then we should get something like https://fiddle.jshell.net/_display/.

window.document.activeElement

The activeElement property is a read only property that returns the Element object which is in focus. The activeElement often will return an input or a textarea object if it has text selection at the time. If this is the case, we can get more details with the selectionStart and selectionEnd properties. Focused elements may also be a select element or an input element of the type button , checkbox or radio . Users can press the tab key to move the focus on a different element that they’re currently focused in. A space bar can activate an input element if it involves selection like a checkbox or a radio button. For macOS systems, elements that aren’t inputs aren’t focusable by default. For example, if we have the following HTML markup:

<form>
  <textarea name="textarea-1" id="textarea-1" rows="7" cols="40">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi interdum justo vel nulla laoreet mollis. Curabitur eget turpis id mi venenatis efficitur vestibulum sit amet libero. Fusce non varius tellus. Vestibulum a nisi venenatis, accumsan diam eget, aliquet ex. Sed tristique purus at est pulvinar, eu tincidunt justo vestibulum. Mauris fringilla interdum ipsum sed blandit. Suspendisse sollicitudin ut mi eget tincidunt. Sed et dolor diam. Praesent venenatis ipsum a libero interdum, in sagittis tellus elementum. Pellentesque in est vitae dui efficitur lacinia eget porta diam.

  </textarea>

  <textarea name="textarea-2" id="textarea-2" rows="7" cols="40">Duis urna dolor, fringilla quis dui quis, bibendum ornare ligula. Fusce ut nisi eu orci elementum rhoncus. Morbi ut tortor mauris. Morbi pretium tempus erat vitae dignissim. Duis et dolor vel metus tempor laoreet nec eget est. Curabitur tincidunt ullamcorper ante, sit amet iaculis arcu condimentum vitae. Donec tincidunt convallis maximus. Mauris pulvinar sem velit, congue volutpat nisl commodo sit amet. Duis ac est eu orci venenatis lacinia.

  </textarea>
</form>

and the following JavaScript code:

const textarea1 = document.getElementById('textarea-1');
const textarea2 = document.getElementById('textarea-2');
const onMouseUp = () => {
  console.log(document.activeElement);
}
textarea1.addEventListener('mouseup', onMouseUp, false);
textarea2.addEventListener('mouseup', onMouseUp, false);

Then when we click either of the 2 textarea elements, then we see the activeElement being the textarea element that’s currently in focus. That is, the one that the cursor is currently in after it was clicked. Since the activeElement is an Element object, we can log its properties. We can change the code to the following to get the id and the value for the currently focused textarea element:

const textarea1 = document.getElementById('textarea-1');
const textarea2 = document.getElementById('textarea-2');
const onMouseUp = () => {
  const {
    id,
    value
  } = document.activeElement
  console.log(id);
  console.log(value);
}
textarea1.addEventListener('mouseup', onMouseUp, false);
textarea2.addEventListener('mouseup', onMouseUp, false);

Then we get:

textarea-1

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi interdum justo vel nulla laoreet mollis. Curabitur eget turpis id mi venenatis efficitur vestibulum sit amet libero. Fusce non varius tellus. Vestibulum a nisi venenatis, accumsan diam eget, aliquet ex. Sed tristique purus at est pulvinar, eu tincidunt justo vestibulum. Mauris fringilla interdum ipsum sed blandit. Suspendisse sollicitudin ut mi eget tincidunt. Sed et dolor diam. Praesent venenatis ipsum a libero interdum, in sagittis tellus elementum. Pellentesque in est vitae dui efficitur lacinia eget porta diam.

when we click on the first textarea and we get:

textarea-2

Duis urna dolor, fringilla quis dui quis, bibendum ornare ligula. Fusce ut nisi eu orci elementum rhoncus. Morbi ut tortor mauris. Morbi pretium tempus erat vitae dignissim. Duis et dolor vel metus tempor laoreet nec eget est. Curabitur tincidunt ullamcorper ante, sit amet iaculis arcu condimentum vitae. Donec tincidunt convallis maximus. Mauris pulvinar sem velit, congue volutpat nisl commodo sit amet. Duis ac est eu orci venenatis lacinia.

if we click on the second textarea . Likewise, we can do that with radio buttons. If we have the following HTML code:

<form>
  <input type='radio' id='choice1' name='choice'> Choice 1
  <input type='radio' id='choice2' name='choice'> Choice 2
</form>

and we modify the JavaScript code slightly like:

const choice1 = document.getElementById('choice1');
const choice2 = document.getElementById('choice2');
const onMouseUp = () => {
  const {
    id,
    value
  } = document.activeElement
  console.log(id);
  console.log(value);
}
choice1.addEventListener('mouseup', onMouseUp, false);
choice2.addEventListener('mouseup', onMouseUp, false);

Then we get the ID of the radio button that was clicked on and the value of the selected radio button, which should always be 'on' since it’s the chosen radio button. For checkboxes, we can write the following HTML code:

<form>
  <input type='checkbox' id='choice1' name='choice'> Choice 1
  <input type='checkbox' id='choice2' name='choice'> Choice 2
</form>

Then we write the following JavaScript:

const choice1 = document.getElementById('choice1');
const choice2 = document.getElementById('choice2');
const onClick = () => {
  const {
    id,
    checked
  } = document.activeElement
  console.log(id);
  console.log(checked);
}
choice1.addEventListener('click', onClick, false);
choice2.addEventListener('click', onClick, false);

In the code above, we switched to listening to the click event to get the right checked value of the currently focused activeElement . We switched from getting the value property to the checked property so that we get the right value for the checkbox.

window.document.fullscreenElement

The fullscreenElement is a read-only property that returns the Element object that’s currently being presented in full screen in the current document, or returns null if full-screen mode isn’t currently in use. It can be used to get the element that has some action done to it to make the browser go full screen. For example, if we have the following HTML:

<!DOCTYPE html>
<html>
  <head>
    <title>Full Screen</title>
  </head>
  <body>
    <img
      src="https://images.unsplash.com/photo-1537498425277-c283d32ef9db?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=757&q=80"
      id="img"
    />
    <script src="main.js"></script>
  </body>
</html>

And then add the following JavaScript code to main.js :

const img = document.getElementById("img");
img.addEventListener("click", async () => {
  await img.requestFullscreen();
  console.log(window.document.fullscreenElement);
});

Then when we click the img element in the HTML page the click event will be triggered, which then will run the click handler we passed into the img.addEventListener method as the second argument. The requestFullScreen which we called on the img object which is the DOM object for the img element we have in the HTML, will make the browser tab go full screen. This will resolve the promise and then the window.document.fullscreenElement will be logged by the console.log . It should log the img element which we clicked to make the browser go full screen since now the img element is presented in full-screen mode after it’s clicked. There’s no guarantee that the full-screen mode operation will succeed. If the permission to go full screen is denied then the promise returned by the requestFullScreen method will be rejected then a fullscreenerror event will be triggered.

The URL , activeElement and the fullscreenElement properties are very useful properties. The URL property lets us get the URL of the currently loaded page as a string. To get the currently focused element, we can use the activeElement property. We get the input, textarea or select elements that’s currently in focus. With the fullscreenElement we can get the DOM element that is shown in full-screen mode. That is the UI element that is being displayed when the browser is in full-screen mode. For example, if we click an image to make the browser go full screen then fullscreenElement is the image we click on since it’s now presented in full-screen mode.

Categories
JavaScript

Introducing the JavaScript Window Object — VisibilityState and Child Elements

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. The document property of the window object has the DOM document and associated nodes and methods that we can use to manipulate the DOM nodes and listen to events for each node. Since the window object is global, it’s available in every part of the application. When a variable is declared without the var , let or const keywords, they’re automatically attached to the window object, making them available to every part of your web app. This is only applicable when strict mode is disabled. If it’s enabled, then declaring variables without var , let , or const will be stopped an error since it’s not a good idea to let us declare global variables accidentally. The window object has many properties. They include constructors, value properties and methods. There’re methods to manipulate the current browser tab like opening and closing new popup windows, etc.

In a tabbed browser, each tab has its own window object, so the window object always represent the state of the currently opened tab in which the code is running. However, some properties still apply to all tabs of the browser like the resizeTo method and the innerHeight and innerWidth properties.

Note that we don’t need to reference the window object directly for invoking methods and object properties. For example, if we want to use the window.Image constructor, we can just write new Image() . In this article, we continue to look at what’s in the window object. In the previous sections, we looked at the constructors and some of the properties of the window object, including using the customElemnts to build a Web Component, and the crypto object to do cryptography on the client using symmetric and asymmetric encryption algorithms. In this part, we will continue from Part 9 and look at more properties of the window.document object, including the visibilityState, childElementCount, and firstElementChild properties.

window.document.visibilityState

The visibilityState property is a read only property that returns the visibility status of the document object in which context this element is now visible. It’s useful for knowing if the document is visible in a background or invisible tab or only loaded for pre-rendering. It’s a string property that can have the following possible values:

  • 'visible' — the page content may at least be partially visible. This means the page is in the foreground tab of a non-minimized window.
  • 'hidden' — the page is not visible to the user. This means that the page is either in a background tab, the window has been minimized, or it’s behind a lock screen.
  • 'prerender' — the page is pre-rendering but not visible to the user. The document may start in this state but can’t transition to another value. This value is removed from the standard so might not be returned by many modern browsers.

For example, to watch for the visibility of a browser tab, we can write the following code:

console.log(document.visibilityState);
document.addEventListener('visibilitychange', () => {
  console.log(document.visibilityState);
})

Then when we split off the browser’s development console from the browser tab, then we switch between tabs while looking at the console.log output from the browser development console without the tab being visible. When we do that, we should see that it logs 'visible' when the browser tab is visible and when you switched out of the tab you’re logging the visibilityState from into another tab then the console.log output will become hidden .

window.document.**childElementCount**

The childElementCount is a read only number property that returns unsigned long number that represents the number of child elements in a given element. For example, if we run:

console.log(document.childElementCount);

Then we should get 1 since the only child of document is the html element.

window.document.children

The get the child elements of document we can use the children property, which is a read only property that returns an HTMLCollection array like object with all the child elements of the document object upon it’s called. For example, if we have the following HTML code:

<div>
  A
</div>
<div>
  B
</div>
<div>
  C
  <div>
    D
  </div>
</div>

Then we can loop through the HTMLCollection object with the for...of loop since it’s an array like object like in the following code:

for (const child of document.children) {
  const {
    tagName,
    outerHTML,
    outerText
  } = child
  console.log(tagName);
  console.log(outerHTML);
  console.log(outerText);
}

Then we get output from the console.log statements. First we get:

HTML

from the first console.log line. Then from the second console.log statement we get the following output:

<html><head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title></title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="robots" content="noindex, nofollow">
  <meta name="googlebot" content="noindex, nofollow">
  <meta name="viewport" content="width=device-width, initial-scale=1">

<script type="text/javascript" src="/js/lib/dummy.js"></script>

<link rel="stylesheet" type="text/css" href="/css/result-light.css">

<style id="compiled-css" type="text/css">

  </style>

<!-- TODO: Missing CoffeeScript 2 -->

<script type="text/javascript">//<![CDATA[

window.onload=function(){

for (const child of document.children) {
  const {
    tagName,
    outerHTML,
    outerText
  } = child
  console.log(tagName);
  console.log(outerHTML);
  console.log(outerText);
}

}

//]]></script>

</head>
<body>
    <div>
  A
</div>
<div>
  B
</div>
<div>
  C
  <div>
    D
  </div>
</div>

<script>
    // tell the embed parent frame the height of the content
    if (window.parent && window.parent.parent){
      window.parent.parent.postMessage(["resultsFrame", {
        height: document.body.getBoundingClientRect().height,
        slug: ""
      }], "*")
    }

// always overwrite window.name, in case users try to set it manually
    window.name = "result"
  </script>

</body></html>

Then from the third console.log line we get:

A
B
C
D

Since we’re getting the children property from the document object, we have the html element as the only child, so we only have one object from the children property.

window.document.**firstElementChild**

The firstElementChild property is a read only property that returns the document ‘s first child. It only has one child which is the html element, so that’s what will be returned. The returned object will be an Element object, which has the properties of an HTML element. If there’s no child then null is returned. An Element object also has the following properties:

  • attributes — a read only property that has the NamedNodeMap object that contains the assigned attributes of the HTML element
  • classList — a read only property that has the list of class attrbiutes.
  • className — a read only string property that has the class of the element
  • cilentHeight — a read only number property that has the inner height of the element
  • clientLeft — a read only number property that has the width of the left border of the element
  • clientTop — a read only number property that has the width of the top border of the element
  • cilentWidth — a read only number property that has the inner width of the element
  • computedName — a read only string property that has the label exposed to accessibility.
  • computedRole — a read only string property that has the ARIA role that’s applied to the particular element.
  • id — a string that has the ID of the element
  • innerHTML — a string that has the HTML markup of the element’s content
  • localName — a read only string that has the local part of the qualified name of the element
  • namespaceURI — a read only property that has the namespace URL of them element or null if there’s no namespace
  • nextElementSibling — a read only property that has another Element object that represents the element which immediately follows the current element, or null if there’s no sibling node.
  • outerHTML — a string that represents the markup of the element including its content. It can also be set so that it replaces the content of the element with the HTML that we assign to this property
  • part — has the part identifiers which are set using the part attribute.
  • prefix — a read only string property that has the namespace prefix of the element, or null if no prefix is specified
  • previousElementSibling— a read only property that has another Element object that represents the element which is immediately before the current element, or null if there’s no such node.
  • scrollHeight — a read only number property that has the scroll view height of the element
  • scrollLeft — a number property that has the left scroll offset of the element. This can be getter or a setter
  • scroolLeftMax — a read only number property that has the maximum left scroll offset possible for the element
  • scrollTop — a number property that has the number of pixels of the top of the document that’s scrolled vertically
  • scrollTopMax — a read only property hat has the maximum top scroll offset possible for the element
  • scrollWidth — a read only number property that has the scroll view width of the element
  • shadowRoot — a read only property that has the open shadow root that’s hosted by the element, or null if no open shadow root is present
  • openOrClosedShadowRoot — a read only property that’s only available WebExtensions that has the shadow root hosted by the element regardless of status.
  • slot — the name of the shadow DOM slot the element is inserted in
  • tabStop — a boolean property that indicates if the element can receive input focus by pressing the tab key
  • tagName — a read only with the string that has the tag name of the given element

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

console.log(document.firstElementChild);

Then we should get something like:

<body>
    <div>
  A
</div>
<div>
  B
</div>
<div>
  C
  <div>
    D
  </div>
</div>

<script>
    // tell the embed parent frame the height of the content
    if (window.parent && window.parent.parent){
      window.parent.parent.postMessage(["resultsFrame", {
        height: document.body.getBoundingClientRect().height,
        slug: ""
      }], "*")
    }

// always overwrite window.name, in case users try to set it manually
    window.name = "result"
  </script>

</body>

We can also get the individual properties of the html Element object like in the following code:

const {
  clientLeft,
  innerHTML,
  outerHTML
} = document.firstElementChild;

console.log(clientLeft);
console.log(innerHTML);
console.log(outerHTML);

Then we should get the width of the left border of the html element which is 0 and get the HTML content of the document logged for the last 2 console logs.

With the document object, we have some handy properties to let us get the elements in the document by using its handy properties. The visibilityState property let us know if the browser tab’s document is visible or not. The childElementCount property get us the number of child elements of the document object which should be 1 since the document object’s only child is the html element. The firstElementChild property should get us the first child element of the document object which should be the html element since it’s the only child element of the document object.

Categories
JavaScript

Introducing the JavaScript Window Object -Design Mode and More

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. The document property of the window object has the DOM document and associated nodes and methods that we can use to manipulate the DOM nodes and listen to events for each node. Since the window object is global, it’s available in every part of the application. When a variable is declared without the var , let or const keywords, they’re automatically attached to the window object, making them available to every part of your web app. This is only applicable when strict mode is disabled. If it’s enabled, then declaring variables without var , let , or const will be stopped an error since it’s not a good idea to let us declare global variables accidentally. The window object has many properties. They include constructors, value properties and methods. There’re methods to manipulate the current browser tab like opening and closing new popup windows, etc.

In a tabbed browser, each tab has its own window object, so the window object always represent the state of the currently opened tab in which the code is running. However, some properties still apply to all tabs of the browser like the resizeTo method and the innerHeight and innerWidth properties.

Note that we don’t need to reference the window object directly for invoking methods and object properties. For example, if we want to use the window.Image constructor, we can just write new Image() . In this article, we continue to look at what’s in the window object. In the previous sections, we looked at the constructors and some of the properties of the window object, including using the customElements to build a Web Component, and the crypto object to do cryptography on the client using symmetric and asymmetric encryption algorithms. In this part, we will continue from Part 11 and look at more properties of the window.document object, including the defaultView , designMode , dir, domain, and lastModified properties.

window.document.defaultView

The defaultView property is a read only property that returns the window object associated with the current document, or null if it’s not available. For example, if we run the following code to log the document.defaultView object:

console.log(document.defaultView);

We should get something like:

alert: ƒ alert()  
applicationCache: ApplicationCache {status: 0, oncached: null, onchecking: null, ondownloading: null, onerror: null, …}  
atob: ƒ atob()  
blur: ƒ ()  
btoa: ƒ btoa()  
caches: CacheStorage {}  
cancelAnimationFrame: ƒ cancelAnimationFrame()  
cancelIdleCallback: ƒ cancelIdleCallback()  
captureEvents: ƒ captureEvents()  
chrome: {loadTimes: ƒ, csi: ƒ}  
clearInterval: ƒ clearInterval()  
clearTimeout: ƒ clearTimeout()  
clientInformation: Navigator {vendorSub: "", productSub: "20030107", vendor: "Google Inc.", maxTouchPoints: 0, hardwareConcurrency: 4, …}  
close: ƒ ()  
closed: false  
confirm: ƒ confirm()  
createImageBitmap: ƒ createImageBitmap()  
crypto: Crypto {subtle: SubtleCrypto}  
customElements: CustomElementRegistry {}  
...

where the list of properties goes on for much longer than the abridged output above.

window.document.designMode

The designMode property controls whether is the entire document is editable. We can either set it to 'on' or 'off' . In Internet Explorer 6 to 10, the values are capitalized. Earlier versions of Chrome and Internet Explorer defaults to 'inherit' , but the 'inherit' value is no longer supported. Starting with Chrome 43, the default is 'off' . For example, if we have the following code HTML code:

<div>  
  <p>  
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus non pharetra dolor. Fusce gravida enim nec lectus rutrum bibendum. Duis mattis nisl tristique, tincidunt mauris ac, ornare lectus. Praesent non massa tristique magna placerat sagittis at consectetur libero. Maecenas varius urna in odio faucibus, at elementum lorem tempor. Duis metus enim, finibus sed ante at, mollis posuere elit. Maecenas elementum tristique vulputate. Curabitur eleifend vehicula congue. Nam bibendum augue sit amet dui egestas, quis ultrices ipsum blandit. Nulla arcu tortor, fringilla eu luctus ac, porta nec sem.  
  </p>

<p>  
    Sed mauris odio, cursus quis lacus at, vulputate varius nisl. Praesent eget accumsan mauris. In gravida magna non ante ultrices, vel egestas enim pulvinar. Duis pulvinar volutpat ex. Donec ac lectus non sapien gravida egestas nec non sapien. Aenean eu vehicula dui, eu aliquam leo. Vivamus viverra tempor lacus, nec venenatis quam blandit a. Mauris viverra diam quis euismod elementum. Aenean quis sapien sit amet metus tempus auctor et vel elit. Morbi blandit libero ac massa laoreet auctor. Aliquam in massa eu nulla varius dictum non ut purus.  
  </p>  
</div>

and in our JavaScript code, we write the following code to set designMode to 'on' :

document.designMode = 'on';

Then we can edit the text that are displayed on the screen in the browser. This flag is very handy for fiddling with the content of the page. Once we refresh the page, we get back to the output that we have rendered from our saved code, so we don’t have to worry about it doing anything undesirable that’s permanent.

window.document.dir

The dir property of the document object is a read only property that returns a string that represents the direction of the text of the document, whether it’s left to right which is the default, or right to left. The possible values are 'rtl' for right to left and 'ltr' for left to right. For example, we can log the dir property with the following code:

console.log(document.dir);

Then we should get 'ltr' for most English pages in most browsers.

window.document.domain

The domain property let us get and set the domain part of the origin of the current document. If the document is inside a sandboxed iframe , the document has no browsing context, the effective domain is null , the given value isn’t equal to the document’s effective domain (which is the origin’s host or domain), or document-domain Feature-Policy is enabled, then a SecurityError will be thrown when document.domain is attempted to be set. The assignment is stopped in the cases above to prevent violation of the same origin policy and to prevent third party code from running in unauthorized locations. For example, if we run:

document.domain = 'mozilla.org';

in the developer’s console on a website that doesn’t have mozilla.org as the domain, then we will get the SecurityError . If we run it on mozilla.org , then the assignment will succeed. We can also use document.domain as a getter. If we run document.domain on https://developer.mozilla.org/en-US/docs/Web/API/Document then we get “developer.mozilla.org” .

window.document.lastModified

To get the date and time on which the current document was last modified, we can use the document object’s lastModified property. It’s a read only property that returns a string of when the document was last modified. For example, we can log it as is and get the date string of the object like we do in the code below:

console.log(document.lastModified);

We should get something like:

11/10/2019 13:22:54

as the output of the console.log . We can also convert it into a Date object by passing it straight into the Date object like in the following code:

console.log(new Date(document.lastModified));

Then we get something like:

Sun Nov 10 2019 13:24:06 GMT-0800 (Pacific Standard Time)

from the console.log output. We can also convert it to milliseconds since January 1, 1970 by using the Number function, the Date.parse method or the unary + operator in front of the date object like in the following code:

console.log(+new Date(document.lastModified));  
console.log(Number(new Date(document.lastModified)));  
console.log(Date.parse(document.lastModified));

All 3 lines of code above should get us the same milliseconds value, something like 1573421113000 .

In this article, we looked at the defaultView , designMode , dir, domain, and lastModified properties. The defaultView property is a read only property that returns the window object associated with the current document. The domain property let us get and set the domain part of the origin of the current document. The designMode property controls whether is the entire document is editable. This property is handy since we can set it to 'on' when we want to fiddle with the page without saving anything. The dir property of the document object is a read only property that returns a string that represents the direction of the text of the document. To get the date and time on which the current document was last modified, we can use the document object’s lastModified property and convert it to a Date object or change it to milliseconds since January 1, 1970.