Javascript notes - browser related

From Helpful
Jump to: navigation, search
Related to web development, hosting, and such: (See also the webdev category)
jQuery: Introduction, some basics, examples · plugin notes · unsorted

Server stuff:

Dynamic server stuff:


Global objects

frames

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

A frame should have a name, so that it can be targeted via <a href="foo" target="framename">

Names are handiest if they also work as javascript symbol names (so don't start with a number), and avoid reserved names like 'top' and '_blank'


A frame corresponds to a windows object, which has:

  • window.document
  • window.history, window.location


  • window.name (empty without frames.)
  • window.frames. Without frames, this is empty. With frames, it is an array of references to the window object of each child <frame>/<frameset>, in order.
  • window.length, which should be the same as window.frames.length


  • window.top: a reference to the outermost frame (self-reference without frames and in the top frame)
  • window.parent: a reference to the direct parent window (self-reference without frames and in the top frame)
  • window.self (a self-reference, apparntly for convenience)
  • window.window (a self-reference, apparently purely for convenience)


Navigation:

  • window.parent
  • window.top
  • window.childname (may be confusing to read if the names aren't clearly names of frames)
  • window.frames[0] that is, index-based (may not work if src is missing from frame(verify)), probably testing for .name and/or .location.href
  • window.frames['childname'] (is this standard?(verify))


Nested frames are framesets within framesets, meaning you'll see code like parent.parent, parent.frames[1], top.frames[1], frames[0].frames[1], etc.


TODO:

Web Storage: localStorage and sessionStorage

A Storage object

  • is a key-value stores (both keys and values are strings)
it is an ordered list, though the order is


The current top-level browsing context keeps storage for each origin (the wording roughly means "it's stuck on the window, and separated for frames").

Each has a sessionStorage (which doesn't persist across browser instantiations) and a localStorage (which does). Keep in mind mobile may consider it transient storage and so clean it up.

Mainly there's

  • setItem(key, val)
  • getItem(key)
  • removeItem(key)
  • length
  • clear()


sessionStorage and localStorage contain, for each origin, of storage areas for The only difference is that, while data stored in localStorage has no expiration time, data stored in sessionStorage gets cleared when the browsing session ends—that is, when the browser is closed.


Notes:

  • while the storage is shared per origin, there are no formal definitions about concurrent access
assume there is no locking - that is, nothing transaction-like
  • events are fired on storage change
note that this allows communication between tabs (on the same origin)


See also:


Web Workers

Notes on code in HTML (void(0), "#", etc.)

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

Considerations:

  • how will it style?
do-nothing href suggests you're using a purely for its default styling
  • what will browsers do / how will javascript behave?
e.g. doing stuff client-side stuff and avoiding connections is often half the point
when you return something other than undefined, most will treat it as a link
a lets you open something in a new window/tab, onclick not so much
this
in onclick, it refers to the DOM element (verify)
in href, it refers to the window object (verify)
  • what will spiders do?
most will only follow URLs


solution ingredients

not using <a>

You can get a span to look much like a link with something like:

span.linklike { cursor:pointer; text-decoration:underline; }
span.linklike:hover { text-decoration:none; }

The argument is that <a> gives you behaviour and looks together. If you then do your best to negate all behaviour, it's simpler to just apply the styling to something more neutral - and put code in its onclick.


It breaks search engine indexability.

href=javascript:void(0)

void

  • evaluates to undefined
  • requires an expression, so when you use a href, you can use it to
    • have a do-nothing href (
      javascript:void(0)
      ,
      javascript:void 0
      , also
      javascript:;
      ), where 0 is just a short ignorable value
    • wrap inline code (see next section)
  • can only contain expressions, not assignments and such (verify)
You can work around this by calling a previously defined function, or defining and immediately calling an anonymous function (verbose, but works and is valid javascript):
href=javascript:void(code)

One way of adding javascript to a link is to add it to its href attribute with a 'execute the code when you click the link' intent. Technically a convention, but an ubiquitous one.

Upsides:

  • Simple
  • valid (X)HTML in and of itself

Downsides:

  • middle-click won't load link in new tab (annoying to users that like to have many tabs open)
  • Is technically a non-standard way of adding handlers to (X)HTML. Most browsers support it, though
  • No graceful degradation - no javascript means no link at all - spiders won't understand it

To worry about:

  • if the code (or rather, its constituent?) returns a string, object or such, the browser will assume that was an URL and will navigate to it. Workaround: using void() or similar
href=#

Using a hash (as in #) in href will

  • not reload the page
  • scroll (skip, really) a page to
    • ...a named anchor, defined like <a name="helpsection">) if it exists
    • ...the top of the page if it does not

Upside:

  • doesn't trigger a page load
  • will work in any browser
  • doesn't do anything different when javascript is disabled

Downside:

  • In most cases, will move the page


There is a semi-workaround that makes this a simple option to have onclick in javascript browsers, and degrade to the href in those without.

Combinations

<a>, with do-nothing href, and code in onclick

...and, if you use a href, some style of do-nothing in there, e.g.

<a href="javascript:void(0)" onclick="code" >
<a href="javascript:;" onclick="code" >
<a href="#" onclick="code" >

Upside:

  • Simple

Downside:

  • no fallback for cases where javascript is disabled
  • # will often trigger a page move (not an issue in SPAs that also handle all of the layout)

Further notes:

  • It is neater, in both HTML elegance and in browser compatibility terms, to register the onclick handler via code instead.
<a> without href, code in onclick

You can omit the href attribute. DTDs (HTML4, XHTML) list it as #IMPLIED, meaning omission is technically valid (recall that anchors are <a> tags with only a name)

Be aware of varying browser behaviour, of link semantics interaction with <base>, and note that some (stupid) scripting may assume href's presence.

Note that the use of a gives you nothing. See the "consider a span" argument above.

On gracefully degrading

Why/Whether

Two basic reasons why: Spider indexability, and support for more basic browsers.


First decide whether you want to.

Most SPAs depend on scripting anyway, and can easily choose to demand a recent browser. They may have no fallback at all, or have a simplified non-interactive fallback.

Neither needs per-link fallback considerations.


Script interactions are invisible to spiders, but fully fleshed interfaces, if they expose content, often have a more specific way to expose it.

This is more about pages that are that exposure to search engines, and have non-reloading interactions on top.


How

If you have good reason to gracefully degrade scripting to a link, consider progressive enhancement rather than graceful degradation

  • e.g. regular links with URL in href, and scripting alters that to XHR instead
(could include adding mouseover/out handlers that set window.status, so that the status bar still displays the link even if you set href to # or void)
  • URL in href, onclick blocks it via preventDefault() / return false -- except historically that's always been non-standard fiddling. Some libraries make it simpler, but you still need a bit of reading.

Note that it's hard to e.g. get middle mouse click to act exactly like it would with plain links



Interesting DOM node...

Variables/constants

Functions

Events

On events

Common quirks

In practice it pays to use one of the javascript libraries, since they evolve to be more cross-browser.


If you don't, then some of the quirkiness you may want to know about:

  • Browsers may have their own events. Particularly IE has a bucketload of IE-only onsomethings (e.g. for dragging). Avoid them if you want portable code.
  • Even the events common to all browsers may have somewhat different semantics between browsers.
For example, onchange behaviour varies a little, probably due of vague wording in the standard.
  • The structural difference between IE's model and the W3 one
see e.g. http://www.quirksmode.org/blog/archives/2005/08/addevent_consid.html
IE's apparently only captures, and doesn't bubble (capturing and bubbling refers to the time in propagation an event is actually handled) There may or may not be a way around this(verify).


Each event handler will have an event object handed to it as a parameter. It has some potentially useful members and functions; see cheatsheets for details.

However, IE does not hand along events in event handers. They instead are in the global window.event (perfectly fine since JavaScript isn't threaded).


See also:

Common events

Also read quirksmode on the matter.

Mouse

onmouseover	mouse enters element's area 	
onmouseout	mouse leaves area
onmousemove	Moves the mouse pointer within an element.
onmousedown	mouse button is pushed down
onmouseup	mouse button is released
onclick         push-release both in the same element
ondblclick	double-click within system doubleclick time

Notes:

  • If the element is near the edge, the element may stay in focus even though the window has lost focus; the OS' window focus the document elements' focus are diffent realms. This applies to mouseover and focus/blur.
  • onmousemove is triggered every pixel of movement; don't put heavy work in this.
    • There are four different pairs of x/y attributes in the event, but most/all are useless.
  • you can get the relevant button from which and button.
    • the values are different between browsers
    • Not all browsers and OSes support this on onclick, which may only fire for left clicks(verify)
  • the non-standard ondblclick also seems implies absence of two onclick events? (verify)
  • mouse reaction areas seem to correlates with the CSS background styling. If something is its default transparent, it may not react at all. Give it a color to make sure it's not quicky about this. IE's logic seems quickier; I have yet to figure out the details.


Keyboard

onkeypress	key is pressed AND released. 
onkeydown	key is pressed
onkeyup         key is released

Notes:

  • Note that this, mixed with OS messaging, may make it technically possible to e.g. catch a keydown but not a keyup for the same key.
  • onkeydown and/or onkeypress may or may not fire repeatedly based on the browser and OS.
  • The pressed key will be in e.which in compliant browsers, and in window.event.keyCode in IE. It seems some browsers also added keyCode.


(TODO: see [1], and see how many are IE-only)


Others

onfocus        input element gains focus
onblur         focus is lost. Seems to have priority over e.g. a click
               that probably caused this.


Event propagation

  • Events propagate two ways (basically a treewalk), first by being captured down the tree (root first, on its way to the target), then bubbling up it from the target to the root element. Note that W3's terms argue more from the perspecive of the node itself than from an ongoing process of treewalking.
  • If something captures, it will be called before getting to an object.
  • There are default actions for some events to allow the browser to do sensical things like selecting text. These are independent of your own functions and always fire unless you call an event's
    preventDefault()
    before it bubbles back up to them.
  • return false
    is mentioned vaguely as both a further-bubble preventer and a default-preventer - it seems to do both by canceling all further event handling for the event (verify) (used e.g. to cancel form submit by value-verifying function). It is apparently a nasty way of controlling behaviour, with browser-dependent behaviour, so avoid it when you can:
  • Events can be cancelable (like clicks) some are not (like losing focus) which means you can or can't cancel all further propagation for and from within some event.
    • 'window.event.returnValue=null' seems to be the IE equivalent of either 'return false' or precentDefault() (verify)
  • See sections below about controlling propagation


Controlling propagation Events happen to things in trees, like explained. Sometimes it is convenient to allow events to do potentially do something at all nodes it passes, sometimes you want to prevent that.

You can usually argue this per action type. When you want things to follow your mouse, you want mousemoves to not be blocked when another element happens to capture it, whereas when you click a button, you probably don't want something under it to also react to the click.

When you want to prevent caputing and/or bubbling, you need to do so explicitly. See e.g. this.


on default actions, return false

Attaching event handlers

Background

Common methods:

  • The DOM standard says to use addEventListener (see e.g. [2]), but IE doesn't support this (it defines its own method instead)
  • Setting onsomething="code" inside HTML is not a DOM standard, but which you can assume all widely used browsers will support(verify). Note they usually put these events in the bubbling phase.
  • setting domreference.onsomething=functionref; from a script are also not standard, but also generally supported. Note: You should use all-lowercap names for most-browser compatibility.


There is more ways, but the most compatible way (that is also short; in a library you could also solve problems like IE's rule of one handler) seems to be the DOMelement.onsomething = function way, or assign a function reference indirectly. You'll probably want to use closures to pass in arguments.


Note, however, that assigning a function this way will replace any if it were previously set. This combines with IE's problem of allowing only one event per event type per DOM element whatever way you choose.

You can work around by e.g. making actual handler one that keeps a list of functions to call, and does so. It's easier to use some library to do this for you.

keycodes

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)


There is some inconsistency between browser keycodes (and where exactly they are reported) for historical reasons. As such, if you use a javascript library, see if it normalizes that muck and makes your life easier. You want that.

See also:

Unsorted

Bookmarks/favorites

While you can't change the bookmarks from scripting (which is a good thing, securitywise), you can prompt to add a bookmark. There is no standard, each browser has its own way.

function addToBookmarks(url,title) {
  if (window.external && window.external.AddFavorite) 
    window.external.AddFavorite(url,title);   // IE4 and later
  else if (window.sidebar && window.sidebar.addPanel)
    window.sidebar.addPanel(title,url,'');    //Gecko/firefox
}
 
//use e.g. like:
addToBookmarks(window.document.location, window.document.title);

Of course, you can check for IE and gecko another way.

See also: