Chapter 9: The Window Object
Every JavaScript environment has aglobal object. Any variables that are created in the global scope are actually properties of this object, and any functions are methods of it. In a browser environment the global object is the window
object, which represents the browser window that contains a web page.
In this chapter, we’ll cover these topics:
- The Browser Object Model
- Finding out browser information
- Browser history
- Controlling windows
- Cookies
- Timing functions
- Our project ― we’ll add a countdown timer to our quiz
The Browser Object Model
The Browser Object Model (or BOM for short) is a collection of properties and methods that contain information about the browser and computer screen. For example, we can find out which browser is being used to view a page (though, this method is unreliable). We can also find out the dimensions of the screen it is viewed on, and which pages have been visited before the current page. It can also be used for the rather dubious practice of creating pop-up windows, if you’re into annoying your users.
There is no official standard for the BOM, although there are a number of properties and methods that are supported by all the major browsers, making a sort of de facto standard. These properties and methods are made available through the window
object. Every browser window, tab, popup, frame, and iframe has a window
object.
The BOM Only Makes Sense in a Browser Environment
Remember that JavaScript can be run in different environments. The BOM only makes sense in a browser environment. This means that other environments (such as Node.js) probably won’t have a window
object, although they will still have a global object; for example, Node.js has an object called global
.
If you don’t know the name of the global object, you can also refer to it using the keyword this
in the global scope. The following code provides a quick way of assigning the variable global
to the global object:
// from within the global scopeconst global = this;
Going Global
All the way back in Chapter 2, we introduced the concept of global variables. These are variables that are created without using the const
, let
or var
keywords. Global variables can be accessed in all parts of the program.
Global variables are actual properties of a global object. In a browser environment, the global object is the window
object. This means that any global variable created is actually a property of the window
object, as can be seen in the example below:
x = 6; // global variable created<< 6window.x // same variable can be accessed as a property of the window object<< 6// both variables are exactly the samewindow.x === x;<< true
In general, you should refer to global variables without using the window
object; it’s less typing and your code will be more portable between environments. An exception is if you need to check whether a global variable has been defined. For example, the following code will throw a ReferenceError if x
has not been defined:
if (x) { // do something}
However, if the variable is accessed as a property of the window
object, then the code will still work, as window.x
will simply return false
, meaning the block of code will not be evaluated:
if (window.x) {// do something}
Some functions we’ve already met, such as parseInt()
and isNaN()
, are actually methods of the global object, which in a browser environment makes them methods of the window
object:
window.parseInt(4.2);<< 4window.isNaN(4.2);<< false
Like variables, it’s customary to omit accessing them through the window
object.
Changes in ES6
ES6 made parseInt()
and isNaN()
methods of the Number
object, so they can be both be called using the following code:
Number.parseInt(4.2);<< 4Number.isNaN(4.2);<< false
Dialogs
In Chapter 1, we introduced three functions that produced dialogs in the browsers: alert()
, confirm()
and prompt()
. These are not part of the ECMAScript standard, although all major browsers support them as methods of the window
object.
The window.alert()
method will pause the execution of the program and display a message in a dialog box. The message is provided as an argument to the method, and undefined
is always returned:
window.alert('Hello');<< undefined

The window.confirm()
method will stop the execution of the program and display a confirmation dialog that shows the message provided as an argument, and giving the options of OK or Cancel. It returns the boolean values of true
if the user clicks OK, and false
if the user clicks Cancel:
window.confirm('Do you wish to continue?');<< undefined

The window.prompt()
method will stop the execution of the program. It displays a dialog that shows a message provided as an argument, as well as an input field that allows the user to enter text. This text is then returned as a string when the user clicks OK. If the user clicks Cancel, null
is returned:
window.prompt('Please enter your name:');

Use With Care
It’s worth reiterating again that these methods will stop the execution of a program in its tracks. This means that everything will stop processing at the point the method is called, until the user clicksOKorCancel. This can cause problems if the program needs to process something else at the same time or the program is waiting for a callback function.
There are some occasions when this functionality can be used as an advantage, for example, a window.confirm()
dialog can be used as a final check to see if a user wants to delete a resource. This will stop the program from going ahead and deleting the resource while the user decides what to do.
It’s also worth keeping in mind that most browsers allow users to disable any dialogs from repeatedly appearing, meaning they are not a feature to be relied upon.
Browser Information
The window
object has a number of properties and methods that provide information about the user’s browser.
Which Browser?
The window
object has a navigator
property that returns a reference to the Navigator
object. The Navigator
object contains information about the browser being used. Its userAgent
property will return information about the browser and operating system being used. For example, if I run the following line of code, it shows that I am using Safari version 10 on Mac OS:
window.navigator.userAgent<< "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8"
Don’t rely on this information though, as it can be modified by a user to masquerade as a different browser. It can also be difficult to make any sense of the string returned, because all browsers pretend to be others to some degree. For example, every browser will include the string “Mozilla” in its userAgent
property, for reasons of legacy Netscape compatibility. The userAgent
property has been deprecated from the official specification, but it remains well supported in all major browsers.
Location, Location, Location
The window.location
property is an object that contains information about the URL of the current page. It contains a number of properties that provide information about different fragments of the URL.
The href
property returns the full URL as a string:
window.location.href << "https://www.sitepoint.com/premium/books/javascript-novice-to-ninja"
This property (as well as most of the others in this section) is a read/write property, which means it can also be changed by assignment. If this is done, the page will be reloaded using the new property. For example, entering the following line into the browser console will redirect the page to the SitePoint JavaScript channel:
window.location.href = 'https://www.sitepoint.com/javascript/'<< "https://www.sitepoint.com/javascript/"
The protocol
property returns a string describing the protocol used (such as http
, https
, pop2
, ftp
etc.). Note that there is a colon ( :
) at the end:
window.location.protocol << "https:"
The host
property returns a string describing the domain of the current URLandthe port number (this is often omitted if the default port 80 is used):
window.location.host<< "www.sitepoint.com"
The hostname
property returns a string describing the domain of the current URL:
window.location.hostname<< "www.sitepoint.com"
The port
property returns a string describing the port number, although it will return an empty string if the port is not explicitly stated in the URL:
window.location.port<< ""
The pathname
property returns a string of the path that follows the domain:
window.location.pathname<< "/premium/books/javascript-novice-to-ninja"
The search
property returns a string that starts with a “?” followed by the query string parameters. It returns an empty string if there are no query string parameters. This is what I get when I search for “JavaScript” on SitePoint:
window.location.search<< "?q=javascript&limit=24&offset=0&page=1&content_types[]=All&slugs[]=all&states[]=available&order="
The hash
property returns a string that starts with a “#” followed by the fragment identifier. It returns an empty string if there is no fragment identifier:
window.location.hash<< ""
The origin
property returns a string that shows the protocol and domain where the current page originated from. This property is read-only, so cannot be changed:
window.location.origin<< "https://www.sitepoint.com"
The window.location
object also has the following methods:
- The
reload()
method can be used to force a reload of the current page. If it’s given a parameter oftrue
, it will force the browser to reload the page from the server, instead of using a cached page. - The
assign()
method can be used to load another resource from a URL provided as a parameter, for example:
window.location.assign('https://www.sitepoint.com/')
- The
replace()
method is almost the same as theassign()
method, except the current page will not be stored in the session history, so the user will be unable to navigate back to it using the back button. - The
toString()
method returns a string containing the whole URL:window.location.toString();<< "https://www.sitepoint.com/javascript/"
The Browser History
The window.history
property can be used to access information about any previously visited pages in the current browser session. Avoid confusing this with the new HTML5 History API. (See http://www.sitepoint.com/javascript-history-pushstate/ post for details.)
The window.history.length
property shows how many pages have been visited before arriving at the current page.
The window.history.go()
method can be used to go to a specific page, where 0 is the current page:
window.history.go(1); // goes forward 1 pagewindow.history.go(0); // reloads the current pagewindow.history.go(-1); // goes back 1 page
There are also the window.history.forward()
and window.history.back()
methods that can be used to navigate forwards and backwards by one page respectively, just like using the browser’s forward and back buttons.
Controlling Windows
A new window can be opened using the window.open()
method. This takes the URL of the page to be opened as its first parameter, the window title as its second parameter, and a list of attributes as the third parameter. This can also be assigned to a variable, so the window can then be referenced later in the code:
const popup = window.open('https://sitepoint.com','SitePoint','width=400,height=400,resizable=yes');

The close()
method can be used to close a window, assuming you have a reference to it:
popup.close();
It is also possible to move a window using the window.moveTo()
method. This takes two parameters that are the X and Y coordinates of the screen that the window is to be moved to:
window.moveTo(0,0); // will move the window to the top-left corner of the screen
You can resize a window using the window.resizeTo()
method. This takes two parameters that specify the width and height of the resized window’s dimensions:
window.resizeTo(600,400);
Annoying Popups
These methods were largely responsible for giving JavaScript a bad name, as they were used for creating annoying pop-up windows that usually contained intrusive advertisements. It’s also a bad idea from a usability standpoint to resize or move a user’s window.
Many browsers block pop-up windows and disallow some of these methods to be called in certain cases. For example, you can’t resize a window if more than one tab is open. You also can’t move or resize a window that wasn’t created using window.open()
.
It’s rare that it would be sensible to use any of these methods, so think very carefully before using them. There will almost always be a better alternative, and a ninja programmer will endeavor to find it.
Screen Information
The window.screen
object contains information about the screen the browser is displayed on. You can find out the height and width of the screen in pixels using the height
and width
properties respectively:
window.screen.height<< 1024window.screen.width<< 1280
The availHeight
and availWidth
can be used to find the height and width of the screen, excluding any operating system menus:
window.screen.availWidth<< 1280window.screen.availHeight<< 995
The colorDepth
property can be used to find the color bit depth of the user’s monitor, although there are few use cases for doing this other than collecting user statistics:
window.screen.colorDepth;<< 24
More Useful on Mobile
The Screen object has more uses for mobile devices. It also allows you to do things like turn off the device’s screen, detect a change in its orientation or lock it in a specific orientation.
Use With Care
Many of the methods and properties covered in the previous section were abused in the past for dubious activities such as user-agent sniffing, or detecting screen dimensions to decide whether or not to display certain elements. These practices have (thankfully) now been superseded by better practices, such as media queries and feature detection, which is covered in the next chapter.
The Document Object
Each window
object contains a document
object. This object has properties and methods that deal with the page that has been loaded into the window. In Chapter 6, we covered the Document Object Model and the properties and methods used to manipulate items on the page. The document
object contains a few other methods that are worth looking at.
document.write()
The write()
method simply writes a string of text to the page. If a page has already loaded, it will completely replace the current document:
document.write('Hello, world!');
This would replace the whole document with the string Hello, world!
. It is possible to include HTML in the string and this will become part of the DOM tree. For example, the following piece of code will create an <h1>
tag node and a child text node:
document.write('<h1>Hello, world!</h1>');
The document.write()
method can also be used within a document inside <script>
tags to inject a string into the markup. This will not overwrite the rest of the HTML on the page. The following example will place the text "Hello, world!"
inside the <h1>
tags and the rest of the page will display as normal:
<h1> <script>document.write("Hello, world!")</script></h1>
The use of document.write()
is heavily frowned upon as it can only be realistically used by mixing JavaScript within an HTML document. There are still some extremely rare legitimate uses of it, but a ninja programmer will hardly ever need to use it.
Cookies
Cookies are small files that are saved locally on a user’s computer. They were invented by Netscape as a way of getting round HTTP being a stateless protocol. This means that a browser does not remember anything from one request to another. So every time a user visits a page, nothing about any previous visits is remembered. Cookies can be used to sidestep this problem by storing information that can then be retrieved between requests.
A restriction of cookies is that they can only be read by a web page from the same domain that set them. This is to stop sites being able to access information about users, such as other sites they have visited. Cookies are also limited to storing up to 4KB of data, although 20 cookies are allowed per domain, which can add up to quite a lot of data.
Cookies can be used for personalizing a user’s browsing experience, storing user preferences, keeping track of user choices (such as a shopping cart), authentication and tracking users. The use of cookies for tracking purposes has been much maligned in recent years. Their use for data storage is starting to be replaced in many cases by the new HTML5 localStorage API as it allows more data to be stored. This is covered in Chapter 14. Cookies are still useful for retaining state information (such as if a user is logged in) because they’re passed between the client and server on every HTTP request.
Cookies take the form of a text file that contain a list of name/value pairs separated by semicolons. For example, a cookie file might contain the following information:
"name=Superman; hero=true; city=Metropolis"
EU Cookie Directive
The EU Cookie Directive is a piece of legislation that requires websites based in an EU country to ask for permission before setting any cookies. It’s possible, however, that in the future this requirement may be part of a global browser setting, rather than the onus being on each individual website to ask for permission to set cookies.
Creating Cookies
To create a cookie, you assign it to JavaScript’s “cookie jar”, using the document.cookie
property, like so:
document.cookie = 'name=Superman';<< "name=Superman"
The document.cookie
property acts like a special type of string. Assigning another cookie to it won’t overwrite the entire property, it will just append it to the end of the string. So we can add more cookies by assigning them to document.cookie
:
document.cookie = 'hero=true';<< "hero=true"document.cookie = 'city=Metropolis';<< "city=Metropolis"
Changing Cookie Values
A cookie’s value can be changed by reassigning it to document.cookie
using the same name but a different value. The following code will update the value of two of the cookies that we set in the previous section:
document.cookie = 'name=Batman'<< "name=Batman"document.cookie = 'city=Gotham'<< "city=Gotham"
Reading Cookies
To see the current contents of the cookie jar, simply enter document.cookie
:
document.cookie:<< "name=Batman; hero=true; city=Gotham"
We can use the split
method to break the string into an array containing each name/value pair, then use a for of
loop to iterate through the array:
const cookies = document.cookie.split("; ");for (crumb of cookies){ const [key,value] = crumb.split("="); console.log(`The value of ${key} is ${value}`);}<< The value of name is BatmanThe value of hero is trueThe value of city is Gotham
To see an example of cookies used in the wild, you can visit almost any website, open the browser console, and type document.cookie
.
Cookie Expiry Dates
Cookies are session cookies by default. This means they are deleted once a browser session is finished (when the user closes the browser tab or window). Cookies can be made persistent ― that is, lasting beyond the browser session ― by adding "; expires=date"
to the end of the cookie when it’s set, where date
is a date value in the UTC String format Day, DD-Mon-YYYY HH:MM:SS GMT
. The following example sets a cookie to expire in one day’s time:
const expiryDate = new Date(); const tomorrow = expiryDate.getTime() + 1000 * 60 * 60 * 24;expiryDate.setTime(tomorrow);document.cookie = `name=Batman; expires=${ expiryDate.toUTCString()}`;
An alternative is to set the max-age
value. This takes a value in seconds, but it wasn’t supported in Internet Explorer before version 10:
document.cookie = 'name=Batman; max-age=86400' // 86400 secs = 1 day
Don’t Rely On Cookie Expiry
Applications that contain sensitive information shouldn’t rely on cookies expiring using these methods. Browsers can sometimes hold on to information stored in a cookie that should have expired when the “session restore” feature is used after a crash.
The Path and Domain of Cookies
By default, cookies can only be read by pages inside the same directory and domain as the file was set. This is for security reasons so that access to the cookie is limited.
The path can be changed so that any page in the root directory can read the cookie. It’s done by adding the string ; path=/
to the end of the cookie when it is set:
document.cookie = 'name=Batman; path=/'
It’s also possible to set the domain by adding "; domain=domainName"
to the end of the cookie:
document.cookie = 'name=Batman; domain=sitepoint.com';
A cookie can only be read by the domain that created it anyway, but doing this will allow all subdomains of sitepoint.com (such as javascript.sitepoint.com and books.sitepoint.com) to read it.
Secure Cookies
Adding the string ; secure
to the end of a cookie will ensure it’s only transmitted over a secure HTTPS network:
document.cookie = 'name=Batman; secure';
Deleting Cookies
To remove a cookie, you need to set it to expire at a time in the past:
document.cookie = 'name=Batman; expires=Thu, 01 Jan 1970 00:00:01 GMT';
If a cookie is a session cookie, it will expire when the tab or window is closed.
Cumbersome Cookies
JavaScript’s cookie handling is quite basic and can also be quite cumbersome. Many developers use a library such asCookies.jsorjsCookie. You could even have a go at developing your own set of functions to make dealing with cookies easier.
Timing Functions
setTimeout()
The window
object provides some useful methods for scheduling the execution of a function, and for repeatedly executing functions at regular intervals.
The window.setTimeout()
method accepts a callback to a function as its first parameter and a number of milliseconds as its second parameter. Try entering the following example into a console. It should show an alert dialog after three seconds (that’s 3000 milliseconds):
window.setTimeout( () => alert("Time's Up!"), 3000);<< 4
Notice that the method returns an integer. This is an ID used to reference that particular timeout. It can also cancel the timeout using the window.clearTimeout()
method. Try calling the code again and make a note of the number that is returned:
window.setTimeout( () => alert("Time's Up!"), 3000);<< 5
Now quickly enter the following code before the alert pops up, making sure that you enter the number that was returned previously (it might not be 5 in your case!):
window.clearTimeout(5);<< undefined
If you were quick enough, and used the correct ID, the alert was prevented from happening.
setInterval()
The window.setInterval()
method works in a similar way to window.setTimeout()
, except that it will repeatedly invoke the callback function after every given number of milliseconds.
The previous example used an anonymous function, but it is also possible to use a named function like so:
function chant(){ console.log('Beetlejuice'); }
Now we can set up the interval and assign it to a variable:
const summon = window.setInterval(chant,1000);<< 6
This should show the message “Beetlejuice” in the console every second (1,000 milliseconds).
To stop this, we can use the window.clearInterval()
method and the variable repeat
as an argument (this is because the window.setInterval()
method returns its ID, so this will be assigned to the variable repeat
):
window.clearInterval(summon);
Using the this
Keyword
Be careful when using a method that uses the this
keyword with either of these timing methods. The binding of this
is set to the window
object, rather than the method’s object, so it can get some unexpected results:
const person = { name: 'Superman', introduce() { console.log(`Hi, I'm ${this.name}`); }}; setTimeout(person.introduce, 50);<< Hi, I'm
In the example above, the value of this.name
is undefined
because the code is looking for a property of the window
object called name
, which doesn’t exist.
There are ways to bind this
to the object instead, and these are discussed in Chapter 12.
Animation
The setTimeOut()
and setInterval()
methods can be used to animate elements on a web page. As an example, let’s create a web page that shows a colored square, and make it rotate. Create a folder called animation
that contains files called index.html
, styles.css
and main.js
. Place the following code inside index.html
:
<!doctype html><html lang='en'><head><meta charset='utf-8'><title>Animation Example</title><link rel='stylesheet' href='styles.css'></head><body><div id='square'></div><script src='main.js'></script></body></html>
This places a div on the page with an ID of square
.
Next, add the following styles.css
:
#square { margin: 100px; width: 100px; height: 100px; background: #d16;}
This will set the position, dimensions and color of the div. Now for the animation ― add the following code to main.js
:
const squareElement = document.getElementById('square');let angle = 0;setInterval( () => { angle = (angle + 2) % 360; squareElement.style.transform = `rotate(${angle}deg)`}, 1000/60);
This code receives a reference to our square div, then sets a variable called angle
to 0. We then use the setInterval()
method to increase the value of angle
by 2
(we also use the %
operator so that it resets to 0 at 360), then set the transform
CSS3 property to rotate that number of degrees. The second argument is 1000/60
, which equates to a frame speed of 60 frames per second.
Open animation.html
in your browser and you should see a rotating square, although it will probably be quite slow and not very smooth. This was the only way to achieve animation using JavaScript until the window.requestAnimationFrame()
method was developed.
requestAnimationFrame
This method of the window
object works in much the same way as the window.setInterval()
method, although it has a number of improvements to optimize its performance. These include making the most of the browser’s built-in graphics-handling capabilities, and not running the animation when the tab is inactive, resulting in a much smoother performance. It’s supported in all major browsers, including Internet Explorer from version 10 onwards. Change the code in main.js
to the following:
const squareElement = document.getElementById('square');let angle = 0;function rotate() { angle = (angle + 2)%360; squareElement.style.transform = `rotate(${angle}deg)` window.requestAnimationFrame(rotate);}const id = requestAnimationFrame(rotate);
This is similar to the earlier code, but this time we place the rotation code inside a function called rotate
. The last line of this function uses the window.requestAnimationFrame()
method and takes the rotate()
function as an argument. This will then call the rotate()
function recursively. The frame rate cannot be set using requestAnimationFrame()
; it’s usually 60 frames per second, although it’s optimized for the device being used.
To start the animation, we need to call the requestAnimationFrame()
method, giving the rotate()
function as an argument. This will return a unique ID that can be employed to stop the animation using the window.cancelAnimationFrame()
method:
cancelAnimationFrame(id);
Refresh the animation.html
page and you should notice that the animation is much faster and smoother than before, as shown below.

Consider Using CSS Instead
The rotation animation example demonstrates how JavaScript can be used to perform animations in the browser. It could also be achieved using pure CSS animation with the following style rules in styles.css
:
#square { margin: 100px; width: 100px; height: 100px; background: #cc0; animation: spin 4s linear infinite;}@keyframes spin { from { transform:rotate(0deg); } to { transform:rotate(3600deg); } }
In general, it is typically better to use CSS for any animation effects, although there may be times when JavaScript might be the better solution.
Quiz Ninja Project
We’re now going add a timer to give our quiz a “beat the clock’ element. We’ll do this using the window
object’s setInterval()
method to add a time limit. First of all, we’ll add an element to the HTML for the timer. Update the <header>
inside the index.html
file to include an extra <div>
element with an id of ‘timer’:
<header> <h1>Quiz Ninja!</h1> <div id='timer'>Time: <strong>20</strong></div> <div id='score'>Score: <strong>0</strong></div></header>
We’ll use this ID to add a reference to this element as a property of the view
object in the main.js
file:
timer: document.querySelector('#timer strong')
Next, we need to add the following code to the game.start()
method:
this.secondsRemaining = 20;this.timer = setInterval( this.countdown , 1000 );
This initializes a property of the game
object called secondsRemaining
to 20
. It is used to measure, in seconds, how the game will last. The next line sets up an interval that calls a method called countdown()
every second (1,000 milliseconds). This method needs adding to the game
object:
countdown() { game.secondsRemaining--; view.render(view.timer,game.secondsRemaining); if(game.secondsRemaining < 0) { game.gameOver(); }}
This function decreases the secondsRemaining
variable that we initialized earlier by 1
using the --
operator, then calls the view.render()
method so the number of seconds remaining is displayed in the header. Last of all, we check to see if the time has fallen below zero and, if it has, we call the gameOver()
function as time has run out!
Finally, we have to add a line at the end of the game.gameOver()
method that will remove the interval when the game has finished, otherwise it will continue to keep counting down past zero! To stop this from happening, we place the following line of code anywhere inside the gameOver()
function:
gameOver(){ view.render(view.info,`Game Over, you scored ${this.score} point${this.score !== 1 ? 's' : ''}`); view.teardown(); clearInterval(this.timer);}
Try playing the game now by opening index.html
in a browser and see how you go with the added pressure of beating the clock.
You can see a live example onCodePen.
Chapter Summary
- The
window
object is the global object in a browser. - Global variables are actually properties of the
window
object in a browser environment. -
alert
,confirm()
, andprompt()
are all methods of thewindow
object, and open dialogs that halt the execution of the program. - The
window.navigator
object gives information about the user’s browser and operating system, although it can be unreliable. - The
window.location
object provides information about the URL of the current page. - The
window.history
object keeps information about the pages that have been visited in the session. - You can open, close, resize, and move windows (although, this doesn’t mean you should!).
- The
window.screen
object provides information about the user’s screen. -
document.write()
is an archaic method of writing text to the document and should be avoided. - Cookies can be used to store small pieces of information between requests using the
document.cookie
property. - The
window.setTimeout()
method can be used to invoke a function after a set amount of time. It can be canceled using theclearTimeout()
method. - The
window.setInterval()
method can be used to repeatedly invoke a function. It can be stopped using theclearInterval()
method. - The
window.requestAnimationFrame()
method can be used to produce smooth and optimized animation by utilizing the browser’s built-in graphics capabilities. It can be canceled using thecancelAnimationFrame()
method.
In the next chapter, we’ll be looking at how to handle errors and write tests in JavaScript.