Every script tag in this cheat is HTML escaped and put inside a pre element after its script by a script so you can see it. Scripts are styled like this:
This cheatsheet is designed to work in modern ES5 compliant browsers. No effort was made to account for incompatibilities.
Content is currently being converted from Js comments to HTML + scripts. This explains the remaining huge script blocks with many useful comments.
The following helper methods are used on this cheat:
JavaScript is a language originally designed to run in a browser.
More recently, it has also been used outside of browsers, often server side, through Node.js. This cheat shall consider mostly a world without Node.js: for a Node.js cheat see: https://github.com/cirosantilli/nodejs
It can be embedded on the HTML given by the server to the browser inside script
tags.
It can also be given in separate .js
files which are then included in the HTML header.
One of the goals of JavaScript is to restrict what the language can do to prevent malicious attacks. Therefore, by design choice JavaScript does not allows dangerous operations such as file IO (this might be possible soon with: the File API) Node.js adds such abilities to JavaScript through its standard library.
JavaScript feels very Pythonic, but with less features and stdlib. CoffeScript "Rubynises" it.
JavaScript is known for having some weird quirks. CoffeScript, a language that transpiles to JavaScript but behaves more like Ruby, attempts to correct many of those quirks.
Microsoft open source Js extension: every valid Js script also a valid TypeScript one. Possible to compile it down to vanilla JavaScript.
Official language name: ECMA-262, or ECMAScript.
Versions are often abbreviated as: ES5, ES6, etc.
ECMAScript is developed by ECMA: it is therefore one of the few key web standards not maintained by W3C.
The ECMA work group that develops JavaScript is called T39. They have a wiki at: http://wiki.ecmascript.org where they organize the proposals for the next version of the standard, including features prior to approval on the strawman namespace http://wiki.ecmascript.org/doku.php?do=index&id=strawman%3Astrawman The wiki is openly readable, but only writable by contributors.
ECMAScript does not include objects which browsers add to JavaScript
such as document
, window
, XMLHttpRequest
,
although it does furnish some global objects like JSON.
Such objects are typically specified in separate W3C specs.
Browser objects are not directly available to Node.js, including useful ones such as XMLHttpRequest
.
Some projects implement the browser interfaces as a Node.js library, such as
https://github.com/driverdan/node-XMLHttpRequest
thus allowing to use such objects in Node.js / browser portable code./
6, AKA #harmony
Expected Dec 2014.
Official PDF drafts: http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts
Officially approved features list under the Harmony namespace of the official wiki: http://wiki.ecmascript.org/doku.php?do=index&id=harmony%3Aharmony
Unofficial HTML version of the draft by one of the contributors: http://people.mozilla.org/~jorendorff/es6-draft.html The official versions are in PDF.
Good cheat: https://github.com/lukehoban/es6features
Promises: http://www.html5rocks.com/en/tutorials/es6/promises/ Currently usable through several libraries.
Modules: attempts to unify CommonJS and AMD and end the mess. http://www.html5rocks.com/en/tutorials/es6/promises/ Currently usable with by transpiling: https://github.com/square/es6-module-transpiler Tutorials: http://www.2ality.com/2013/07/es6-modules.html
5.1, 2011: http://www.ecma-international.org/ecma-262/5.1/
5: 2009.
Generally implemented.
Fully implemented by Google's V8 engine for Chrome and Node.js.
http://www.ecma-international.org/publications/standards/Ecma-262.htm
was aborted
1999
Not possible?! http://stackoverflow.com/questions/7340726/detect-version-of-javascript
People recommend checking for individual features instead.
Besides the standards, also check out:
Since JavaScript is sent to browsers over the network, methods have been developed to make JavaScript code smaller:
Compress JavaScript with gzip before sending. Notify browser with Content-Encoding
HTTP header.
Remove unnecessary characters like whitespaces.
Rename variables and functions to shorter names, factor things out in ways that are shorter but hard for humans to understand.
jsfuck: arbitrary Js in only 6 characters https://github.com/aemkei/jsfuck https://blog.checkpoint.com/2016/02/02/ebay-platform-exposed-to-severe-vulnerability/
Concatenate multiple Js files together.
OK, not really a form of compression, but serves the same purpose: make things faster, in this case by reducing the number of HTTP requests.
When writing JavaScript code, you must be aware that this can happen, and that it may have consequences. See for example the Semicolon before IIFE pattern.
.js
files and included with script src=
onclick
, whose usage is discouraged.script
elements can appear either inside the head or of the body.
The most commonly recommended place is load all scripts just before the closing body
tag,
so that the page can load before long scripts do, so it seems more responsive.
It is not valid to put scripts after the body
tag, as HTML specifies that only
comments can be put there.
Scripts are executed in the order which they appear on the file.
head scripts are executed before body ones.
Definitions from previous scripts blocks are kept for future script blocks:
Errors and uncaught exceptions (e.g. undefined variables) only stop execution of the current script block: future script blocks still execute. There is no way to prevent future script blocks from executing.
Source a script from a separate .js
file.
The included script behaves exactly as a script inside a script
element:
it can for example get and set cookies. Therefore, when you include a third-party script you
must future-trust the source or they can hack your users away.
In HTML5, the script
tag *cannot* be self closing
because it is neither void nor foreign.
In HTML5 you cannot have src
and a non-empty innerHTML
:
http://stackoverflow.com/questions/6528325/what-does-a-script-tag-with-src-and-content-mean
It is possible to run external scripts asynchronously.
This makes script run other unpredictable.
Can only be used for external scripts.
Before HTML5 it was mandatory to specify the language of the script as an
attribute to the script tag: type="text/javascript"
In HTML5 js became the default, so the attribute is not needed anymore.
Any HTML tags can be included inside a script element except the closing script tag. The HTML parser just reads everything up to that and then passes it to the Js interpreter.
A common technique to write a literal </script> string inside JavaScript it to break it up
with concatenation as /scr'+'ipt
ES5.
Throws exceptions in a bunch of extra smelly cases.
Seems to be the only current directive,
although there are extension directives like asm.js "use asm"
Turn on for entire script element:
Turn on for single function:
Separates statements.
Good tutorial http://inimino.org/~inimino/blog/javascript_semicolons
Automatic semicolon insertion.
In most cases, semicolons are automatically added by the parser at newlines:
There are a few complex cases however.
Operators inhibit ASI to allow programmers to write:
Because of ASI, many people use a coding style without semicolons, using them only for the only exception: lines that start with parenthesis:
One notable case where this happens is for IIFE scope preservation.
TODO why are semicolons are not required are in single line functions:
Advantages of using semicolons:
It is a controversial subject which style is better. This is one of the things CoffeScript takes care of.
GitHub style says no semicolons. Rationale: http://mislav.uniqpath.com/2010/05/semicolons/
Google says semicolons. Rationale: http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml#Semicolons
Like C++.
Identifiers can contain very weird characters. http://stackoverflow.com/questions/1661197/valid-characters-for-javascript-variable-names
The first character is more restricted than the following ones, for example it cannot be a number.
Some libraries make extensive use of such variables, notably JQuery which uses the dollar sign $
which is an alias for jQuery.
Make sure to use meta charset=UTF-8
if you really want to use non ASCII identifier chars.
JavaScript is case sensitive.
It is unfortunate that many standard classes use all uppercase case for initials
or even worse: mixed standards like the insane XMLHttpRequest
,
which has two case standards on a single identifier:
XML
all uppercase and (insane) and Http
camel.
Only functions with var
generate new scopes,
not blocks like if
in general.
Binary negation.
Common application: transform -1
into 0
on indexOf
(jQuery inArray
).
Works because number representation is fixed at 2's complement and in that case:
~-1 == 0
~-1 == 0~x == 0
Evaluates expression and returns undefined
.
TODO applications, besides golfing for undefined
, specially on discouraged javascript:void(0)
hrefs: ?
http://stackoverflow.com/questions/1291942/what-does-javascriptvoid0-mean
Since this is an operator, the parenthesis are not required. If added, what is inside of them is evaluated, so it also works:
But it might be required to avoid some parsing errors like
ReferenceError: invalid assignment left hand side
:
Bad practice: http://stackoverflow.com/questions/1291942/what-does-javascriptvoid0-mean Only use links for links: for other things use styled spans.
Evaluate JavaScript and open it on the new page if the result is not undefined
.
TODO: W3C standard? Likely not, since not even in IANA.
If undefined
, do nothing, and unlike number sign URL,
#
don't go to the top of the page.
Often used with void(0)
, which is golf for undefined
to make links
which trigger scripts instead of opening pages. Used because the href
attribute is mandatory for valid HTML.
TODO: vs javascript:;
Also used instead of straight undefined
because undefined
can be redefined to something else, while void
can't.
Major problem with that technique: middle click still opens up a new tab / window
with address javascript:void(0)
that shows nothing on the screen.
Yes, go ahead and type javascript:something
on you browser URL, it will work.
Variables contain address of data.
=
always takes the address of the data on the right and sets it to the variable on the left.
Integers like `0` and `1` *do* have a single (because immutable) address in JavaScript.
Not possible, unless derived from function.
Allow property getting and assignment to do magic user define things.
In literals with get
and set
:
Programmatically with ES5 defineProperty
__defineGetter__
and __defineSetter__
are nonstandard extensions.
ES6
ES6 draft: http://wiki.ecmascript.org/doku.php?id=harmony:const
Better to also stick to the convention of CAPS_UNDERSCORE
for constants.
Gotcha: month
is 0-based,
e.g. 1
means February!
Explicit constructor and getters for local time:
Other constructors:
Create a UTC date object with new Date(Date.UTC(2000, 1, 2, 3, 4, 5, 6))
.
Works because Date.UTC
returns the number of milliseconds in UTC.
toISOString
, ES5,
ISO 8601 http://en.wikipedia.org/wiki/ISO_8601
By default ends in Z
, thus it is the UTC time, not local time!
ES5, thus also present in Node.js.
For greater portability, https://github.com/douglascrockford/JSON-js/blob/master/json2.js is a common option through the CDN: http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js
Run code from string in current environment.
ES6, already implemented in some browsers.
Makes it easier to deal with event success / failure.
Good article: http://www.html5rocks.com/en/tutorials/es6/promises/
Already implemented by many libraries.
Promises/A+ is an open standard that influences ES6. It is followed by the promise implementation of some libraries, but not others, notably jQuery.
In jQuery, `Promise` is a subset of `Deferreds`.
The following implementation exists for Node.js that mimics EC6's exactly: https://github.com/jakearchibald/es6-promise
http://www.ecma-international.org/ecma-262/6.0/#sec-global-object
Encode entire object at once: no built-in: http://stackoverflow.com/questions/1714786/querystring-encoding-of-a-javascript-object
Documented on the HTML5 browsers section: http://www.w3.org/TR/html5/browsers.html#the-window-object
One of the most important objects.
Offers an interface to the browser contents.
May be undefined on Node.js. This can be used to check if we are no Node.js or browser.
`window` is the global object in browser implementations: http://www.ecma-international.org/ecma-262/5.1/#sec-15.1
It is not present in Node.js.
All global objects are attributes of window
In-window modals (popup that disables background).
Practical, but not very customizable, cannot render HTML in it. Whitespace is preserved.
Often replaced by more flexible JavaScript libraries or CSS :target
.
Bootstrap offers:
http://getbootstrap.com/javascript/#modals
The following built-in modals exist:
Show an important message. Only a single continue button exists, so no information can be retrieved from the user.
Get a boolean value from the user. Common for: "are you sure you want to quit?" messages to avoid data loss while editing potentially large textareas.
Get a string value from the user. Very rare because it does not scale well: it is only a matter of time before you need another field. Also makes the site unusable if Js is off. Use HTML forms instead.
Not on IE8.
Inner does not include scrollbars, toolbars, address bar, tabs:
window.innerHeight
= window.innerWidth
= Outer includes everything:
window.outerHeight
= window.outerWidth
= Get how much scroll was done from top left:
scrollby: TODO window.scrollBy(100,100)
Run a function every n milliseconds.
500ms: 0
Callback once after given number of milliseconds.
Not part of ES5, but Node.js also implements an identical interface.
It is asynchronous:
Synchronous sleep: impossible, do a busy wait loop that waits for a setTimeout control variable. http://stackoverflow.com/questions/951021/what-do-i-do-if-i-want-a-javascript-version-of-sleep
Opens up new windows / tabs on the browser.
Popup blockers usually block this.
Good way to annoy users =)
Returns a window object.
TODO: what is the name
parameter?
http://www.w3.org/TR/html5/browsers.html#location
Implements
http://www.w3.org/TR/html5/infrastructure.html#urlutils
which contains many properties like href
and hash
.
urlutils
seems to be defined at:
https://url.spec.whatwg.org/#urlutils
Reload current page page: window.location.reload()
.
Set URL and navigate to it. Old URL gets added to history.
Same as assign
but old URL does not get added to history.
For assignment, same as: window.location.assign('url')
.
http://stackoverflow.com/questions/1034621/get-current-url-with-javascript
document.URL
: readonly from when page was loaded
(not affected by JavaScript operations like replace
)
window.location.href
: updated by JavaScript operations.
Same as: window.location.assign('#fragment')
.
My id is location-hash
.
HTML5
https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history
Do not trigger DOMContentLoaded
.
Still not consistent across browsers. A popular alternative is the History.js library
https://github.com/browserstate/history.js
which provides the History
object and a similar property interface to that of the standard.
Apparently you can only get the last one for security reasons: http://stackoverflow.com/questions/3528324/how-do-you-get-the-previous-url-in-javascript
http://stackoverflow.com/a/3503206/895245
Great to store state while making AJAX or preloaded modifications.
User can still go back to previous URLs because this history is being modified.
May not work on file:///
for security concerns.
Try on localhost
with python -m SimpleHTTPServer
click me for new-url-1! click me for new-url-2!
http://stackoverflow.com/questions/4539253/what-is-console-log
Widely implemented (but not necessarily uniformly).
On Firefox, logged messages appear under Console > Logging
Navigator metadata
Change the window size of the browser.
Chrome and IE WONTFIX, so unlikely to end up in a spec.
http://stackoverflow.com/questions/7452040/cross-browser-resize-browser-window-in-javascript
Move browser window to position on screen. Same status as resizeTo
.
Starting to get a specification at: http://fullscreen.spec.whatwg.org/, but still very early stage. Already has incompatible implementations on major browsers. Most implementations first asks user if he wants to do it the first time.
https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html
http://www.html5rocks.com/en/tutorials/pointerlock/intro/
Locks the pointer into the screen. Allows for similar effect to common first person shooters.
Still in very early stage as of 2014.
HTML5: http://www.w3.org/TR/html5/dom.html#document which extends the DOM specification: http://www.w3.org/TR/dom/#document
This section shall only describe the HTML5 extensions.
Constructor of the window.document
object.
Write after the current script.
Scripts inserted like this will be executed. TODO which order? http://stackoverflow.com/questions/94141/javascripts-document-write-inline-script-execution-order Probably not a good idea to rely on such things.
Last URL before current, if use clicked on a link to come here.
May not always work? http://stackoverflow.com/questions/3528324/how-do-you-get-the-previous-url-in-javascript
document.referrer
= See also: window.history
http://www.w3.org/TR/html5/browsers.html#dom-document-domain
Can always be read, and set with some SOP limitations.
HTMLCollection
of all form elements. TODO: why for forms only?
Interface to interact with both HTML and XML elements from a tree point of view.
All HTML5 elements have a "DOM Interface IDL" section which specifies its available properties.
List of all DOM specs: http://www.w3.org/DOM/DOMTR
Edge spec: http://www.w3.org/TR/dom/
The entire DOM spec is split across multiple modules. Latest REC is DOM level 3.
Informal name for pre W3C standard rules, specially those derived from Netscape behavior.
Some still work widely across browsers, but have been superseded by a W3C standard method,
for instance returning false
from click
vs preventDefault
.
http://www.w3.org/TR/dom/#node
Different from Element
, which is a child class.
http://www.w3.org/TR/dom/#nodelist
Many DOM methods that get multiple nodes like getElementsByClassName
do not return
an Array
but NodeList
or HTMLCollection
objects.
Those are Array-like and support index access, but not all Array operations such as forEach
.
To use arbitrary Array
methods, first convert to an array with
Array.prototype.slice.call(elem.getElementsByClassName('class'))
Apparently some node types have been deprecated: https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType
ELEMENT_NODE
ATTRIBUTE_NODE
TEXT_NODE
CDATA_SECTION_NODE
ENTITY_REFERENCE_NODE
ENTITY_NODE
PROCESSING_INSTRUCTION_NODE
COMMENT_NODE
DOCUMENT_NODE
DOCUMENT_TYPE_NODE
DOCUMENT_FRAGMENT_NODE
NOTATION_NODE
A string representing the nodeType
Only meant for nodes of type 1, AKA elements.
*Don't* do innerHTML += innerHTML + 'something'
unless you are sure it is only a string.
Otherwise, this would destroy events associated to elements in the innerHTML
.
Use insertAdjacentHTML
instead.
TODO are multiple whitespaces preserved? Inconclusive question:
http://stackoverflow.com/questions/213845/javascript-removing-whitespace-when-it-shouldnt
Passing on Firefox 30 and Chromium 34, but maybe unspecified:
Same for getAttribute
.
a b
Find elements inside other elements.
Select elements by CSS selector. Very powerful.
Not supported in IE7.
By Xpath. Working Group Note, not REC. Implementation status: only not in desktop IE 10 as of 2014: https://developer.mozilla.org/en-US/docs/Web/API/document.evaluate#Browser_compatibility Sample usage: http://stackoverflow.com/questions/10596417/is-there-a-way-to-get-element-by-xpath-in-javascript/14284815?noredirect=1#comment38086251_14284815
Same as querySelectorAll()[0]
Not implemented on IE8. Alternatives: http://stackoverflow.com/questions/3808808/how-to-get-element-by-class-in-javascript
IE8 alternatives: use querySelectorAll
or JQuery.
The return can be either NodeList or HTMLCollection
depending on browser versions and standard considered.
In particular, no forEach
Array method.
Good article: https://developer.mozilla.org/en-US/docs/Web/API/Element.getElementsByTagName
Some special cases have shortcuts for them:
Get the current script element:
http://www.w3.org/TR/dom/#element
Inherits Node
.
Check if the element matches a selector.
https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
List of classes of element.
Form element for a given input
element.
http://stackoverflow.com/questions/991367/how-to-get-the-form-parent-of-an-input
http://www.w3.org/TR/html5/dom.html#htmlelement
Extends element.
DOMStringMap
with the data-*
attributes of the element.
Automatically converts keys to camel case.
Like innerHTML
, but also includes the tags. Less support than innerHTML
but increasing.
Test preparation:
children and firstElementChild: only elements, no text:
childNodes and firstChild: include text:
childNodes is of type NodeList. Therefore no forEach.
Insert string before or after tag.
Insert an element before another.
Must work with elements: cannot insert string directly. Consider insertAdjacentHTML
for that.
TODO what happens when element exists already? Copy of events? Probably.
Does not exist, but easily defined with insertBefore
.
http://stackoverflow.com/questions/4793604/how-to-do-insert-after-in-javascript-without-using-a-library
Must get parent first: http://stackoverflow.com/questions/3387427/javascript-remove-element-by-id
setAttribute
creates the attribute if it does not exist.
If the attribute does not exist, return null
.
Get and set CSS attributes.
HTMLElement
is the Base element class.
It is extended by more specific types of element such as HTMLImageElement
.
The derived element types can be constructed either with document.createElement
or specific constructors like Image
.
Both are standard, widely implemented and equivalent. TODO confirm http://stackoverflow.com/questions/6936071/where-are-constructors-such-as-new-image-and-new-option-documented https://developer.mozilla.org/en/docs/Web/API/HTMLImageElement
new Image
vs document.createElement('img')
http://stackoverflow.com/questions/6241716/is-there-a-difference-between-new-image-and-document-createelementimg
Not an element, but can be a child.
Contains the text on the outside of other elements.
Convert string to DOM tree of Elements:
http://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro
innerHTML
trick:
Method of HTMLElement
that gives focus to element.
Not all elements can have focus: http://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus
Get element with focus with activeElement
:
http://stackoverflow.com/questions/497094/how-do-i-find-out-which-dom-element-has-the-focus
Widely supported. TODO standards?
src
attribute: starts loading as soon as it is set.
Set to true
when load has finished.
Set to false
when load starts, e.g. img.src =
.
Application: do something when image finished loading. Must take care not to add the callback after the event happened.
The same is not possible for the error event
since there is no analogous boolean error
indicator.
Get or set the content with the value
property.
The default value can be retrieved with the defaultValue
property:
it's the text that was put inside the textarea
tags in the HTML.
This differs from input
elements,
where the default value is set through the value
property (and can also be retrieved
with this property).
Events that are activated when:
change
: value of input element changed.
Only triggered for input text fields when you lose focus of field
not on keypress. To do that, use input
.
input
: when the value changes, before losing focus.
Property to get or set the disabled state of a form control.
Property that gets or sets checked state of checkbox.
The HTML canvas element was made to be drawn with JavaScript and destroy Flash.
Events are part of the DOM.
Each event is attached to an element.
Events propagate
Like the rest of the DOM, it is a bit messy to find where events are defined.
A good source is Firefox's documentation http://www.w3.org/TR/DOM-Level-3-Events
The major standards are:
Allows to add an unlimited amount of handlers per event.
Better choice than on
attributes like onload
.
Can be used together with on
events. TODO check.
TODO do all events have a on version and an addEventListener
one?
Very good example: http://stackoverflow.com/a/4616720/895245
Prevent event from being listened on further listeners. http://stackoverflow.com/questions/4470417/how-do-i-consume-a-key-event-in-javascript-so-that-it-doesnt-propagate
Only implemented in recent IE. Consider jQuery's preventDefault
and/or stopPropagation
if you care.
document
, window
and body
have different possible events.
TODO understand clearly.
http://stackoverflow.com/questions/12045440/difference-between-document-addeventlistener-and-window-addeventlistener
You cannot attach events to the body
element form scripts in the head,
because the body is not yet part of the DOM!
Prefer to attach events to the document
or window
objects instead.
http://stackoverflow.com/questions/191157/window-onload-vs-body-onload
HTML5 http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end
DOMContentLoaded
vs document.onload
:
http://stackoverflow.com/questions/2414750/difference-between-domcontentloaded-and-load-events
Former does not wait for external resources to load, later does.
Used by jQuery's $(document).ready
method where supported.
Can only be used on body
or elements that load remote sources such as
img
, link
or remote script
tags.
Cannot be used on other elements such as div
.
Both window and document objects have this event:
http://stackoverflow.com/questions/588040/window-onload-vs-document-onload>
but document
's is probably more useful.
On body
and document
, waits for all content to load,
including images.
If load
has already finished when callback is set, it does not get called.
Fortunately it is possible to check if load completed with complete
:
The same is not possible for the error event
since there is no analogous boolean error
indicator.
Something like an image failed to load.
Not fired if event already failed before assigning the listener. TODO: sure?
For 'load', possible to work around via the complete
argument,
but not for error.
Source: http://www.html5rocks.com/en/tutorials/es6/promises/
Catches js exceptions? TODO how is that related to load errors of the 'error' event?
Works on buttons:
Don't take the default action that would be taken on an event, e.g. open link on anchor click. Works for middle click.
On DOM0, if return is false
then the default action, e.g. open link, is not taken.
This still works on most browsers, but the W3C way of doing it is preventDefault
jQuery implements this interface on the callback passed to on
.
Like click but when submitting a form through the submit button. Attached to the form itself.
Programmatically submit a form:
http://www.w3.org/TR/html5/browsers.html#beforeunloadevent
Before the user exits the current page by either of:
Can be cancelled, preventing the exit.
TODO:
alert
does not work inside the handler,
probably because otherwise malicious code could prevent you from ever leaving the page.
Where is this written on HTML5?
returnValue
is not being shown.
It is known that some browsers don't follow the default and use the actual return value of the
callback as message, but Firefox should work no?
Related bug: https://bugzilla.mozilla.org/show_bug.cgi?id=588292
Docs: https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload
preventDefault
work?Click me to leave the page after activating the beforeunload event.
Application: "Are you sure you want to exit?" while editing large textareas. Check if the textarea has been modified since first load, and if yes show the message.
A way of storing small data strings on user's computer hard disk.
View all cookies on Firefox: chrome://browser/content/preferences/cookies.xul
Cookies are accessible through DOM.
Cookies can be set/get only for current domain.
WARNING: some browsers may not keep cookies for local files (file://) so these tests may fail. Current Firefox does keep the cookies.
Each browser stores its own cookies
Cookies can also be set via headers using the Set-Cookie
header key.
Cookies are automatically sent to servers by browsers via the Cookie
header value.
Cookies are sent from servers to CGI scripts via the HTTP_COOKIE
env var.
These are the most reliable methods, there is no need to use js for cookies.
A cookie based technique to maintain user logged in.
TODO: how to avoid getting the session hijacked?
Make server requests without reloading the current page.
W3C WD: http://www.w3.org/TR/XMLHttpRequest/, WHATWG spec: https://xhr.spec.whatwg.org/ widely implemented.
The name is only historical and currently horrible, as this object can:
so neither XML
nor HTTP
in the name make sense anymore,
should be just Request
...
TODO I'm confused about what is the difference between level 1 and level 2. It seems that in the past, there ware two W3C documents, XMLHttpRequest and XHMLHttpRequest2 http://www.w3.org/TR/XMLHttpRequest2/ Now it the level 2 latest version points to the level 1 URL, so I imagine they have been merged, and that the only difference is informal between old and new methods, so: both level 1 and 2 have the same constructor, but level 2 extends level 1 with further capabilities if implemented.
Not a part of ES, thus not available in Node.js. node-XMLHttpRequest is a wrapper for Node.js's stdlib HTTP implementation with interface exactly like this browser object.
jQuery has an almost extension of XHR called jqXHR
:
it contains most, but not all, properties of XHR, plus some extra behavior,
and is used by the jQuery API instead of the plain XHR.
Overview:
TODO: is Content-Length
required?
There is no JSON response, you have to parse the text: http://stackoverflow.com/questions/1973140/parsing-json-from-xmlhttprequest-responsejson
Non-standard like most X-
prefixed headers: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
Can be used to check if the request was made with a form or not. jQuery sends it by default, and frameworks like Django check it by default: https://docs.djangoproject.com/en/1.9/ref/request-response/#django.http.HttpRequest.is_ajax
http://stackoverflow.com/questions/17478731/whats-the-point-of-the-x-requested-with-header
Set basic request info. Does not send the request yet.
Open signature: open(method,url,async)
Post data is set at send
.
Allows full control over the HTTP headers.
Many JS libraries add the following to the header:
Response should be used from a callback function on asynchronous mode.
onreadystatechange
callback is called every time the readyState
property changes.
Its possible values are:
It is typical for the state to go through all of those states.
TODO how does the server inform which state we are currently on?
Field always present: contains the plain response.
Field only present if the response type is specified XML on the HTTP headers.
Actually make the request.
https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
For security reasons, browsers don't let you read HTTP requests to different locations other than the current one by default.
Simple attack examples: http://stackoverflow.com/questions/14667189/simple-example-for-why-same-origin-policy-is-needed
The most common things that this forbids are:
iframe
if it points to another domain
It is however perfectly possible to make cross site requests in HTML:
every external hyper link and image tag makes such GET
request,
and nothing prevents a form from doing a POST
request across domains.
Preventing such requests would make the web unusable: the only thing that is forbidden
is reading that information into JavaScript.
The reason why it is not possible with XHR is that the send
always allows the JavaScript to read the request response.
It is however possible to make requests from JavaScript using other techniques, which do not allow to read the response, and thus do not violate the SOP, in particular:
iframe
and trigger the submit with JavaScript,
http://stackoverflow.com/questions/298745/how-do-i-send-a-cross-domain-post-request-via-javascript
Since it is a security principle like "don't publicly post your password", there are not standards that specify it: only security best practices. http://stackoverflow.com/questions/11423682/cross-domain-form-posting
The same origin policy is the basis for the Synchronizer Token Pattern that prevents CSRF. If it were not used, then the attacker could obtain the token and make the request. https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
Some browsers have an option to allow that to happen for testing purposes.
If an XHR
is blocked on SOP basis, you will get xmlhttp.status == 0
.
On the Firefox inspector, those requests get logged under Console > Security.
Apparently not possible.
does not make much sense, since file://
does not take HTTP requests, and XHR stands for XML HTTP requests.
On Firefox, readyState
reaches 4, but status
is 0.
Jan 2014 W3C REC that enables cross origin XHR requests in a controlled manner. http://www.w3.org/TR/cors/. Part of XHR2. As of Jul 2014, widely implemented on the most recent version of browser families, and plugins exist for most major server systems, including Apache, Nginx, Rack, etc.
Promotional website: http://enable-cors.org/
On the JavaScript side nothing needs to be done on XHR2: if the server supports CORS, you do nothing.
Browser and server implementors several headers to deal with, and one extra request. Simple tutorial including the HTTP interface: http://www.html5rocks.com/en/tutorials/cors/
For a CORS request to be doable, the server must support it, and allow it for the safe pages of course.
Set the response type request header. TODO check.
Local file IO.
W3C spec: http://www.w3.org/TR/file-upload/
Tutorial: http://www.html5rocks.com/en/tutorials/file/dndfiles/
The file API is purposefully restricted in many aspects for security.
For example, you cannot get directory listings: all path selections are done through the browser's built-in popup.
The first thing you have to do is get the files from the user.
There are two main methods:
input type="file"
Naturally, for security reasons you can't just read file paths from the user's computer: he has to explicitly take some action to give you the files.
TODO
The drop
event has a dataTransfers.file
property,
which contains a list of File API File
objects.
Therefore, it is possible to do drag and drop file upload in HTML5!
Worse method than input type=file
, because it is only usable from large screens
and you can have multiple windows open and suitably positioned.
The advantage of drag and drop is that if you already have a file browser open, you don't have to search for the file path again.
Some browsers like Firefox 31 support drag and drop into a regular input type=file
element.
This would be the perfect behaviour, allowing both input methods in one, but unfortunately it seems that it is not standardized:
http://stackoverflow.com/questions/2677565/how-to-drag-and-drop-file-attachment-into-the-browser
Now try dragging the image into the drop area: file
is now undefined.
There is a limited amount of information you can get from files:
name
: the basenamelastModifiedDate
: Date
objectsize
: in bytesThe spec explicitly says that you can't get the full path.
To get the contents of a File
, you must use the FileReader
object on it,
which allows for flexible asynchronous data read in chunks.
Seems not to be possible.
Through drag and drop: http://stackoverflow.com/questions/3590058/does-html5-allow-drag-drop-upload-of-folders-or-a-folder-tree Already implemented in Chrome 21, but not standardized.
Through input type=file
:
http://stackoverflow.com/questions/9518335/select-directory-for-html5-multiple-file-input-in-firefox
http://stackoverflow.com/questions/2897619/using-html5-javascript-to-generate-and-save-a-file
Note that file download can be achieved with an href download="filename"
,
so if the file is generated server side, the cleanest way is to make it available on a URL and use it.
If the file is generated by client on the browser by JavaScript, things are complicated, and probably the best option is to use https://github.com/eligrey/FileSaver.js/
Possible but imperfect HTLM5 solutions include:
download
link with a data:
URL.
Fails in some browsers. Size limitations.
window.saveAs
: not in HTML5FileSaver
API was considered for HTML5 by was droppedPossible as a magic Chrome extension, but not in any standard: http://stackoverflow.com/questions/5416748/drag-a-file-from-browser-to-desktop
Web Real Time Communication.
Developed by Chrome and Mozilla (probably to counter Skype)
W3C WD: http://www.w3.org/TR/webrtc/
HTML5 rocks: http://www.html5rocks.com/en/tutorials/webrtc/basics/
Publicity page demo section: http://www.webrtc.org/demo
https://webrtchacks.com/datachannel-multiplayer-game/
http://www.html5rocks.com/en/tutorials/webrtc/datachannels/
Not easy / possible?
https://github.com/cjb/serverless-webrtc
https://www.quora.com/Is-it-possible-to-make-a-video-chat-application-without-server-with-WebRTC
Master index of SO questions: http://stackoverflow.com/questions/7022383/how-can-i-make-a-browser-to-browser-peer-to-peer-connection
http://stackoverflow.com/questions/21869337/webrtc-without-node-js-or-peer-js
http://stackoverflow.com/questions/2463665/how-create-a-p2p-web-chat-without-any-server
http://www.w3.org/TR/webaudio/
Advanced audio control.
W3C spec.
Tutorial: http://www.html5rocks.com/en/tutorials/webaudio/intro/
https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html
https://www.google.com/intl/en/chrome/demos/speech.html
OpenGL for the browser.
W3C spec.
Wide support on desktop browsers.
https://en.wikipedia.org/wiki/WebCL
JavaScript access to the device's location, like GPS or other methods.
W3C spec: http://www.w3.org/TR/geolocation-API/
HTML5 intro: http://www.html5rocks.com/en/tutorials/geolocation/trip_meter/
The browser may require your permission to give those informations to the JavaScript. Firefox shows: "Would you like to share your location with the file ...?"
Many sources can be used to get the location, including the IP address and a GPS if present.
Accelerometers, gyroscopes and compasses, present specially in mobile devices like phones.
HTML5 intro: http://www.html5rocks.com/en/tutorials/device/orientation/
Last call: http://www.w3.org/TR/notifications/
http://www.sitepoint.com/introduction-web-notifications-api/
TODO get working on Chromium
http://www.w3.org/TR/eventsource/
http://caniuse.com/#feat=eventsource
http://en.wikipedia.org/wiki/Push_technology#HTTP_server_push/p>
http://en.wikipedia.org/wiki/Server-sent_events
http://stackoverflow.com/questions/19995/is-there-some-way-to-push-data-from-web-server-to-browser
http://stackoverflow.com/questions/5195452/websockets-vs-server-sent-events-eventsource
Added with the Web Workers API.
Even callbacks run on a single thread: you don't have to worry about synchronization. Callbacks exist to overcome the huge networking IO delays of web development.
http://stackoverflow.com/questions/39879/why-doesnt-javascript-support-multithreading
Mozilla subset of JavaScript that can be compiled.
Work in progress, only implemented on very recent Firefox.
Subset so small that although Turing complete it is not practical to write directly: it is meant to be transpiled from C++ using LLVM + Emscripten.
Very popular peer reviewed CDN. Source and discussions at: https://github.com/cdnjs/cdnjs
Great way to search for new libraries when you need to do something.
http://stackoverflow.com/questions/16521471/relation-between-commonjs-amd-and-requirejs
AMD and CommonJS are specifications that besides other things describe how to modularize JavaScript code.
RequireJS is the major implementation of AMD. If it a single file regular JavaScript library.
Node.js implements CommonJS.
AMD is a fork of CommonJS.
AMD is more popular in browsers, CommonJS outside.
AMD loads asynchronously, CommonJS synchronously. This is a major divergence point, and explains why AMD is more popular on browsers.
The Browserify utility implements CommonJS for the browser, by pre-compiling multiple files into one before serving.
Simple examples demo: http://www.ringabell.org/en/un-simple-guide-pour-debuter-avec-requirejs/
Large multi file example: https://github.com/requirejs/example-multipage
Possibilities for Js-only tabs:
The only clean solution however is to integrate tabs with the server side,
and decide which tab is open based on the URL path
.