[whatwg] hashchange only dispatched in history traversal

Garrett Smith dhtmlkitchen at gmail.com
Tue Sep 9 12:48:10 PDT 2008

On Thu, Aug 21, 2008 at 4:09 PM, Ian Hickson <ian at hixie.ch> wrote:
> On Thu, 21 Aug 2008, Garrett Smith wrote:
>> HTML 5 expands "hashchange" to any element. Any element, such as div
>> or pre? How can you know if an element supports "hashchange" or not?

I still wonder about this.

>> "hashchange" seems closely related to the Location interface, so it
>> would seem to make sense to have "hashchange" implemented for objects
>> that implement Location.
>> Has this been considered?
> Yes, but the benefit of being able to do <body onhashchange=""> outweighs
> the logicalness of dispatching events to the Location object.

I still wonder what the benefit is.

>> >> I'm not sure what that has to do with the body element.
>> >
>> > Nothing especially, except that that is where the event is fired, so
>> > that you can do <body onhashchange="...">.

and what if you have:

<body onhashchange="alert(document.body.ohashchange);">

Expected result: ?

Should this elert "undefined"?

What is the handler's scope? What is the context?

I see:
| The function's this parameter must be the Element  object
representing the element.


But that isn't what happens when a DOM 0 Event clobbers the body tag.

The wording should be changed to: "The function's context" or "The
function's thisArg".

>>  "fires at the body element"  sounds as if the event is firing itself,
>> at the body. Instead, say the EventTarget fires the event. For example:
>> "The window fires the hashchange event."
> I disagree with your interpretation of the terminology, but that's not
> just editorial so it's not a big deal.

I believe the problem may be more than editorial.

>> Body event handler attributes cascading to window is unclear and creates
>> ambiguity as to what the event is being attached to.
>> <body onmousedown="alert(this)">
>> alerts "window" in Firefox 3. The mousedown event fires anywhere, not
>> just on the body. This creates ambiguity. So it is a practice that
>> should be avoided in attempt to be cross browser. Has this problem been
>> considered?
> Yeah, this is an open issue. I'm hoping that the DOM Events spec handles
> it.

Handles what?

A BODY event handler can be added as a content attribute to the BODY
tag. It should generally have the scope chain as
body->document->window, with the context as body (this === body);

The following example shows that this is true:-

<head><title>onclick content handler test</title></head>
<script type="text/javascript">var title=1</script>
<style type="text/css">*{white-space: pre;font-family:monospace}</style>
<body title="body"
 '\ncurrentTarget is body: '+(event.currentTarget === document.body)
 + '\ncontext is body: ' + (this === document.body)
 + '\nscope is window: ' + (title === 'body');"
 ><p>(click) All should be true:</p></body>

currentTarget is body: true
context is body: true
scope is window: true

Except in Firefox. In Firefox, the scope and context are window:
currentTarget is body: false
context is body: false
scope is window: false

We can also observe that clicking anywhere in the window will trigger
the event. Firefox handles click events for window and the equivalent
event handler content attribute is assigned in the BODY tag.

This may seem strange, but it is the way that DOM 0 events for window
work. Window has no tag. Content handler attributes for window are
place in the BODY tag. This is true for all DOM 0 events, such as
onload, onunload, onfocus, onblur.

For example, onload:-

<head><title>onload content handler test</title></head>
<script type="text/javascript">var title=1</script>
<style type="text/css">*{white-space: pre;font-family:monospace}</style>
<body title="body"
  onload="var target = event.target || event.srcElement;
 document.body.innerHTML+='\ntarget is document: '+(target === document)
 + '\ncontext is window: ' + (this === window)
 + '\nscope is window: ' + (title === 1);"
 ><p>All should be true:</p></body>

We can already observe some ambiguity. It may seem odd to some that
Firefox has mouseevents for window, but it does. Firefox has also has
keyEvent,s mousewheel events. What happens when the event is focus?
Any element with tabIndex can now have focus, and window can have a
different kind of focus. What happens when BODY has an onfocus content
handler? What happens when BODY has an event handler content attribute
with the same name as a window event?

This example shows that we can add an onfocus content handler to a <p>
tag, and an onfocus content handler to the body, but that the window's
onfocus "wins" the event handler assignment in Firefox, Opera, and

<head><title>onfocus content handler test</title></head>
<script type="text/javascript">var title=1</script>
<style type="text/css">*{white-space: pre;font-family:monospace}</style>
<body title="body" tabindex="1" style="position:absolute"
  '\ncontext is window: ' + (this === window)
 + '\nscope is window: ' + (title === 1);"
 ><p onfocus="alert('onfocus for <p>. this: ' + this)" tabindex="2"
 >All should be <strong>false</strong>:</p></body>

By clicking the <p> element, we can observe that the onfocus handler
is called in three browsers. By raising and lowering the window, we
can observe that window.onfocus is called in three browsers.
document.body.onfocus is null/undefined. window.onfocus got the
content handler. Window "won".

When DOM 0 events clobber the HTML body content handler attributes,
there is ambiguity. Usually, the window will win.

Ambiguous outcomes from clobbering can be avoided by authors by not
using content handlers for body.

Window events that clobber body event handler content attributes is a
messy, complicated problem. There is onscroll, onmousewheel, onblur,
all key events, and all mouse events.

Specifications should not create ambiguous outcomes. Specifications
should be mention the problem and avoid it.

HTML 5 defines onload for all elements. The event won't be called on a
body element's load (body doesn't fire load events), but a body event
handler content attribute will become the body of a window event
handler function.

Event clobbering precludes the possibility from the BODY element
having an onload event handler content attribute. HTML 5 says all
elements have an onload handler.

Adding hashchange as a body event handler clobbers body with a window event.

This precludes that possibility of the BODY element having a
hashchange event because it would be ambiguous as to what
document.body.onhashchange means.

>> 1) add a note about bubbling. hashchange events bubble
> Per the spec, it doesnt.

Did this change?

I cannot find hashchange in whatwg html 5 draft, only here:

| Must be invoked whenever a hashchange event is targeted
| at or bubbles through the element.

>> 2) replace the "fires at the body element" with "the EventTarget fires
>> the event"
> I disagree with this interpretation of the terminology.

For body content event handlers, it is important to make clear what are:
1) target (for clobbered window events)
2) context (what is the this value?)
3) scope chain.

It would be a good idea to define how clobbering works, and what is
the expected outcome shoud be. Should window win?

("win" = The winner fires event that calls the callback, using the
winner's context. Callback function has winner's scope and the
function body has the event handler content .)

What can be expected of implementations that use non-standard
extensions like mouseevents, keyevents for window? Should window
always win?


> --
> Ian Hickson               U+1047E                )\._.,--....,'``.    fL
> http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
> Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

Compounding complications makes things impossible.

More information about the whatwg mailing list