├── README.md ├── files └── en-us │ ├── web │ ├── css │ │ └── background-image │ │ │ └── index.html │ └── api │ │ ├── windoworworkerglobalscope │ │ └── fetch │ │ │ └── index.html │ │ ├── xmlhttprequest │ │ └── index.html │ │ └── web_storage_api │ │ └── using_the_web_storage_api │ │ └── index.html │ └── learn │ └── getting_started_with_the_web │ └── javascript_basics │ └── index.html └── LICENSE.md /README.md: -------------------------------------------------------------------------------- 1 | # machine-translation-testing-content 2 | This is a repository for testing machine translations of English content. 3 | -------------------------------------------------------------------------------- /files/en-us/web/css/background-image/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: background-image 3 | slug: Web/CSS/background-image 4 | tags: 5 | - CSS 6 | - CSS Background 7 | - CSS Property 8 | - Reference 9 | - 'recipe:css-property' 10 | --- 11 |

{{CSSRef}}

12 | 13 |

The background-image CSS property sets one or more background images on an element.

14 | 15 |
{{EmbedInteractiveExample("pages/css/background-image.html")}}
16 | 17 | 18 | 19 |

The background images are drawn on stacking context layers on top of each other. The first layer specified is drawn as if it is closest to the user.

20 | 21 |

The borders of the element are then drawn on top of them, and the {{cssxref("background-color")}} is drawn beneath them. How the images are drawn relative to the box and its borders is defined by the {{cssxref("background-clip")}} and {{cssxref("background-origin")}} CSS properties.

22 | 23 |

If a specified image cannot be drawn (for example, when the file denoted by the specified URI cannot be loaded), browsers handle it as they would a none value.

24 | 25 |
Note: Even if the images are opaque and the color won't be displayed in normal circumstances, web developers should always specify a {{cssxref("background-color")}}. If the images cannot be loaded—for instance, when the network is down—the background color will be used as a fallback.
26 | 27 |

Syntax

28 | 29 |

Each background image is specified either as the keyword none or as an {{cssxref("<image>")}} value.

30 | 31 |

To specify multiple background images, supply multiple values, separated by a comma:

32 | 33 |
background-image:
 34 |   linear-gradient(to bottom, rgba(255,255,0,0.5), rgba(0,0,255,0.5)),
 35 |   url('https://mdn.mozillademos.org/files/7693/catfront.png');
36 | 37 |

Values

38 | 39 |
40 |
none
41 |
Is a keyword denoting the absence of images.
42 |
<image>
43 |
Is an {{cssxref("<image>")}} denoting the image to display. There can be several of them, separated by commas, as multiple backgrounds are supported.
44 |
45 | 46 |

Accessibility concerns

47 | 48 |

Browsers do not provide any special information on background images to assistive technology. This is important primarily for screen readers, as a screen reader will not announce its presence and therefore convey nothing to its users. If the image contains information critical to understanding the page's overall purpose, it is better to describe it semantically in the document.

49 | 50 | 54 | 55 |

Formal definition

56 | 57 |

{{cssinfo}}

58 | 59 |

Formal syntax

60 | 61 |
{{csssyntax}}
62 | 63 |

Examples

64 | 65 |

Layering background images

66 | 67 |

Note that the star image is partially transparent and is layered over the cat image.

68 | 69 |

HTML

70 | 71 |
<div>
 72 |   <p class="catsandstars">
 73 |     This paragraph is full of cats<br />and stars.
 74 |   </p>
 75 |   <p>This paragraph is not.</p>
 76 |   <p class="catsandstars">
 77 |     Here are more cats for you.<br />Look at them!
 78 |   </p>
 79 |   <p>And no more.</p>
 80 | </div>
81 | 82 |

CSS

83 | 84 |
p {
 85 |   font-size: 1.5em;
 86 |   color: #FE7F88;
 87 |   background-image: none;
 88 |   background-color: transparent;
 89 | }
 90 | 
 91 | div {
 92 |   background-image:
 93 |       url("https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png");
 94 | }
 95 | 
 96 | .catsandstars {
 97 |   background-image:
 98 |       url("https://mdn.mozillademos.org/files/11991/startransparent.gif"),
 99 |       url("https://mdn.mozillademos.org/files/7693/catfront.png");
100 |   background-color: transparent;
101 | }
102 | 
103 | 104 |

Result

105 | 106 |

{{EmbedLiveSample('Layering_background_images')}}

107 | 108 |

Specifications

109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 |
SpecificationStatusComment
{{SpecName('CSS3 Backgrounds', '#background-image', 'background-image')}}{{Spec2('CSS3 Backgrounds')}}From CSS2 Revision 1, the property has been extended to support multiple backgrounds and any {{cssxref("<image>")}} CSS data type.
{{SpecName('CSS2.1', 'colors.html#propdef-background-image', 'background-image')}}{{Spec2('CSS2.1')}}From CSS1, the way images with and without intrinsic dimensions are handled is now described.
{{SpecName('CSS1', '#background-image', 'background-image')}}{{Spec2('CSS1')}}Initial definition.
136 | 137 |

Browser compatibility

138 | 139 | 140 | 141 |
{{Compat("css.properties.background-image")}}
142 | 143 |

See also

144 | 145 | 164 | -------------------------------------------------------------------------------- /files/en-us/web/api/windoworworkerglobalscope/fetch/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: WindowOrWorkerGlobalScope.fetch() 3 | slug: Web/API/WindowOrWorkerGlobalScope/fetch 4 | tags: 5 | - API 6 | - Experimental 7 | - Fetch 8 | - Fetch API 9 | - GlobalFetch 10 | - Method 11 | - Reference 12 | - WindowOrWorkerGlobalScope 13 | - request 14 | --- 15 |

{{APIRef("Fetch API")}}

16 | 17 |

The fetch() method of the {{domxref("WindowOrWorkerGlobalScope")}} mixin starts the process of fetching a resource from the network, returning a promise which is fulfilled once the response is available. The promise resolves to the {{domxref("Response")}} object representing the response to your request. The promise does not reject on HTTP errors — it only rejects on network errors. You must use then handlers to check for HTTP errors.

18 | 19 |

WindowOrWorkerGlobalScope is implemented by both {{domxref("Window")}} and {{domxref("WorkerGlobalScope")}}, which means that the fetch() method is available in pretty much any context in which you might want to fetch resources.

20 | 21 |

A {{domxref("WindowOrWorkerGlobalScope.fetch","fetch()")}} promise only rejects when a network error is encountered (which is usually when there’s a permissions issue or similar). A {{domxref("WindowOrWorkerGlobalScope.fetch","fetch()")}} promise does not reject on HTTP errors (404, etc.). Instead, a then() handler must check the {{domxref("Response.ok")}} and/or {{domxref("Response.status")}} properties.

22 | 23 |

The fetch() method is controlled by the connect-src directive of Content Security Policy rather than the directive of the resources it's retrieving.

24 | 25 |
26 |

Note: The fetch() method's parameters are identical to those of the {{domxref("Request.Request","Request()")}} constructor.

27 |
28 | 29 |

Syntax

30 | 31 |
const fetchResponsePromise = fetch(resource [, init])
 32 | 
33 | 34 |

Parameters

35 | 36 |
37 |
resource
38 |
This defines the resource that you wish to fetch. This can either be: 39 | 43 |
44 |
init {{optional_inline}}
45 |
46 |

An object containing any custom settings that you want to apply to the request. The possible options are:

47 | 48 |
49 |
method
50 |
The request method, e.g., GET, POST. Note that the {{httpheader("Origin")}} header is not set on Fetch requests with a method of {{HTTPMethod("HEAD")}} or {{HTTPMethod("GET")}}.
51 | (This behavior was corrected in Firefox 65 — see {{bug(1508661)}}).
52 |
headers
53 |
Any headers you want to add to your request, contained within a {{domxref("Headers")}} object or an object literal with {{domxref("ByteString")}} values. Note that some names are forbidden.
54 |
body
55 |
Any body that you want to add to your request: this can be a {{domxref("Blob")}}, {{domxref("BufferSource")}}, {{domxref("FormData")}}, {{domxref("URLSearchParams")}}, {{domxref("USVString")}}, or {{domxref("ReadableStream")}} object. Note that a request using the GET or HEAD method cannot have a body.
56 |
mode
57 |
The mode you want to use for the request, e.g., cors, no-cors, or same-origin.
58 |
credentials
59 |
The request credentials you want to use for the request: omit, same-origin, or include. To automatically send cookies for the current domain, this option must be provided. Starting with Chrome 50, this property also takes a {{domxref("FederatedCredential")}} instance or a {{domxref("PasswordCredential")}} instance.
60 |
cache
61 |
The cache mode you want to use for the request.
62 |
redirect
63 |
The redirect mode to use: follow (automatically follow redirects), error (abort with an error if a redirect occurs), or manual (handle redirects manually). In Chrome the default is follow (before Chrome 47 it defaulted to manual).
64 |
referrer
65 |
A {{domxref("USVString")}} specifying the referrer of the request. This can be a same-origin URL, about:client, or an empty string.
66 |
referrerPolicy
67 |
Specifies the referrer policy to use for the request. May be one of no-referrer, no-referrer-when-downgrade, same-origin, origin, strict-origin, origin-when-cross-origin, strict-origin-when-cross-origin, or unsafe-url.
68 |
integrity
69 |
Contains the subresource integrity value of the request (e.g., sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=).
70 |
keepalive
71 |
The keepalive option can be used to allow the request to outlive the page. Fetch with the keepalive flag is a replacement for the {{domxref("Navigator.sendBeacon()")}} API.
72 |
signal
73 |
An {{domxref("AbortSignal")}} object instance; allows you to communicate with a fetch request and abort it if desired via an {{domxref("AbortController")}}.
74 |
75 |
76 |
77 | 78 |

Return value

79 | 80 |

A {{domxref("Promise")}} that resolves to a {{domxref("Response")}} object.

81 | 82 |

Exceptions

83 | 84 |
85 |
AbortError
86 |
The request was aborted due to a call to the {{domxref("AbortController")}} method {{domxref("AbortController.abort", "abort()")}} method.
87 |
TypeError
88 |
The specified URL string includes user credentials. This information should instead be provided using an {{HTTPHeader("Authorization")}} header.
89 |
90 | 91 |

Examples

92 | 93 |

In our Fetch Request example (see Fetch Request live) we create a new {{domxref("Request")}} object using the relevant constructor, then fetch it using a fetch() call. Since we are fetching an image, we run {{domxref("Body.blob()")}} on the response to give it the proper MIME type so it will be handled properly, then create an Object URL of it and display it in an {{htmlelement("img")}} element.

94 | 95 |
const myImage = document.querySelector('img');
 96 | 
 97 | let myRequest = new Request('flowers.jpg');
 98 | 
 99 | fetch(myRequest)
100 | .then(function(response) {
101 |   if (!response.ok) {
102 |     throw new Error(`HTTP error! status: ${response.status}`);
103 |   }
104 |   return response.blob();
105 | })
106 | .then(function(response) {
107 |   let objectURL = URL.createObjectURL(response);
108 |   myImage.src = objectURL;
109 | });
110 | 111 |

In the Fetch with init then Request example (see Fetch Request init live), we do the same thing except that we pass in an init object when we invoke fetch():

112 | 113 |
const myImage = document.querySelector('img');
114 | 
115 | let myHeaders = new Headers();
116 | myHeaders.append('Content-Type', 'image/jpeg');
117 | 
118 | const myInit = {
119 |   method: 'GET',
120 |   headers: myHeaders,
121 |   mode: 'cors',
122 |   cache: 'default'
123 | };
124 | 
125 | let myRequest = new Request('flowers.jpg');
126 | 
127 | fetch(myRequest, myInit).then(function(response) {
128 |   // ...
129 | });
130 | 131 |

You could also pass the init object in with the Request constructor to get the same effect:

132 | 133 |
let myRequest = new Request('flowers.jpg', myInit);
134 | 135 |

You can also use an object literal as headers in init.

136 | 137 |
const myInit = {
138 |   method: 'GET',
139 |   headers: {
140 |     'Content-Type': 'image/jpeg'
141 |   },
142 |   mode: 'cors',
143 |   cache: 'default'
144 | };
145 | 
146 | let myRequest = new Request('flowers.jpg', myInit);
147 | 
148 | 149 |

Specifications

150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 |
SpecificationStatusComment
{{SpecName('Fetch','#fetch-method','fetch()')}}{{Spec2('Fetch')}}Defined in a WindowOrWorkerGlobalScope partial in the newest spec.
{{SpecName('Fetch','#dom-global-fetch','fetch()')}}{{Spec2('Fetch')}}Initial definition
{{SpecName('Credential Management')}}{{Spec2('Credential Management')}}Adds {{domxref("FederatedCredential")}} or {{domxref("PasswordCredential")}} instance as a possible value for init.credentials.
177 | 178 |

Browser compatibility

179 | 180 | 181 | 182 |

{{Compat("api.WindowOrWorkerGlobalScope.fetch")}}

183 | 184 |

See also

185 | 186 | 192 | -------------------------------------------------------------------------------- /files/en-us/web/api/xmlhttprequest/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: XMLHttpRequest 3 | slug: Web/API/XMLHttpRequest 4 | tags: 5 | - AJAX 6 | - API 7 | - Communication 8 | - HTTP 9 | - Interface 10 | - Reference 11 | - Web 12 | - XHR 13 | - XMLHttpRequest 14 | --- 15 |
{{DefaultAPISidebar("XMLHttpRequest")}}
16 | 17 |

XMLHttpRequest (XHR) objects are used to interact with servers. You can retrieve data from a URL without having to do a full page refresh. This enables a Web page to update just part of a page without disrupting what the user is doing. XMLHttpRequest is used heavily in {{Glossary("AJAX")}} programming.

18 | 19 |

{{InheritanceDiagram(650, 150)}}

20 | 21 |

Despite its name, XMLHttpRequest can be used to retrieve any type of data, not just XML.

22 | 23 |

If your communication needs to involve receiving event data or message data from a server, consider using server-sent events through the {{domxref("EventSource")}} interface. For full-duplex communication, WebSockets may be a better choice.

24 | 25 |

Constructor

26 | 27 |
28 |
{{domxref("XMLHttpRequest.XMLHttpRequest", "XMLHttpRequest()")}}
29 |
The constructor initializes an XMLHttpRequest. It must be called before any other method calls.
30 |
31 | 32 |

Properties

33 | 34 |

This interface also inherits properties of {{domxref("XMLHttpRequestEventTarget")}} and of {{domxref("EventTarget")}}.

35 | 36 |
37 |
{{domxref("XMLHttpRequest.onreadystatechange")}}
38 |
An {{domxref("EventHandler")}} that is called whenever the readyState attribute changes.
39 |
{{domxref("XMLHttpRequest.readyState")}} {{readonlyinline}}
40 |
Returns an unsigned short, the state of the request.
41 |
{{domxref("XMLHttpRequest.response")}} {{readonlyinline}}
42 |
Returns an {{jsxref("ArrayBuffer")}}, {{domxref("Blob")}}, {{domxref("Document")}}, JavaScript object, or a {{domxref("DOMString")}}, depending on the value of {{domxref("XMLHttpRequest.responseType")}}, that contains the response entity body.
43 |
{{domxref("XMLHttpRequest.responseText")}} {{readonlyinline}}
44 |
Returns a {{domxref("DOMString")}} that contains the response to the request as text, or null if the request was unsuccessful or has not yet been sent.
45 |
{{domxref("XMLHttpRequest.responseType")}}
46 |
Is an enumerated value that defines the response type.
47 |
{{domxref("XMLHttpRequest.responseURL")}} {{readonlyinline}}
48 |
Returns the serialized URL of the response or the empty string if the URL is null.
49 |
{{domxref("XMLHttpRequest.responseXML")}} {{readonlyinline}}
50 |
Returns a {{domxref("Document")}} containing the response to the request, or null if the request was unsuccessful, has not yet been sent, or cannot be parsed as XML or HTML. Not available in workers.
51 |
{{domxref("XMLHttpRequest.status")}} {{readonlyinline}}
52 |
Returns an unsigned short with the status of the response of the request.
53 |
{{domxref("XMLHttpRequest.statusText")}} {{readonlyinline}}
54 |
Returns a {{domxref("DOMString")}} containing the response string returned by the HTTP server. Unlike {{domxref("XMLHttpRequest.status")}}, this includes the entire text of the response message ("200 OK", for example). 55 |
56 |

Note: According to the HTTP/2 specification (8.1.2.4 Response Pseudo-Header Fields), HTTP/2 does not define a way to carry the version or reason phrase that is included in an HTTP/1.1 status line.

57 |
58 |
59 |
{{domxref("XMLHttpRequest.timeout")}}
60 |
Is an unsigned long representing the number of milliseconds a request can take before automatically being terminated.
61 |
{{domxref("XMLHttpRequestEventTarget.ontimeout")}}
62 |
Is an {{domxref("EventHandler")}} that is called whenever the request times out. {{gecko_minversion_inline("12.0")}}
63 |
{{domxref("XMLHttpRequest.upload")}} {{readonlyinline}}
64 |
Is an {{domxref("XMLHttpRequestUpload")}}, representing the upload process.
65 |
{{domxref("XMLHttpRequest.withCredentials")}}
66 |
Is a {{domxref("Boolean")}} that indicates whether or not cross-site Access-Control requests should be made using credentials such as cookies or authorization headers.
67 |
68 | 69 |

Non-standard properties

70 | 71 |
72 |
{{domxref("XMLHttpRequest.channel")}}{{ReadOnlyInline}}
73 |
Is a {{Interface("nsIChannel")}}. The channel used by the object when performing the request.
74 |
{{domxref("XMLHttpRequest.mozAnon")}}{{ReadOnlyInline}}
75 |
Is a boolean. If true, the request will be sent without cookie and authentication headers.
76 |
{{domxref("XMLHttpRequest.mozSystem")}}{{ReadOnlyInline}}
77 |
Is a boolean. If true, the same origin policy will not be enforced on the request.
78 |
{{domxref("XMLHttpRequest.mozBackgroundRequest")}}
79 |
Is a boolean. It indicates whether or not the object represents a background service request.
80 |
{{domxref("XMLHttpRequest.mozResponseArrayBuffer")}}{{gecko_minversion_inline("2.0")}} {{obsolete_inline("6")}} {{ReadOnlyInline}}
81 |
{{jsxref("ArrayBuffer")}}. The response to the request, as a JavaScript typed array.
82 |
{{domxref("XMLHttpRequest.multipart")}}{{obsolete_inline("22")}}
83 |
This Gecko-only feature, a boolean, was removed in Firefox/Gecko 22. Please use Server-Sent Events, Web Sockets, or responseText from progress events instead.
84 |
85 | 86 |

Event handlers

87 | 88 |

onreadystatechange as a property of the XMLHttpRequest instance is supported in all browsers.

89 | 90 |

Since then, a number of additional event handlers have been implemented in various browsers (onload, onerror, onprogress, etc.). See Using XMLHttpRequest.

91 | 92 |

More recent browsers, including Firefox, also support listening to the XMLHttpRequest events via standard {{domxref("EventTarget.addEventListener", "addEventListener()")}} APIs in addition to setting on* properties to a handler function.

93 | 94 |

Methods

95 | 96 |
97 |
{{domxref("XMLHttpRequest.abort()")}}
98 |
Aborts the request if it has already been sent.
99 |
{{domxref("XMLHttpRequest.getAllResponseHeaders()")}}
100 |
Returns all the response headers, separated by {{Glossary("CRLF")}}, as a string, or null if no response has been received.
101 |
{{domxref("XMLHttpRequest.getResponseHeader()")}}
102 |
Returns the string containing the text of the specified header, or null if either the response has not yet been received or the header doesn't exist in the response.
103 |
{{domxref("XMLHttpRequest.open()")}}
104 |
Initializes a request.
105 |
{{domxref("XMLHttpRequest.overrideMimeType()")}}
106 |
Overrides the MIME type returned by the server.
107 |
{{domxref("XMLHttpRequest.send()")}}
108 |
Sends the request. If the request is asynchronous (which is the default), this method returns as soon as the request is sent.
109 |
{{domxref("XMLHttpRequest.setRequestHeader()")}}
110 |
Sets the value of an HTTP request header. You must call setRequestHeader()after open(), but before send().
111 |
112 | 113 |

Non-standard methods

114 | 115 |
116 |
{{domxref("XMLHttpRequest.init()")}}
117 |
Initializes the object for use from C++ code. 118 |
Warning: This method must not be called from JavaScript.
119 |
120 |
{{domxref("XMLHttpRequest.openRequest()")}}
121 |
Initializes a request. This method is to be used from native code; to initialize a request from JavaScript code, use open() instead. See the documentation for open().
122 |
{{domxref("XMLHttpRequest.sendAsBinary()")}}{{deprecated_inline()}}
123 |
A variant of the send() method that sends binary data.
124 |
125 | 126 |

Events

127 | 128 |
129 |
{{domxref("XMLHttpRequest/abort_event", "abort")}}
130 |
Fired when a request has been aborted, for example because the program called {{domxref("XMLHttpRequest.abort()")}}.
131 | Also available via the {{domxref("XMLHttpRequestEventTarget/onabort", "onabort")}} property.
132 |
{{domxref("XMLHttpRequest/error_event", "error")}}
133 |
Fired when the request encountered an error.
134 | Also available via the {{domxref("XMLHttpRequestEventTarget/onerror", "onerror")}} property.
135 |
{{domxref("XMLHttpRequest/load_event", "load")}}
136 |
Fired when an {{domxref("XMLHttpRequest")}} transaction completes successfully.
137 | Also available via the {{domxref("XMLHttpRequestEventTarget/onload", "onload")}} property.
138 |
{{domxref("XMLHttpRequest/loadend_event", "loadend")}}
139 |
Fired when a request has completed, whether successfully (after {{domxref("XMLHttpRequest/load_event", "load")}}) or unsuccessfully (after {{domxref("XMLHttpRequest/abort_event", "abort")}} or {{domxref("XMLHttpRequest/error_event", "error")}}).
140 | Also available via the {{domxref("XMLHttpRequestEventTarget/onloadend", "onloadend")}} property.
141 |
{{domxref("XMLHttpRequest/loadstart_event", "loadstart")}}
142 |
Fired when a request has started to load data.
143 | Also available via the {{domxref("XMLHttpRequestEventTarget/onloadstart", "onloadstart")}} property.
144 |
{{domxref("XMLHttpRequest/progress_event", "progress")}}
145 |
Fired periodically when a request receives more data.
146 | Also available via the {{domxref("XMLHttpRequestEventTarget/onprogress", "onprogress")}} property.
147 |
{{domxref("XMLHttpRequest/timeout_event", "timeout")}}
148 |
Fired when progress is terminated due to preset time expiring.
149 | Also available via the {{domxref("XMLHttpRequestEventTarget/ontimeout", "ontimeout")}} property.
150 |
151 | 152 |

Specifications

153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 |
SpecificationStatusComment
{{SpecName('XMLHttpRequest')}}{{Spec2('XMLHttpRequest')}}Live standard, latest version
170 | 171 |

Browser compatibility

172 | 173 | 174 | 175 |
{{Compat("api.XMLHttpRequest")}}
176 | 177 |

See also

178 | 179 | 192 | -------------------------------------------------------------------------------- /files/en-us/web/api/web_storage_api/using_the_web_storage_api/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Using the Web Storage API 3 | slug: Web/API/Web_Storage_API/Using_the_Web_Storage_API 4 | tags: 5 | - API 6 | - Guide 7 | - Storage 8 | - Web Storage API 9 | - localStorage 10 | - sessionStorage 11 | --- 12 |
{{DefaultAPISidebar("Web Storage API")}}
13 | 14 |

The Web Storage API provides mechanisms by which browsers can securely store key/value pairs.

15 | 16 |

This article provides a walkthrough of how to make use of this technology.

17 | 18 |

Basic concepts

19 | 20 |

Storage objects are simple key-value stores, similar to objects, but they stay intact through page loads. The keys and the values are always strings (note that, as with objects, integer keys will be automatically converted to strings). You can access these values like an object, or with the {{domxref("Storage.getItem()")}} and {{domxref("Storage.setItem()")}} methods. These three lines all set the (same) colorSetting entry:

21 | 22 |
localStorage.colorSetting = '#a4509b';
 23 | localStorage['colorSetting'] = '#a4509b';
 24 | localStorage.setItem('colorSetting', '#a4509b');
25 | 26 |
27 |

Note: It's recommended to use the Web Storage API (setItem, getItem, removeItem, key, length) to prevent the pitfalls associated with using plain objects as key-value stores.

28 |
29 | 30 |

The two mechanisms within Web Storage are as follows:

31 | 32 | 36 | 37 |

These mechanisms are available via the {{domxref("Window.sessionStorage")}} and {{domxref("Window.localStorage")}} properties (to be more precise, in supporting browsers the Window object implements the WindowLocalStorage and WindowSessionStorage objects, which the localStorage and sessionStorage properties are members of) — invoking one of these will create an instance of the {{domxref("Storage")}} object, through which data items can be set, retrieved, and removed. A different Storage object is used for the sessionStorage and localStorage for each origin — they function and are controlled separately.

38 | 39 |

So, for example, initially calling localStorage on a document will return a {{domxref("Storage")}} object; calling sessionStorage on a document will return a different {{domxref("Storage")}} object. Both of these can be manipulated in the same way, but separately.

40 | 41 |

Feature-detecting localStorage

42 | 43 |

To be able to use localStorage, we should first verify that it is supported and available in the current browsing session.

44 | 45 |

Testing for availability

46 | 47 |
48 |

Note: This API is available in current versions of all major browsers. Testing for availability is necessary only if you must support very old browsers, such as Internet Explorer 6 or 7, or in the limited circumstances described below.

49 |
50 | 51 |

Browsers that support localStorage have a property on the window object named localStorage. However, just asserting that that property exists may throw exceptions. If the localStorage object does exist, there is still no guarantee that the localStorage API is actually available, as various browsers offer settings that disable localStorage. So a browser may support localStorage, but not make it available to the scripts on the page.

52 | 53 |

For example, Safari browser in Private Browsing mode gives us an empty localStorage object with a quota of zero, effectively making it unusable. Conversely, we might get a legitimate QuotaExceededError, which means that we've used up all available storage space, but storage is actually available. Our feature detection should take these scenarios into account.

54 | 55 |

Here is a function that detects whether localStorage is both supported and available:

56 | 57 |
function storageAvailable(type) {
 58 |     var storage;
 59 |     try {
 60 |         storage = window[type];
 61 |         var x = '__storage_test__';
 62 |         storage.setItem(x, x);
 63 |         storage.removeItem(x);
 64 |         return true;
 65 |     }
 66 |     catch(e) {
 67 |         return e instanceof DOMException && (
 68 |             // everything except Firefox
 69 |             e.code === 22 ||
 70 |             // Firefox
 71 |             e.code === 1014 ||
 72 |             // test name field too, because code might not be present
 73 |             // everything except Firefox
 74 |             e.name === 'QuotaExceededError' ||
 75 |             // Firefox
 76 |             e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
 77 |             // acknowledge QuotaExceededError only if there's something already stored
 78 |             (storage && storage.length !== 0);
 79 |     }
 80 | }
81 | 82 |

And here is how you would use it:

83 | 84 |
if (storageAvailable('localStorage')) {
 85 |   // Yippee! We can use localStorage awesomeness
 86 | }
 87 | else {
 88 |   // Too bad, no localStorage for us
 89 | }
90 | 91 |

You can test for sessionStorage instead by calling storageAvailable('sessionStorage').

92 | 93 |

See here for a brief history of feature-detecting localStorage.

94 | 95 |

Example

96 | 97 |

To illustrate some typical web storage usage, we have created an example, imaginatively called Web Storage Demo. The landing page provides controls that can be used to customize the color, font, and decorative image:

98 | 99 |

When you choose different options, the page is instantly updated; in addition, your choices are stored in localStorage, so that when you leave the page and load it again, later on, your choices are remembered.

100 | 101 |

We have also provided an event output page — if you load this page in another tab, then make changes to your choices in the landing page, you'll see the updated storage information outputted as a {{domxref("StorageEvent")}} is fired.

102 | 103 |

104 | 105 |
106 |

Note: As well as viewing the example pages live using the above links, you can also check out the source code.

107 |
108 | 109 |

Testing whether your storage has been populated

110 | 111 |

To start with, in main.js, we test whether the storage object has already been populated (i.e., the page was previously accessed):

112 | 113 |
if(!localStorage.getItem('bgcolor')) {
114 |   populateStorage();
115 | } else {
116 |   setStyles();
117 | }
118 | 119 |

The {{domxref("Storage.getItem()")}} method is used to get a data item from storage; in this case, we are testing to see whether the bgcolor item exists; if not, we run populateStorage() to add the existing customization values to the storage. If there are already values there, we run setStyles() to update the page styling with the stored values.

120 | 121 |

Note: You could also use {{domxref("Storage.length")}} to test whether the storage object is empty or not.

122 | 123 |

Getting values from storage

124 | 125 |

As noted above, values can be retrieved from storage using {{domxref("Storage.getItem()")}}. This takes the key of the data item as an argument, and returns the data value. For example:

126 | 127 |
function setStyles() {
128 |   var currentColor = localStorage.getItem('bgcolor');
129 |   var currentFont = localStorage.getItem('font');
130 |   var currentImage = localStorage.getItem('image');
131 | 
132 |   document.getElementById('bgcolor').value = currentColor;
133 |   document.getElementById('font').value = currentFont;
134 |   document.getElementById('image').value = currentImage;
135 | 
136 |   htmlElem.style.backgroundColor = '#' + currentColor;
137 |   pElem.style.fontFamily = currentFont;
138 |   imgElem.setAttribute('src', currentImage);
139 | }
140 | 141 |

Here, the first three lines grab the values from local storage. Next, we set the values displayed in the form elements to those values, so that they keep in sync when you reload the page. Finally, we update the styles/decorative image on the page, so your customization options come up again on reload.

142 | 143 |

Setting values in storage

144 | 145 |

{{domxref("Storage.setItem()")}} is used both to create new data items, and (if the data item already exists) update existing values. This takes two arguments — the key of the data item to create/modify, and the value to store in it.

146 | 147 |
function populateStorage() {
148 |   localStorage.setItem('bgcolor', document.getElementById('bgcolor').value);
149 |   localStorage.setItem('font', document.getElementById('font').value);
150 |   localStorage.setItem('image', document.getElementById('image').value);
151 | 
152 |   setStyles();
153 | }
154 | 155 |

The populateStorage() function sets three items in local storage — the background color, font, and image path. It then runs the setStyles() function to update the page styles, etc.

156 | 157 |

We've also included an onchange handler on each form element so that the data and styling are updated whenever a form value is changed:

158 | 159 |
bgcolorForm.onchange = populateStorage;
160 | fontForm.onchange = populateStorage;
161 | imageForm.onchange = populateStorage;
162 | 163 |

Responding to storage changes with the StorageEvent

164 | 165 |

The {{domxref("StorageEvent")}} is fired whenever a change is made to the {{domxref("Storage")}} object (note that this event is not fired for sessionStorage changes). This won't work on the same page that is making the changes — it is really a way for other pages on the domain using the storage to sync any changes that are made. Pages on other domains can't access the same storage objects.

166 | 167 |

On the events page (see events.js) the only JavaScript is as follows:

168 | 169 |
window.addEventListener('storage', function(e) {
170 |   document.querySelector('.my-key').textContent = e.key;
171 |   document.querySelector('.my-old').textContent = e.oldValue;
172 |   document.querySelector('.my-new').textContent = e.newValue;
173 |   document.querySelector('.my-url').textContent = e.url;
174 |   document.querySelector('.my-storage').textContent = JSON.stringify(e.storageArea);
175 | });
176 | 177 |

Here we add an event listener to the window object that fires when the {{domxref("Storage")}} object associated with the current origin is changed. As you can see above, the event object associated with this event has a number of properties containing useful information — the key of the data that changed, the old value before the change, the new value after that change, the URL of the document that changed the storage, and the storage object itself (which we've stringified so you can see its content).

178 | 179 |

Deleting data records

180 | 181 |

Web Storage also provides a couple of simple methods to remove data. We don't use these in our demo, but they are very simple to add to your project:

182 | 183 | 187 | 188 |

Specifications

189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 |
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'webstorage.html#webstorage')}}{{Spec2('HTML WHATWG')}}
206 | 207 |

Browser compatibility

208 | 209 |

Window.localStorage

210 | 211 |
212 | 213 | 214 |

{{Compat("api.Window.localStorage")}}

215 | 216 |

Window.sessionStorage

217 | 218 |
219 | 220 | 221 |

{{Compat("api.Window.sessionStorage")}}

222 |
223 |
224 | 225 |

All browsers have varying capacity levels for both localStorage and sessionStorage. Here is a detailed rundown of all the storage capacities for various browsers.

226 | 227 |

See also

228 | 229 | 232 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # Licenses for MDN content 2 | 3 | MDN's content (including prose and code examples) is entirely available 4 | under various open source licenses. This file covers the types of 5 | content we provide and what licenses are in effect for each. 6 | 7 | ## License for all prose content 8 | 9 | All prose content is available under 10 | ([CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/)). 11 | 12 | ### Text of CC-BY-SA-2.5 license 13 | 14 | ``` 15 | Creative Commons Attribution-ShareAlike 2.5 16 | 17 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. 18 | 19 | License 20 | 21 | THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. 22 | 23 | BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. 24 | 25 | 1. Definitions 26 | a. "Collective Work" means a work, such as a periodical issue, anthology or encyclopedia, in which the Work in its entirety in unmodified form, along with a number of other contributions, constituting separate and independent works in themselves, are assembled into a collective whole. A work that constitutes a Collective Work will not be considered a Derivative Work (as defined below) for the purposes of this License. 27 | b. "Derivative Work" means a work based upon the Work or upon the Work and other pre-existing works, such as a translation, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or any other form in which the Work may be recast, transformed, or adapted, except that a work that constitutes a Collective Work will not be considered a Derivative Work for the purpose of this License. For the avoidance of doubt, where the Work is a musical composition or sound recording, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered a Derivative Work for the purpose of this License. 28 | c. "Licensor" means the individual or entity that offers the Work under the terms of this License. 29 | d. "Original Author" means the individual or entity who created the Work. 30 | e. "Work" means the copyrightable work of authorship offered under the terms of this License. 31 | f. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. 32 | g. "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike. 33 | 2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or restrict any rights arising from fair use, first sale or other limitations on the exclusive rights of the copyright owner under copyright law or other applicable laws. 34 | 3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: 35 | a. to reproduce the Work, to incorporate the Work into one or more Collective Works, and to reproduce the Work as incorporated in the Collective Works; 36 | b. to create and reproduce Derivative Works; 37 | c. to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission the Work including as incorporated in Collective Works; 38 | d. to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission Derivative Works. 39 | e. For the avoidance of doubt, where the work is a musical composition: 40 | i. Performance Royalties Under Blanket Licenses. Licensor waives the exclusive right to collect, whether individually or via a performance rights society (e.g. ASCAP, BMI, SESAC), royalties for the public performance or public digital performance (e.g. webcast) of the Work. 41 | ii. Mechanical Rights and Statutory Royalties. Licensor waives the exclusive right to collect, whether individually or via a music rights society or designated agent (e.g. Harry Fox Agency), royalties for any phonorecord You create from the Work ("cover version") and distribute, subject to the compulsory license created by 17 USC Section 115 of the US Copyright Act (or the equivalent in other jurisdictions). 42 | f. Webcasting Rights and Statutory Royalties. For the avoidance of doubt, where the Work is a sound recording, Licensor waives the exclusive right to collect, whether individually or via a performance-rights society (e.g. SoundExchange), royalties for the public digital performance (e.g. webcast) of the Work, subject to the compulsory license created by 17 USC Section 114 of the US Copyright Act (or the equivalent in other jurisdictions). 43 | 44 | The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by Licensor are hereby reserved. 45 | 4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: 46 | a. You may distribute, publicly display, publicly perform, or publicly digitally perform the Work only under the terms of this License, and You must include a copy of, or the Uniform Resource Identifier for, this License with every copy or phonorecord of the Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Work that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Work itself to be made subject to the terms of this License. If You create a Collective Work, upon notice from any Licensor You must, to the extent practicable, remove from the Collective Work any credit as required by clause 4(c), as requested. If You create a Derivative Work, upon notice from any Licensor You must, to the extent practicable, remove from the Derivative Work any credit as required by clause 4(c), as requested. 47 | b. You may distribute, publicly display, publicly perform, or publicly digitally perform a Derivative Work only under the terms of this License, a later version of this License with the same License Elements as this License, or a Creative Commons iCommons license that contains the same License Elements as this License (e.g. Attribution-ShareAlike 2.5 Japan). You must include a copy of, or the Uniform Resource Identifier for, this License or other license specified in the previous sentence with every copy or phonorecord of each Derivative Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Derivative Works that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder, and You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Derivative Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Derivative Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Derivative Work itself to be made subject to the terms of this License. 48 | c. If you distribute, publicly display, publicly perform, or publicly digitally perform the Work or any Derivative Works or Collective Works, You must keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or (ii) if the Original Author and/or Licensor designate another party or parties (e.g. a sponsor institute, publishing entity, journal) for attribution in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; the title of the Work if supplied; to the extent reasonably practicable, the Uniform Resource Identifier, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and in the case of a Derivative Work, a credit identifying the use of the Work in the Derivative Work (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). Such credit may be implemented in any reasonable manner; provided, however, that in the case of a Derivative Work or Collective Work, at a minimum such credit will appear where any other comparable authorship credit appears and in a manner at least as prominent as such other comparable authorship credit. 49 | 5. Representations, Warranties and Disclaimer 50 | 51 | UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE MATERIALS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. 52 | 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 53 | 7. Termination 54 | a. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Derivative Works or Collective Works from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. 55 | b. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. 56 | 8. Miscellaneous 57 | a. Each time You distribute or publicly digitally perform the Work or a Collective Work, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. 58 | b. Each time You distribute or publicly digitally perform a Derivative Work, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. 59 | c. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. 60 | d. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. 61 | e. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. 62 | 63 | Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor. 64 | 65 | Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, neither party will use the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. 66 | 67 | Creative Commons may be contacted at http://creativecommons.org/. 68 | ``` 69 | 70 | ## Licenses for code examples and snippets 71 | 72 | ### Added on or after August 20, 2010 73 | 74 | Code examples and snippets added on or after August 20, 2010 are in the public domain 75 | ([CC0](https://creativecommons.org/publicdomain/zero/1.0/legalcode)). No licensing notice 76 | is necessary, but if you need one, you can use: 77 | ``` 78 | Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ 79 | ``` 80 | 81 | #### Text of CC0 license 82 | 83 | ``` 84 | Creative Commons Legal Code 85 | 86 | CC0 1.0 Universal 87 | 88 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 89 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 90 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 91 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 92 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 93 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 94 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 95 | HEREUNDER. 96 | 97 | Statement of Purpose 98 | 99 | The laws of most jurisdictions throughout the world automatically confer 100 | exclusive Copyright and Related Rights (defined below) upon the creator 101 | and subsequent owner(s) (each and all, an "owner") of an original work of 102 | authorship and/or a database (each, a "Work"). 103 | 104 | Certain owners wish to permanently relinquish those rights to a Work for 105 | the purpose of contributing to a commons of creative, cultural and 106 | scientific works ("Commons") that the public can reliably and without fear 107 | of later claims of infringement build upon, modify, incorporate in other 108 | works, reuse and redistribute as freely as possible in any form whatsoever 109 | and for any purposes, including without limitation commercial purposes. 110 | These owners may contribute to the Commons to promote the ideal of a free 111 | culture and the further production of creative, cultural and scientific 112 | works, or to gain reputation or greater distribution for their Work in 113 | part through the use and efforts of others. 114 | 115 | For these and/or other purposes and motivations, and without any 116 | expectation of additional consideration or compensation, the person 117 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 118 | is an owner of Copyright and Related Rights in the Work, voluntarily 119 | elects to apply CC0 to the Work and publicly distribute the Work under its 120 | terms, with knowledge of his or her Copyright and Related Rights in the 121 | Work and the meaning and intended legal effect of CC0 on those rights. 122 | 123 | 1. Copyright and Related Rights. A Work made available under CC0 may be 124 | protected by copyright and related or neighboring rights ("Copyright and 125 | Related Rights"). Copyright and Related Rights include, but are not 126 | limited to, the following: 127 | 128 | i. the right to reproduce, adapt, distribute, perform, display, 129 | communicate, and translate a Work; 130 | ii. moral rights retained by the original author(s) and/or performer(s); 131 | iii. publicity and privacy rights pertaining to a person's image or 132 | likeness depicted in a Work; 133 | iv. rights protecting against unfair competition in regards to a Work, 134 | subject to the limitations in paragraph 4(a), below; 135 | v. rights protecting the extraction, dissemination, use and reuse of data 136 | in a Work; 137 | vi. database rights (such as those arising under Directive 96/9/EC of the 138 | European Parliament and of the Council of 11 March 1996 on the legal 139 | protection of databases, and under any national implementation 140 | thereof, including any amended or successor version of such 141 | directive); and 142 | vii. other similar, equivalent or corresponding rights throughout the 143 | world based on applicable law or treaty, and any national 144 | implementations thereof. 145 | 146 | 2. Waiver. To the greatest extent permitted by, but not in contravention 147 | of, applicable law, Affirmer hereby overtly, fully, permanently, 148 | irrevocably and unconditionally waives, abandons, and surrenders all of 149 | Affirmer's Copyright and Related Rights and associated claims and causes 150 | of action, whether now known or unknown (including existing as well as 151 | future claims and causes of action), in the Work (i) in all territories 152 | worldwide, (ii) for the maximum duration provided by applicable law or 153 | treaty (including future time extensions), (iii) in any current or future 154 | medium and for any number of copies, and (iv) for any purpose whatsoever, 155 | including without limitation commercial, advertising or promotional 156 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 157 | member of the public at large and to the detriment of Affirmer's heirs and 158 | successors, fully intending that such Waiver shall not be subject to 159 | revocation, rescission, cancellation, termination, or any other legal or 160 | equitable action to disrupt the quiet enjoyment of the Work by the public 161 | as contemplated by Affirmer's express Statement of Purpose. 162 | 163 | 3. Public License Fallback. Should any part of the Waiver for any reason 164 | be judged legally invalid or ineffective under applicable law, then the 165 | Waiver shall be preserved to the maximum extent permitted taking into 166 | account Affirmer's express Statement of Purpose. In addition, to the 167 | extent the Waiver is so judged Affirmer hereby grants to each affected 168 | person a royalty-free, non transferable, non sublicensable, non exclusive, 169 | irrevocable and unconditional license to exercise Affirmer's Copyright and 170 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 171 | maximum duration provided by applicable law or treaty (including future 172 | time extensions), (iii) in any current or future medium and for any number 173 | of copies, and (iv) for any purpose whatsoever, including without 174 | limitation commercial, advertising or promotional purposes (the 175 | "License"). The License shall be deemed effective as of the date CC0 was 176 | applied by Affirmer to the Work. Should any part of the License for any 177 | reason be judged legally invalid or ineffective under applicable law, such 178 | partial invalidity or ineffectiveness shall not invalidate the remainder 179 | of the License, and in such case Affirmer hereby affirms that he or she 180 | will not (i) exercise any of his or her remaining Copyright and Related 181 | Rights in the Work or (ii) assert any associated claims and causes of 182 | action with respect to the Work, in either case contrary to Affirmer's 183 | express Statement of Purpose. 184 | 185 | 4. Limitations and Disclaimers. 186 | 187 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 188 | surrendered, licensed or otherwise affected by this document. 189 | b. Affirmer offers the Work as-is and makes no representations or 190 | warranties of any kind concerning the Work, express, implied, 191 | statutory or otherwise, including without limitation warranties of 192 | title, merchantability, fitness for a particular purpose, non 193 | infringement, or the absence of latent or other defects, accuracy, or 194 | the present or absence of errors, whether or not discoverable, all to 195 | the greatest extent permissible under applicable law. 196 | c. Affirmer disclaims responsibility for clearing rights of other persons 197 | that may apply to the Work or any use thereof, including without 198 | limitation any person's Copyright and Related Rights in the Work. 199 | Further, Affirmer disclaims responsibility for obtaining any necessary 200 | consents, permissions or other rights required for any use of the 201 | Work. 202 | d. Affirmer understands and acknowledges that Creative Commons is not a 203 | party to this document and has no duty or obligation with respect to 204 | this CC0 or use of the Work. 205 | ``` 206 | 207 | ### Added before August 20, 2010 208 | 209 | Code examples and snippets added before August 20, 2010 are available under 210 | the [MIT license](https://opensource.org/licenses/MIT). You should insert 211 | the following attribution information into the MIT license template: 212 | ``` 213 | © 214 | ``` 215 | 216 | #### Text of MIT license template 217 | 218 | ``` 219 | Copyright 220 | 221 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 222 | software and associated documentation files (the "Software"), to deal in the Software 223 | without restriction, including without limitation the rights to use, copy, modify, merge, 224 | publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons 225 | to whom the Software is furnished to do so, subject to the following conditions: 226 | 227 | The above copyright notice and this permission notice shall be included in all copies or 228 | substantial portions of the Software. 229 | 230 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 231 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 232 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 233 | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 234 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 235 | DEALINGS IN THE SOFTWARE. 236 | ``` 237 | -------------------------------------------------------------------------------- /files/en-us/learn/getting_started_with_the_web/javascript_basics/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: JavaScript basics 3 | slug: Learn/Getting_started_with_the_web/JavaScript_basics 4 | tags: 5 | - Beginner 6 | - CodingScripting 7 | - JavaScript 8 | - Learn 9 | - Web 10 | - 'l10n:priority' 11 | --- 12 |
{{LearnSidebar}}
13 | 14 |
{{PreviousMenuNext("Learn/Getting_started_with_the_web/CSS_basics", "Learn/Getting_started_with_the_web/Publishing_your_website", "Learn/Getting_started_with_the_web")}}
15 | 16 |
17 |

JavaScript is a programming language that adds interactivity to your website. This happens in games, in the behavior of responses when buttons are pressed or with data entry on forms; with dynamic styling; with animation, etc. This article helps you get started with JavaScript and furthers your understanding of what is possible.

18 |
19 | 20 |

What is JavaScript?

21 | 22 |

{{Glossary("JavaScript")}} ("JS" for short) is a full-fledged {{Glossary("Dynamic programming language", "dynamic programming language")}} that can add interactivity to a website. It was invented by Brendan Eich (co-founder of the Mozilla project, the Mozilla Foundation, and the Mozilla Corporation).

23 | 24 |

JavaScript is versatile and beginner-friendly. With more experience, you'll be able to create games, animated 2D and 3D graphics, comprehensive database-driven apps, and much more!

25 | 26 |

JavaScript itself is relatively compact, yet very flexible. Developers have written a variety of tools on top of the core JavaScript language, unlocking a vast amount of functionality with minimum effort. These include:

27 | 28 |
    29 |
  • Browser Application Programming Interfaces ({{Glossary("API","APIs")}}) built into web browsers, providing functionality such as dynamically creating HTML and setting CSS styles; collecting and manipulating a video stream from a user's webcam, or generating 3D graphics and audio samples.
  • 30 |
  • Third-party APIs that allow developers to incorporate functionality in sites from other content providers, such as Twitter or Facebook.
  • 31 |
  • Third-party frameworks and libraries that you can apply to HTML to accelerate the work of building sites and applications.
  • 32 |
33 | 34 |

It's outside the scope of this article—as a light introduction to JavaScript—to present the details of how the core JavaScript language is different from the tools listed above. You can learn more in MDN's JavaScript learning area, as well as in other parts of MDN.

35 | 36 |

The section below introduces some aspects of the core language, and offers an opportunity to play with a few browser API features too. Have fun!

37 | 38 |

A Hello world! example

39 | 40 |

JavaScript is one of the most popular modern web technologies! As your JavaScript skills grow, your websites will enter a new dimension of power and creativity.

41 | 42 |

However, getting comfortable with JavaScript is more challenging than getting comfortable with HTML and CSS. You may have to start small, and progress gradually. To begin, let's examine how to add JavaScript to your page for creating a Hello world! example. (Hello world! is the standard for introductory programming examples.)

43 | 44 |
45 |

Important: If you haven't been following along with the rest of our course, download this example code and use it as a starting point.

46 |
47 | 48 |
    49 |
  1. Go to your test site and create a new folder named scripts. Within the scripts folder, create a new file called main.js, and save it.
  2. 50 |
  3. In your index.html file, enter this code on a new line, just before the closing </body> tag: 51 |
    <script src="scripts/main.js"></script>
    52 |
  4. 53 |
  5. This is doing the same job as the {{htmlelement("link")}} element for CSS. It applies the JavaScript to the page, so it can have an effect on the HTML (along with the CSS, and anything else on the page).
  6. 54 |
  7. Add this code to the main.js file: 55 |
    const myHeading = document.querySelector('h1');
     56 | myHeading.textContent = 'Hello world!';
    57 |
  8. 58 |
  9. Make sure the HTML and JavaScript files are saved. Then load index.html in your browser. You should see something like this:
  10. 59 |
60 | 61 |
62 |

Note: The reason the instructions (above) place the {{htmlelement("script")}} element near the bottom of the HTML file is that the browser reads code in the order it appears in the file.

63 | 64 |

If the JavaScript loads first and it is supposed to affect the HTML that hasn't loaded yet, there could be problems. Placing JavaScript near the bottom of an HTML page is one way to accommodate this dependency. To learn more about alternative approaches, see Script loading strategies.

65 |
66 | 67 |

What happened?

68 | 69 |

The heading text changed to Hello world! using JavaScript. You did this by using a function called {{domxref("Document.querySelector", "querySelector()")}} to grab a reference to your heading, and then store it in a variable called myHeading. This is similar to what we did using CSS selectors. When you want to do something to an element, you need to select it first.

70 | 71 |

Following that, the code set the value of the myHeading variable's {{domxref("Node.textContent", "textContent")}} property (which represents the content of the heading) to Hello world!.

72 | 73 |
74 |

Note: Both of the features you used in this exercise are parts of the Document Object Model (DOM) API, which has the capability to manipulate documents.

75 |
76 | 77 |

Language basics crash course

78 | 79 |

To give you a better understanding of how JavaScript works, let's explain some of the core features of the language. It's worth noting that these features are common to all programming languages. If you master these fundamentals, you have a head start on coding in other languages too!

80 | 81 |
82 |

Important: In this article, try entering the example code lines into your JavaScript console to see what happens. For more details on JavaScript consoles, see Discover browser developer tools.

83 |
84 | 85 |

Variables

86 | 87 |

{{Glossary("Variable", "Variables")}} are containers that store values. You start by declaring a variable with the var (less recommended, dive deeper for the explanation) or the let keyword, followed by the name you give to the variable:

88 | 89 |
let myVariable;
90 | 91 |
92 |

Note: A semicolon at the end of a line indicates where a statement ends. It is only required when you need to separate statements on a single line. However, some people believe it's good practice to have semicolons at the end of each statement. There are other rules for when you should and shouldn't use semicolons. For more details, see Your Guide to Semicolons in JavaScript.

93 |
94 | 95 |
96 |

Note: You can name a variable nearly anything, but there are some restrictions. (See this section about naming rules.) If you are unsure, you can check your variable name to see if it's valid.

97 |
98 | 99 |
100 |

Note: JavaScript is case sensitive. This means myVariable is not the same as myvariable. If you have problems in your code, check the case!

101 |
102 | 103 |
104 |

Note: For more details about the difference between var and let, see The difference between var and let.

105 |
106 | 107 |

After declaring a variable, you can give it a value:

108 | 109 |
myVariable = 'Bob';
110 | 
111 | 112 |

Also, you can do both these operations on the same line:

113 | 114 |
let myVariable = 'Bob';
115 | 116 |

You retrieve the value by calling the variable name:

117 | 118 |
myVariable;
119 | 120 |

After assigning a value to a variable, you can change it later in the code:

121 | 122 |
let myVariable = 'Bob';
123 | myVariable = 'Steve';
124 | 125 |

Note that variables may hold values that have different data types:

126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 157 | 158 | 159 | 160 | 161 | 163 | 164 | 165 |
VariableExplanationExample
{{Glossary("String")}}This is a sequence of text known as a string. To signify that the value is a string, enclose it in single quote marks.let myVariable = 'Bob';
{{Glossary("Number")}}This is a number. Numbers don't have quotes around them.let myVariable = 10;
{{Glossary("Boolean")}}This is a True/False value. The words true and false are special keywords that don't need quote marks.let myVariable = true;
{{Glossary("Array")}}This is a structure that allows you to store multiple values in a single reference.let myVariable = [1,'Bob','Steve',10];
155 | Refer to each member of the array like this:
156 | myVariable[0], myVariable[1], etc.
{{Glossary("Object")}}This can be anything. Everything in JavaScript is an object, and can be stored in a variable. Keep this in mind as you learn.let myVariable = document.querySelector('h1');
162 | All of the above examples too.
166 | 167 |

So why do we need variables? Variables are necessary to do anything interesting in programming. If values couldn't change, then you couldn't do anything dynamic, like personalize a greeting message or change an image displayed in an image gallery.

168 | 169 |

Comments

170 | 171 |

Comments are snippets of text that can be added along with code. The browser ignores text marked as comments. You can write comments in JavaScript just as you can in CSS:

172 | 173 |
/*
174 | Everything in between is a comment.
175 | */
176 | 177 |

If your comment contains no line breaks, it's an option to put it behind two slashes like this:

178 | 179 |
// This is a comment
180 | 
181 | 182 |

Operators

183 | 184 |

An {{Glossary("operator")}} is a mathematical symbol which produces a result based on two values (or variables). In the following table you can see some of the simplest operators, along with some examples to try in the JavaScript console.

185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 202 | 203 | 204 | 205 | 206 | 207 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 223 | 224 | 225 | 226 | 227 | 228 | 239 | 240 | 241 |
OperatorExplanationSymbol(s)Example
AdditionAdd two numbers together or combine two strings.+6 + 9;
201 | 'Hello ' + 'world!';
Subtraction, Multiplication, DivisionThese do what you'd expect them to do in basic math.-, *, /9 - 3;
208 | 8 * 2; // multiply in JS is an asterisk
209 | 9 / 3;
AssignmentAs you've seen already: this assigns a value to a variable.=let myVariable = 'Bob';
EqualityThis performs a test to see if two values are equal. It returns a true/false (Boolean) result.===let myVariable = 3;
222 | myVariable === 4;
Not, Does-not-equalThis returns the logically opposite value of what it precedes. It turns a true into a false, etc.. When it is used alongside the Equality operator, the negation operator tests whether two values are not equal.!, !== 229 |

For "Not", the basic expression is true, but the comparison returns false because we negate it:

230 | 231 |

let myVariable = 3;
232 | !(myVariable === 3);

233 | 234 |

"Does-not-equal" gives basically the same result with different syntax. Here we are testing "is myVariable NOT equal to 3". This returns false because myVariable IS equal to 3:

235 | 236 |

let myVariable = 3;
237 | myVariable !== 3;

238 |
242 | 243 |

There are a lot more operators to explore, but this is enough for now. See Expressions and operators for a complete list.

244 | 245 |
246 |

Note: Mixing data types can lead to some strange results when performing calculations. Be careful that you are referring to your variables correctly, and getting the results you expect. For example, enter '35' + '25' into your console. Why don't you get the result you expected? Because the quote marks turn the numbers into strings, so you've ended up concatenating strings rather than adding numbers. If you enter 35 + 25 you'll get the total of the two numbers.

247 |
248 | 249 |

Conditionals

250 | 251 |

Conditionals are code structures used to test if an expression returns true or not. A very common form of conditionals is the if ... else statement. For example:

252 | 253 |
let iceCream = 'chocolate';
254 | if(iceCream === 'chocolate') {
255 |   alert('Yay, I love chocolate ice cream!');
256 | } else {
257 |   alert('Awwww, but chocolate is my favorite...');
258 | }
259 | 260 |

The expression inside the if( ... ) is the test. This uses the identity operator (as described above) to compare the variable iceCream with the string chocolate to see if the two are equal. If this comparison returns true, the first block of code runs. If the comparison is not true, the second block of code—after the else statement—runs instead.

261 | 262 |

Functions

263 | 264 |

{{Glossary("Function", "Functions")}} are a way of packaging functionality that you wish to reuse. It's possible to define a body of code as a function that executes when you call the function name in your code. This is a good alternative to repeatedly writing the same code. You have already seen some uses of functions previously. For example:

265 | 266 |
    267 |
  1. 268 |
    let myVariable = document.querySelector('h1');
    269 |
  2. 270 |
  3. 271 |
    alert('hello!');
    272 |
  4. 273 |
274 | 275 |

These functions, document.querySelector and alert, are built into the browser.

276 | 277 |

If you see something which looks like a variable name, but it's followed by parentheses— () —it is likely a function. Functions often take {{Glossary("Argument", "arguments")}}: bits of data they need to do their job. Arguments go inside the parentheses, separated by commas if there is more than one argument.

278 | 279 |

For example, the alert() function makes a pop-up box appear inside the browser window, but we need to give it a string as an argument to tell the function what message to display.

280 | 281 |

You can also define your own functions. In the next example, we create a simple function which takes two numbers as arguments and multiplies them:

282 | 283 |
function multiply(num1,num2) {
284 |   let result = num1 * num2;
285 |   return result;
286 | }
287 | 288 |

Try running this in the console; then test with several arguments. For example:

289 | 290 |
multiply(4, 7);
291 | multiply(20, 20);
292 | multiply(0.5, 3);
293 | 294 |
295 |

Note: The return statement tells the browser to return the result variable out of the function so it is available to use. This is necessary because variables defined inside functions are only available inside those functions. This is called variable {{Glossary("Scope", "scoping")}}. (Read more about variable scoping.)

296 |
297 | 298 |

Events

299 | 300 |

Real interactivity on a website requires events handlers. These are code structures that listen for activity in the browser, and run code in response. The most obvious example is handling the click event, which is fired by the browser when you click on something with your mouse. To demonstrate this, enter the following into your console, then click on the current webpage:

301 | 302 |
document.querySelector('html').onclick = function() {
303 |     alert('Ouch! Stop poking me!');
304 | }
305 | 306 |

There are many ways to attach an event handler to an element. Here we select the {{htmlelement("html")}} element, setting its onclick handler property equal to an anonymous (i.e. nameless) function, which contains the code we want the click event to run.

307 | 308 |

Note that

309 | 310 |
document.querySelector('html').onclick = function() {};
311 | 312 |

is equivalent to

313 | 314 |
let myHTML = document.querySelector('html');
315 | myHTML.onclick = function() {};
316 | 317 |

It's just shorter.

318 | 319 |

Supercharging our example website

320 | 321 |

With this review of JavaScript basics completed (above), let's add some new features to our example site.

322 | 323 |

Adding an image changer

324 | 325 |

In this section, you will learn how to use JavaScript and DOM API features to alternate the display of one of two images. This change will happen as a user clicks the displayed image.

326 | 327 |
    328 |
  1. Choose an image you want to feature on your example site. Ideally, the image will be the same size as the image you added previously, or as close as possible.
  2. 329 |
  3. Save this image in your images folder.
  4. 330 |
  5. Rename the image firefox2.png.
  6. 331 |
  7. Add the JavaScript below to your main.js file. (Also delete your Hello world! JavaScript from the earlier exercise.) 332 |
    let myImage = document.querySelector('img');
    333 | 
    334 | myImage.onclick = function() {
    335 |     let mySrc = myImage.getAttribute('src');
    336 |     if(mySrc === 'images/firefox-icon.png') {
    337 |       myImage.setAttribute('src','images/firefox2.png');
    338 |     } else {
    339 |       myImage.setAttribute('src','images/firefox-icon.png');
    340 |     }
    341 | }
    342 |
  8. 343 |
  9. Save all files and load index.html in the browser. Now when you click the image, it should change to the other one.
  10. 344 |
345 | 346 |

This is what happened. You stored a reference to your {{htmlelement("img")}} element in the myImage variable. Next, you made this variable's onclick event handler property equal to a function with no name (an "anonymous" function). So every time this element is clicked:

347 | 348 |
    349 |
  1. The code retrieves the value of the image's src attribute.
  2. 350 |
  3. The code uses a conditional to check if the src value is equal to the path of the original image: 351 |
      352 |
    1. If it is, the code changes the src value to the path of the second image, forcing the other image to be loaded inside the {{htmlelement("img")}} element.
    2. 353 |
    3. If it isn't (meaning it must already have changed), the src value swaps back to the original image path, to the original state.
    4. 354 |
    355 |
  4. 356 |
357 | 358 |

Adding a personalized welcome message

359 | 360 |

Next, let's change the page title to a personalized welcome message when the user first visits the site. This welcome message will persist. Should the user leave the site and return later, we will save the message using the Web Storage API. We will also include an option to change the user, and therefore, the welcome message.

361 | 362 |
    363 |
  1. In index.html, add the following line just before the {{htmlelement("script")}} element: 364 | 365 |
    <button>Change user</button>
    366 |
  2. 367 |
  3. In main.js, place the following code at the bottom of the file, exactly as it is written. This takes references to the new button and the heading, storing each inside variables: 368 |
    let myButton = document.querySelector('button');
    369 | let myHeading = document.querySelector('h1');
    370 |
  4. 371 |
  5. Add the function below to set the personalized greeting. This won't do anything yet, but this will change soon. 372 |
    function setUserName() {
    373 |   let myName = prompt('Please enter your name.');
    374 |   localStorage.setItem('name', myName);
    375 |   myHeading.textContent = 'Mozilla is cool, ' + myName;
    376 | }
    377 | The setUserName() function contains a prompt() function, which displays a dialog box, similar to alert(). This prompt() function does more than alert(), asking the user to enter data, and storing it in a variable after the user clicks OK. In this case, we are asking the user to enter a name. Next, the code calls on an API localStorage, which allows us to store data in the browser and retrieve it later. We use localStorage's setItem() function to create and store a data item called 'name', setting its value to the myName variable which contains the user's entry for the name. Finally, we set the textContent of the heading to a string, plus the user's newly stored name.
  6. 378 |
  7. Add the if ... else block (below). We could call this initialization code, as it structures the app when it first loads. 379 |
    if(!localStorage.getItem('name')) {
    380 |   setUserName();
    381 | } else {
    382 |   let storedName = localStorage.getItem('name');
    383 |   myHeading.textContent = 'Mozilla is cool, ' + storedName;
    384 | }
    385 | This first line of this block uses the negation operator (logical NOT, represented by the !) to check whether the name data exists. If not, the setUserName() function runs to create it. If it exists (that is, the user set a user name during a previous visit), we retrieve the stored name using getItem() and set the textContent of the heading to a string, plus the user's name, as we did inside setUserName().
  8. 386 |
  9. Put this onclick event handler (below) on the button. When clicked, setUserName() runs. This allows the user to enter a different name by pressing the button. 387 |
    myButton.onclick = function() {
    388 |   setUserName();
    389 | }
    390 | 
    391 |
  10. 392 |
393 | 394 |

A user name of null?

395 | 396 |

When you run the example and get the dialog box that prompts you to enter your user name, try pressing the Cancel button. You should end up with a title that reads Mozilla is cool, null. This happens because—when you cancel the prompt—the value is set as null. Null is a special value in JavaScript that refers to the absence of a value.

397 | 398 |

Also, try clicking OK without entering a name. You should end up with a title that reads Mozilla is cool, for fairly obvious reasons.

399 | 400 |

To avoid these problems, you could check that the user hasn't entered a blank name. Update your setUserName() function to this:

401 | 402 |
function setUserName() {
403 |   let myName = prompt('Please enter your name.');
404 |   if(!myName) {
405 |     setUserName();
406 |   } else {
407 |     localStorage.setItem('name', myName);
408 |     myHeading.innerHTML = 'Mozilla is cool, ' + myName;
409 |   }
410 | }
411 | 412 |

In human language, this means: If myName has no value, run setUserName() again from the start. If it does have a value (if the above statement is not true), then store the value in localStorage and set it as the heading's text.

413 | 414 |

Conclusion

415 | 416 |

If you have followed all the instructions in this article, you should end up with a page that looks something like the image below. You can also view our version.

417 | 418 |

419 | 420 |

If you get stuck, you can compare your work with our finished example code on GitHub.

421 | 422 |

We have just scratched the surface of JavaScript. If you enjoyed playing, and wish to go further, take advantage of the resources listed below.

423 | 424 |

See also

425 | 426 |
427 |
Dynamic client-side scripting with JavaScript
428 |
Dive into JavaScript in much more detail.
429 |
Learn JavaScript
430 |
This is an excellent resource for aspiring web developers! Learn JavaScript in an interactive environment, with short lessons and interactive tests, guided by an automated assessment. The first 40 lessons are free. The complete course is available for a small one-time payment.
431 |
432 | 433 |

{{PreviousMenuNext("Learn/Getting_started_with_the_web/CSS_basics", "Learn/Getting_started_with_the_web/Publishing_your_website", "Learn/Getting_started_with_the_web")}}

434 | 435 |

In this module

436 | 437 | 447 | --------------------------------------------------------------------------------