Categories
Quasar

Developing Vue Apps with the Quasar Library — Split Screen Options

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.

Horizontal Split Screen

We can make a split-screen that’s split horizontally by adding the horizontal prop.

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 horizontal 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>

v-model is bound to the splitterModel reactive property is the height of the top panel as a percentage.

Drag Limit

We can set the min and max value for the split-screen by setting the limit prop:

<!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
            :limits="[50, 100]"
            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>

We set the limits prop to an array with the min and max percentage of the screen that the left panel takes up.

Split Screen Panel Units

We can change the unit of the size for the panels by setting the unit prop:

<!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 unit="px" 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: 150
        }
      });
    </script>
  </body>
</html>

The unit prop is set to 'px' to change the unit of splitterModel to pixels.

Conclusion

We can add split-screen panels with various options into our Vue app with Quasar.

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.