Categories
JavaScript

What can we build with JavaScript?

From its simple beginnings as a language to do browser-side scripting, JavaScript has evolved a lot since the first version of the language. There’re now lots of things that we can build with JavaScript that we can’t do before. Here’re some things that we can build with JavaScript today.

Client-Side Apps

JavaScript is still the only language for browser-side web applications. The proliferation of app frameworks like React, Angular, and Vue have made things infinitely easier. Also with ES6+, building client-side apps with JavaScript has been much more pleasant than before. Any other language like TypeScript has to be converted to plain JavaScript before they can run in browsers. All modern browsers support JavaScript and nothing else, so it’s the only language for client-side applications.

Server-Side Web Apps

With Node.js, JavaScript has arrived on the server-side. We can do so much with Node.js, like building a back-end app. There’re various back end frameworks like Express, Nest.js, and many other frameworks that let us write back end apps with ease. It’s so popular that popular hosts like Amazon Web Services have provided SDKs for Node.js, so we can integrate with their services without a hitch. It’s also pretty fast and easy to build back end apps with it.

There’re libraries for interacting with most popular database systems like MySQL and Postgres so we can easily use it for back end apps. If we want NoSQL, there’s also tight MongoDB integration with libraries like Mongoose which lets us interact with MongoDB and provides a schema to save dynamic data.

Presentations

With Reveal.js and Eagle.js, we can use it easily to build presentations with HTML, CSS, and JavaScript. It provides as much flexibility as PowerPoint but they cost nothing. This is great since it hasn’t been to easy to build presentations with code before these libraries existed.

Scripts

Once again, Node.js provides a great run-time environment for running scripts. With the fs module, we can do lots of common file and folder operations like add, changing, renaming, and deleting files. Also, changing permissions is easy with it. It also has the child_process module to run processes on any computer the script is running.

Also, Node.js is aware of the differences between Windows and Unix-like systems like Linux and Mac OS, so compatibility issues are minimal when running scripts on any computer.

Games

With HTML5, add interactivity to web pages is easier than ever. This is coupled with the power of JavaScript to make everything dynamic. The Canvas API has lots of methods to draw whatever we want and make them animate.

There’re also game frameworks like Phaser which abstracts out some of the more tedious parts like handling inputs and animations of shapes by abstracting things out into a framework.

Mobile Apps

There’re 2 ways to build mobile apps with JavaScript. One is to write a native app with frameworks like React Native, and the other is to write a hybrid with frameworks like Ionic.

React Native lets us write our app’s code in JavaScript and then compile it into a native mobile app by converting the JavaScript React components into native components of the platforms you’re targeting. Since the framework builds code into native apps, accessing hardware is easier to React Native. It provides built-in support for cameras and accelerometers for example.

Hybrid app frameworks like Ionic let us write apps with HTML, CSS, and JavaScript and then display the code in a browser web view on our mobile devices. Accessing hardware requires native plugins which makes development and testing more difficult. Native plugins are also limited or buggy which is another problem if we try to build apps that need to access hardware with it.

They’re both cross-platform frameworks that let us write our code once and then build them for different platforms.

Internet of Things Programs

We can use JavaScript to build programs that control embedded hardware with frameworks like the Johnny-Five framework. It supports the Arduino single-board computer which we normal load C programs with it.

With Johnny-Five, we can use JavaScript to write our programs which makes writing useful programs a lot easier. It supports full hardware access like LEDs, timers, GPS, motors, buttons and switches, compasses, and more. Of course, this is also thanks to the existence of Node.js since it lets us run JavaScript programs outside the browser.

Desktop Apps

With Electron, we can write desktop apps with JavaScript easily. We can convert React, Angular or Vue apps into Windows, Linux, or Mac OS apps with Electron libraries for these frameworks.

We can also write apps with just the Electron framework alone. It can access things like our computer’s file system so it can do things that a normal desktop program does. However, access to specialized hardware is lacking so it’s more for general business apps. Lots of programs are built with Electron, with the biggest examples being Slack, Visual Studio Code, and the Atom text editor.

We can do a lot with JavaScript. Thanks to Node.js, JavaScript can leave the browser, letting us build apps for Internet of Things devices, back end apps, desktop apps and more. On the browser side, we can use it to build interactive apps like games and rich business apps. We can also make great presentations with it.

Categories
JavaScript JavaScript Basics

What are Holes in Arrays?

One special feature of JavaScript arrays is that not every slot in the array has to be filled with values. This means that we can skip values as follows:

let arr = [];  
arr[1] = 1;  
arr[10] = 10;

We don’t have to worry about setting values for other slots of the array.

There’s also an alternative syntax for doing the above, by writing:

[, 1, , 2];

What we have above are called holes of an array, where we have nothing between the commas. An array with holes is called a sparse array.

In this piece, we’ll look at how holes in arrays are handled in JavaScript.


Checking for Values in Arrays

We can check for holes in arrays with the in operator. To do this, we can write something like the following code:

const arr = [, 1, , 2];  
1 in arr;

We should get true returned from the last line since 1 is in the array.

ES6 treat holes in arrays as undefined entries. So if we want to check for holes in the array, check for undefined.

Iterators and generators also treat holes as undefined. For example, if we have

const arr = [, 1, , 2];  
const iter = arr[Symbol.iterator]()

for (let a of iter) {  
  console.log(a);  
}

we get

undefined  
1  
undefined  
2

If we call next to get the next item, as follows,

iter.next();

we get

{value: undefined, done: false}

for the first entry.

Likewise, if we have the given generator,

function* generator () {  
  const arr = [, 1, , 2];  
  for (let a of arr) {  
    yield a;  
  }  
}

for (let a of generator()) {  
  console.log(a);  
}

we get the same thing.


Array.from()

Array.from() treats holes as undefined like with iterators and generators.

For example, if we have

const arr = [, 1, , 2];  
const arrFrom = Array.from(arr);

then we get that the value of arrFrom is

[undefined, 1, undefined, 2]

Likewise, if we create an array from array-like objects, where we have non-negative integers as keys and a length property with a non-negative number as a value, missing entries are also treated as undefined.

For example, if we run

const arrFrom = Array.from({  
  1: 'foo',  
  length: 2  
});

we get the value of arrFrom as

[undefined, "foo"]

How Array.prototype Methods Treat Holes

The behavior of these methods differs with different versions of JavaScript. In ES5, they’re the following:

  • forEach, filter, every, and some ignore holes.
  • map skips but preserves holes.
  • join and toString treat holes as if they were undefined elements but treat both null and undefined as empty strings.

The following is a full list of methods and how they deal with holes. Each method acts differently.

  • concat — keeps holes
  • copyWithin — holes are copied
  • entries, keys, values — treats holes as undefined
  • every — ignores holes
  • fill — fills holes
  • filter — removes holes
  • find — treats holes as elements
  • findIndex — treats holes as elements
  • forEach — ignores holes
  • indexOf — ignores holes
  • join — converts holes to empty strings
  • lastIndexOf — ignores holes
  • map — preserves holes
  • pop — treat holes as elements
  • push — preserves holes
  • reduce , reduceRight— ignores holes
  • reverse — preserves holes
  • shift — treat holes as undefined
  • slice — preserves holes
  • sort — preserves holes
  • toString — preserves holes
  • unshift — preserves holes
  • values — converts holes to undefined

When arrays are sparse, they have holes. They’re iterated through as undefined, but each array prototype method treats holes differently, so we have to be careful when defining arrays with holes and dealing with them.

We can use the in operator to check if a given entry is in an array.

Array.from() also treats holes as undefined and turns holes into undefined when converting arrays or array-like objects with holes into arrays.

Categories
JavaScript TypeScript

TypeScript Advanced Types — Type Guards

TypeScript has many advanced type capabilities which make writing dynamically typed code easy. It also facilitates the adoption of existing JavaScript code since it lets us keep the dynamic capabilities of JavaScript while using the type-checking capabilities of TypeScript.

There are multiple kinds of advanced types in TypeScript, like intersection types, union types, type guards, nullable types, and type aliases, and more. In this article, we’ll look at type guards.


Type Guards

To check if an object is of a certain type, we can make our own type guards to check for members that we expect to be present and the data type of the values. To do this, we can use some TypeScript-specific operators and also JavaScript operators.

One way to check for types is to explicitly cast an object with a type with the as operator. This is needed for accessing a property that’s not specified in all the types that form a union type.

For example, if we have the following code:


interface Person {
  name: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let person: Person | Employee = {
  name: 'Jane',
  age: 20,
  employeeCode: '123'
};
console.log(person.name);

Then the TypeScript compiler won’t let us access the name property of the person object since it’s only available in the Person type but not in the Employee type. Therefore, we’ll get the following error:

Property 'name' does not exist on type 'Person | Employee'.Property 'name' does not exist on type 'Employee'.(2339)

In this case, we have to use the type assertion operator available in TypeScript to cast the type to the Person object so that we can access the name property, which we know exists in the person object.

To do this, we use the as operator, as we do in the following code:

interface Person {
  name: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let person: Person | Employee = {
  name: 'Jane',
  age: 20,
  employeeCode: '123'
};
console.log((person as Person).name);

With the as operator, we explicitly tell the TypeScript compiler that the person is of the Person class, so that we can access the name property which is in the Person interface.


Type Predicates

To check for the structure of the object, we can use a type predicate. A type predicate is a piece code where we check if the given property name has a value associated with it.

For example, we can write a new function isPerson to check if an object has the properties in the Person type:

interface Person {
  name: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let person: Person | Employee = {
  name: 'Jane',
  age: 20,
  employeeCode: '123'
};
const isPerson = (person: Person | Employee): person is Person => {
  return (person as Person).name !== undefined;  
}
if (isPerson(person)) {
  console.log(person.name);  
}
else {
  console.log(person.employeeCode);  
}

In the code above, the isPerson returns a person is Person type, which is our type predicate.

If we use that function as we do in the code above, then the TypeScript compiler will automatically narrow down the type if a union type is composed of two types.

In the if (isPerson(person)){ ... } block, we can access any member of the Person interface.

However, this doesn’t work if there are more than two types that form the union type. For example, if we have the following code:

interface Animal {
  kind: string;
}
interface Person {
  name: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let person: Person | Employee | Animal = {
  name: 'Jane',
  age: 20,
  employeeCode: '123'
};
const isPerson = (person: Person | Employee | Animal): person is Person => {
  return (person as Person).name !== undefined;  
}
if (isPerson(person)) {
  console.log(person.name);  
}
else {
  console.log(person.employeeCode);  
}

Then the TypeScript compiler will refuse to compile the code and we’ll get the following error messages:

Property 'employeeCode' does not exist on type 'Animal | Employee'.Property 'employeeCode' does not exist on type 'Animal'.(2339)

This is because it doesn’t know the type of what’s inside the else clause since it can be either Animal or Employee. To solve this, we can add another if block to check for the Employee type as we do in the following code:

interface Animal {
  kind: string;
}
interface Person {
  name: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let person: Person | Employee | Animal = {
  name: 'Jane',
  age: 20,
  employeeCode: '123'
};
const isPerson = (person: Person | Employee | Animal): person is Person => {
  return (person as Person).name !== undefined;  
}
const isEmployee = (person: Person | Employee | Animal): person is Employee => {
  return (person as Employee).employeeCode !== undefined;  
}
if (isPerson(person)) {
  console.log(person.name);  
}
else if (isEmployee(person)) {
  console.log(person.employeeCode);  
}
else {
  console.log(person.kind);  
}

In Operator

Another way to check the structure to determine the data type is to use the in operator. It’s like the JavaScript in operator, where we can use it to check if a property exists in an object.

For example, to check if an object is a Person object, we can write the following code:

interface Animal {
  kind: string;
}
interface Person {
  name: string;
  age: number;
}
interface Employee {
  employeeCode: string;
}
let person: Person | Employee | Animal = {
  name: 'Jane',
  age: 20,
  employeeCode: '123'
};
const getIdentifier = (person: Person | Employee | Animal) => {
  if ('name' in person) {
    return person.name;
  }
  else if ('employeeCode' in person) {
    return person.employeeCode
  }
  return person.kind;
  
}

In the getIdentifier function, we used the in operator as we do in ordinary JavaScript code. If we check the name of a member that’s unique to a type, then the TypeScript compiler will infer the type of the person object in the if block as we have above.

Since name is a property that’s only in the Person interface, then the TypeScript compiler is smart enough to know that whatever inside is a Person object.

Likewise, since employeeCode is only a member of the Employee interface, then it knows that the person object inside is of type Employee.

If both types are eliminated, then the TypeScript compiler knows that it’s Animal since the other two types are eliminated by the if statements.


Typeof Type Guard

For determining the type of objects that have union types composed of primitive types, we can use the typeof operator.

For example, if we have a variable that has the union type number | string | boolean, then we can write the following code to determine whether it’s a number, a string, or a boolean. For example, if we write:

const isNumber = (x: any): x is number =>{
    return typeof x === "number";
}
const isString = (x: any): x is string => {
    return typeof x === "string";
}
const doSomething = (x: number | string | boolean) => {
  if (isNumber(x)) {
    console.log(x.toFixed(0));
  }
  else if (isString(x)) {
    console.log(x.length);
  }
  else {
    console.log(x);
  }
}
doSomething(1);

Then we can call number methods as we have inside the first if block since we used the isNumber function to help the TypeScript compiler determine if x is a number.

Likewise, this also goes for the string check with the isString function in the second if block.

If a variable is neither a number nor a string then it’s determined to be a boolean since we have a union of the number, string, and boolean types.

The typeof type guard can be written in the following ways:

  • typeof v === "typename"
  • typeof v !== "typename"

Where “typename” can be be "number", "string", "boolean", or "symbol".


Instanceof Type Guard

The instanceof type guard can be used to determine the type of instance type.

It’s useful for determining which child type an object belongs to, given the child type that the parent type derives from. For example, we can use the instanceof type guard like in the following code:

interface Animal {
  kind: string;
}
class Dog implements Animal{
  breed: string;
  kind: string;
  constructor(kind: string, breed: string) {    
    this.kind = kind;
    this.breed = breed;
  }
}
class Cat implements Animal{
  age: number;
  kind: string;
  constructor(kind: string, age: number) {    
    this.kind = kind;
    this.age = age;
  }
}
const getRandomAnimal = () =>{
  return Math.random() < 0.5 ?
    new Cat('cat', 2) :
    new Dog('dog', 'Laborador');
}
let animal = getRandomAnimal();
if (animal instanceof Cat) {
  console.log(animal.age);
}
if (animal instanceof Dog) {
  console.log(animal.breed);    
}

In the code above, we have a getRandomAnimal function that returns either a Cat or a Dog object, so the return type of it is Cat | Dog. Cat and Dog both implement the Animal interface.

The instanceof type guard determines the type of the object by its constructor, since the Cat and Dog constructors have different signatures, it can determine the type by comparing the constructor signatures.

If both classes have the same signature, the instanceof type guard will also help determine the right type. Inside the if (animal instanceof Cat) { ... } block, we can access the age member of the Cat instance.

Likewise, inside the if (animal instanceof Dog) {...} block, we can access the members that are exclusive to the Dog instance.


Conclusion

With various type guards and type predicates, the TypeScript compiler can narrow down the type with conditional statements.

Type predicate is denoted by the is keyword, like pet is Cat where pet is a variable and Cat is the type. We can also use the typeof type guard for checking primitive types, and the instanceof type guard for checking instance types.

Also, we have the in operator checking if a property exists in an object, which in turn determines the type of the object by the existence of the property.

Categories
JavaScript JavaScript Basics

Using HTML Audio and Video Elements

With HTML5, we are provided numerous tools and tags to work with multimedia. One of the new things that come with HTML5 is the ability to embed audio and video without needing plugins like Flash.

In this article, we’ll look at how to add audio and video elements to a web page and control it with JavaScript.

Adding Audio or Video Elements

To add audio and video elements, we use the audio and video tags respectively. They have a few attributes. They are:

  • autoplay — specifies whether the audio or video will play automatically
  • controls — specifies whether playback controls are shown
  • loop — specifies whether we want to play the clip again once it ends
  • muted — specifies if sound should play or not
  • preload — specifies which part of the clip should be preloaded. It can be auto , which loads everything, metadata, which loads only the metadata, or none, which loads nothing
  • src — the URL for the clip

To embed audio in our web pages, we can write the following:

<audio controls>  
  <source src="https://file-examples.com/wp-content/uploads/2017/11/file_example_OOG_1MG.ogg" type="audio/ogg">  
  <source src="https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_700KB.mp3" type="audio/mpeg">  
  Your browser does not support the audio tag.  
</audio>

In the code above, we specified the audio in different formats of the audio that we want to load.

Likewise, we can do the same with video:

<video controls width="250">  
  <source src="https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4" type="video/mp4">  
  Your browser does not support the video tag.  
</video>

In both pieces of code, then text within the tag is the fallback text in case the browser doesn’t support these tags.

Controlling the Elements with JavaScript

We can customize the functionality of the audio or video element with JavaScript code. The following are methods are available for controlling the playback of audio or video elements:

  • play — start playing the audio or video
  • pause — pausing the audio or video
  • load — reload the audio or video element
  • addTextTrack — add a text track to audio or video
  • canPlayType — check if the browser can play the specified type of audio or video

There’re also some properties that we can set the control the audio or video playback:

  • currentTime — sets the current time of the audio or video in seconds
  • defaultMuted — indicate whether the audio output should be muted by default
  • defaultPlaybackRate — a number indicating the default playback for the media
  • loop — boolean indicating whether we want restart playback after it ends
  • muted — boolean we can set for muting the audio
  • playbackRate — sets the playback rate of the clip
  • volume — change the volume of the audio or video

We can use these methods and value properties as follows. First, we add our clip into our HTML code:

<video controls width="250">  
  <source src="https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4" type="video/mp4">  
  Sorry, your browser doesn't support embedded videos.  
</video>

Then we can add buttons to change various things like the playback rate or muting the audio as follows. First, we add some buttons to let us click to change the settings:

<button id='fast-button'>1.5x speed</button>
<button id='fastest-button'>2x speed</button>
<button id='mute'>Toggle Mute  </button>

Then we add some code to get the button and video elements and set the settings accordingly.

const fastButton = document.querySelector('#fast-button');  
const fastestButton = document.querySelector('#fastest-button');  
const muteButton = document.querySelector('#mute');  
const video = document.querySelector('video');

fastButton.onclick = () => {  
  video.playbackRate = 1.5  
}

fastestButton.onclick = () => {  
  video.playbackRate = 2  
}

muteButton.onclick = () => {  
  video.muted = !video.muted;  
}

In the code above, we get the elements and then in the click event handlers for the buttons, we set the playbackRate and toggle the muted properties for the video.

We can do something similar with the methods. For example, we can add the following buttons:

<button id='play'>Play</button>
<button id='pause'>Pause</button>

Then we can add the following buttons click handlers to play and pause the clip programmatically:

playButton.onclick = () => {  
  video.play();  
}

pauseButton.onclick = () => {  
  video.pause();  
}

This is handy for creating custom video and audio players that don’t use the default browser style, along with the controls attribute for showing or hiding the controls.

Another example is making a seek bar for our clip. We can do that by adding a range slider as follows:

<input type="range" name="time" id='time' min='0'>

Then we can set the max attribute of the slider to the duration of our clip and add an onchange event handler as follows:

timeInput.max = video.duration  
timeInput.onchange = (e) => {  
  video.currentTime = e.target.value;  
}

The let us seek to anywhere from the start to the end of the video as we slide back and forth with the slider.

Events

Audio and video elements also have the following events fired, so we can handle them with event handlers we wish to:

  • canplay — the browser can play the media, but estimates that not enough data will be available to finish playback without stopping to buffer.
  • canplaythrough — browser estimates that playback finish without stopping for more buffering
  • complete — playback ends
  • durationchange — duration has been updated
  • emptied — media has become empty
  • ended — playback ended before the end of the clip was reached
  • loadeddata — the first frame has finished loading
  • loadedmetadata — metadata has been loaded
  • pause — playback is paused
  • play — playback began
  • playing — playback is ready to start after having been paused or delayed due to lack of data
  • progress — fired periodically as browser loads a resource
  • ratechange — playback rate changed
  • seeked —seek operation completed
  • seeking — seek operation began
  • stalled —a user-agent tries to fetch media data, but nothing is coming in
  • suspend — media data loading has been suspended
  • timeupdate — the time indicated by the currentTime attribute has been updated
  • volumechange — volume changed
  • waiting — playback stopped because of a temporary lack of data
Categories
JavaScript JavaScript Basics

Using Design Mode and execCommand to Fiddle with Web Pages

To make fiddling with the design of webpages easy, modern browsers have a design mode built-in. We can toggle it on with the document.designMode property set to 'on' .

Furthermore, we can send commands to change the page when it’s design mode with the document.execCommand method.

In this article, we’ll look at how to use the document.execCommand method to change web pages in design mode on the fly.

Usage

The document.execCommand method takes 3 arguments. The syntax is the following:

document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)

The parameters are:

  • aCommandName — a string specifying the name of the command to run.
  • aShowDefaultUI — a boolean indicating whether the default user interface should be shown. This isn’t supported in Mozilla
  • aValueArgument — a string that provides information for commands requires input. For example, a URL for an image is required for the insertImage command.

It returns false if a command is unsupported or disabled.

We can run the commands from the browser console or in our code. The changes will be cleared once we refresh.

Commands

The follows commands can be run with execCommand :

backColor

Changes the background color of the block that’s selected.

We can change the selected background to blue as follows:

document.execCommand('backColor', false, 'blue');

bold

Toggle selected text’s boldness on and off.

For example, we can use it as follows:

document.execCommand('bold')

ClearAuthenticationCache

Clears authentication credentials from the cache.

For instance, we can run:

document.execCommand("ClearAuthenticationCache","false");

to make sure that we have to authenticate again.

contentReadOnly

Marks content as read-only or editable. A boolean is required as the value argument. This isn’t supported by Internet Explorer.

We can use it like the following code:

document.execCommand('contentReadOnly', false, true)

copy

Copies the current selection to the clipboard. Support may vary between browsers.

For example, we can write:

document.execCommand('copy')

createLink

Create a link from the selection. A URI string is required in the value argument to set the link’s href attribute. The URI must at least have 1 character which may be whitespace. IE will also create a link with a null value.

We can use it as follows:

document.execCommand('createLink', true, 'http://www.google.com')

cut

Remove the selected text and copied it to the clipboard. Support may vary between browsers.

We can use it as follows:

document.execCommand('cut')

decreaseFontSize

Add a small tag around the select text. This command isn’t supported by IE.

For example, we can use it by writing:

document.execCommand('decreaseFontSize')

defaultParagraphSeparator

Change the paragraph separator used when new paragraphs are created in editable text regions.

We can use by writing:

document.execCommand('defaultParagraphSeparator', false, 'br')

to change the separator to br .

delete

Deletes the current selection. We can use it by writing:

document.execCommand('delete')

enableAbsolutePositionEditor

Toggle the grabber that allows absolutely positioned elements to be moved around. It’s disabled by default in Firefox 63 beta or dev editions.

We can use it by running:

document.execCommand('enableAbsolutePositionEditor', true, true)

fontName

Change the font name for the selection or at the insertion point.

For example, we can use it by writing:

document.execCommand('fontName', true, 'Arial')

foreColor

Change the font color for the selection or insertion point. A hexadecimal color value is required as the value argument.

For example, we can write:

document.execCommand('foreColor', true, '#4287f5')

formatBlock

Add an HTML block-level element around the line containing the current selection.

We can use it by writing:

document.execCommand('formatBlock', true, 'blockquote')

Where 'blockquote' can be replaced by other block-level elements.

forwardDelete

Deletes the character ahead of the cursor’s position. It’s the same as hitting the Delete key on a Windows keyboard.

For example, we can use it by running:

document.execCommand('forwardDelete')

heading

Add a heading element around the selection or insertion point line. Requires the tag name string as the value argument. This command isn’t supported by IE or Safari.

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

document.execCommand('heading', true, 'H1')

hiliteColor

Change the background color for the selection or at the insertion point. It requires a color value string as a value argument. It’s not supported by IE.

We can run:

document.execCommand('hilitecolor', true, 'red')

to change the highlight color to red.

increaseFontSize

Add a big tag around the selector or at the insertion point. It’s not supported by IE.

document.execCommand('increaseFontSize')

indent

Indent the line containing the selection or insertion point. The least indented line will be indented if there’re multiple lines at different levels of indentation.

We can run:

document.execCommand('indent')

to indent the text.

insertBrOnReturn

insertBrOnReturn adds a line break or <br> element. It’s not supported by IE.

We can run:

document.execCommand('insertBrOnReturn')

insertHorizontalRule

Insert an hr element at the insertion point or replace the selection with it.

We can run:

document.execCommand('insertHorizontalRule')

insertHTML

Insert an HTML string at the insertion point, which deletes the selection. It’s not supported by IE, and requires valid HTML string.

We can run it by typing in:

document.execCommand('insertHTML', false, '<b>foo</b>')

insertImage

Inserts an image at the insertion point. A URL for the string is required for the src attribute of the image.

For example, we can run:

document.execCommand('insertImage', false, 'https://images.unsplash.com/photo-1496096265110-f83ad7f96608?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80')

insertOrderedList

Inserts a numbered ordered list for the selection or at the insertion point.

We can use it as follows:

document.execCommand('insertOrderedList');

insertUnorderedList

Inserts a bulleted unordered list for the selection or at the insertion point.

We can use it as follows:

document.execCommand('insertUnorderedList');

insertParagraph

Add a paragraph around the selection or the current line. IE inserts a paragraph at the insertion point and deletes the selection.

We can use it as follows:

document.execCommand('insertParagraph');

insertText

Adds the given plain text at the insert point and deletes the selection.

We can use it as follows:

document.execCommand('insertText');

italic

Toggle italics on and off for the selection or at the insertion point. IE uses em instead of i .

document.execCommand('italic');

justifyCenter

Centers the selection or insertion point.

We can use it as follows:

document.execCommand('justifyCenter');

justifyFull

Justifies the selection or insertion point.

We can use it as follows:

document.execCommand('justifyFull');

justifyLeft

Left justifies the selection or insertion point.

We can use it as follows:

document.execCommand('justifyLeft');

justifyRight

Right justifies the selection or the insertion point.

We can use it as follows:

document.execCommand('justifyRight');

outdent

Outdents the line containing the selection or insertion point.

We can use it as follows:

document.execCommand('outdent');

paste

Paste the clipboard content at the insertion and replaces the current selection. It’s disabled for web content.

We can use it as follows:

document.execCommand('paste');

redo

Redo a previously undone command.

We can use it as follows:

document.execCommand('redo');

removeFormat

Removes all formatting from the current selection.

We can use it as follows:

document.execCommand('removeFormat');

selectAll

Selects all the content of the editable region.

We can use it as follows:

document.execCommand('selectAll');

strikeThrough

Toggle strikethrough on or off for the selection or insertion point.

We can use it as follows:

document.execCommand('strikeThrough');

subscript

Toggle subscript on or off for the selection or insertion point.

We can use it as follows:

document.execCommand('subscript');

superscript

Toggle superscript on or off for the selection or insertion point.

We can use it as follows:

document.execCommand('superscript');

underline

Toggle underline on or off for the selection or insertion point.

We can use it as follows:

document.execCommand('underline');

undo

Undo to the last run command.

We can use it as follows:

document.execCommand('undo');

unlink

Removes the a element from a selected hyperlink.

We can use it as follows:

document.execCommand('unlink');

styleWithCSS

Toggle on or off the use of HTML tags or CSS for the generated markup. true modifies/generates style attributes in markup, false generate presentational elements.

We can use it as follows:

document.execCommand('styleWithCSS', true, true);

The document.execCommand method is very useful for fiddling with web pages that have design mode on. We can make lots of changes to formatting by running various commands listed above.

It’s more convenient than inspecting the element and then changing it manually if we want to make lots of changes.