Elisabeth
Elisabeth

Reputation: 3032

What objects can trigger the key press event in the DOM?

I've been experimenting and it seems like only form elements and the window object can trigger the keypress event.

I checked MDN documentation, and also the spec, but couldn't find anywhere that listed valid objects that can trigger this event. In the code sample below, if I comment out the line beginning "window" then I get no console message, implying that the div element is not triggering the key press event, however, if I leave in the line to define a handler for the key press event on the window, then I do see the console messages.

Can anyone point me to something (or confirm/list) the valid objects that can trigger the keypress event? Thanks!

window.onload = function() {
    var div = document.getElementById("div");
    div.onclick = clickMeHandler;
    div.onkeypress = clickMeHandler;
    window.onkeypress = clickMeHandler;
};
function clickMeHandler(e) {
    console.log("click me handler, type: ", e.type);
    console.log("click me handler, target: ", e.target);
}

Upvotes: 2

Views: 2471

Answers (3)

zamnuts
zamnuts

Reputation: 9592

Edit: Added HTML5 note after explanation.

The following tags have any on* event (i.e. onkeypress) associated with them (listed in alphabetical order):

a, abbr, acronym, address, area, b, bdo, big, blockquote, body, button, caption, cite, code, col, colgroup, dd, del, dfn, div, dl, dt, em, fieldset, form, h1, h2, h3, h4, h5, h6, hr, i, img, input, ins, kbd, label, legend, li, link, map, noscript, object, ol, optgroup, option, p, pre, q, samp, select, small, span, strong, sub, sup, table, tbody, td, textarea, tfoot, th, thead, tr, tt, ul, var

The following tags do not have any on* events:

base, br, head, html, meta, param, script, style, title

According to XHTML 1.0 Strict DTD. The element's attribute list contain either attrs or events entities, e.g. (second line):

<!ATTLIST img
  %attrs;
  src         %URI;          #REQUIRED
  alt         %Text;         #REQUIRED
  longdesc    %URI;          #IMPLIED
  height      %Length;       #IMPLIED
  width       %Length;       #IMPLIED
  usemap      %URI;          #IMPLIED
  ismap       (ismap)        #IMPLIED
  >

It is broken down as follows... first your onkeypress event is defined in the entity %events:

<!ENTITY % events
 "onclick     %Script;       #IMPLIED
  ondblclick  %Script;       #IMPLIED
  onmousedown %Script;       #IMPLIED
  onmouseup   %Script;       #IMPLIED
  onmouseover %Script;       #IMPLIED
  onmousemove %Script;       #IMPLIED
  onmouseout  %Script;       #IMPLIED
  onkeypress  %Script;       #IMPLIED
  onkeydown   %Script;       #IMPLIED
  onkeyup     %Script;       #IMPLIED"
  >

Which is then aliased in the entity %attrs:

<!ENTITY % attrs "%coreattrs; %i18n; %events;">

These two entities are not referenced anywhere else in the DTD. So then search for any ATTLISTs containing at least one of those entities.


On the other hand, HTML5 is not SGML-based, it cannot have a DTD; see Where is the HTML5 Document Type Definition?. Therefore, the analysis I have preformed with regard to XHTML 1.0 does not apply to HTML5.

According to the HTML5 spec, any and all elements can have events applied to them:

[E]vent handlers (and their corresponding event handler event types) ... must be supported by all HTML elements, as both event handler content attributes and event handler IDL attributes; and ... must be supported by all Document and Window objects, as event handler IDL attributes.

Within the event table includes your onkeypress event handler with event type keypress.

In theory any event will work on any element node (node type ELEMENT_NODE 1), but I wouldn't count on it in all browsers. I'd say it would be safer to stick with the XHTML implementation.


I used the following PHP script to parse and compile the list:

<?php

$dtd = '/path/to/local/copy/of/xhtml1-strict.dtd';
$file = file_get_contents($dtd);

$match = '/(<!ATTLIST[^>]+%(attrs|events);[^>]*>)/i';
preg_match_all($match,$file,$matches);

$tags = array();
if ( isset($matches[0]) ) {
    foreach ( $matches[0] as $attlist ) {
        preg_match('/ATTLIST\s([^\s]+)\s/',$attlist,$tag);
        if ( isset($tag[1]) && $tag[1] ) {
            $tags[] = $tag[1];
        }
    }
}

sort($tags);

$element = '/<!ELEMENT\s([^\s]+)/i';
preg_match_all($element,$file,$elements);
$elements = $elements[1];
sort($elements);

echo 'Has Events: '.implode(', ',$tags);
echo "\n\n";
echo 'Missing Events: '.implode(', ',array_diff($elements,$tags));

?>

Upvotes: 2

Yuriy Galanter
Yuriy Galanter

Reputation: 39777

Haven't gotten the full list of elements keypress applies to, but I believe you're correct - only controls were keypress makes sense - have it. Taking your example - a DIV can have keypress event but only when you can actually type something into it, namely when it has attribute set contenteditable="true"

Demo: http://jsfiddle.net/qny4A/

UPDATE

Actually I stand corrected. I beleive pretty much any element can generate keypress event as long as it can receive focus, which can be achived via "tabindex" attribute

Here is a demo of a SPAN that generates the event when it's in focus: http://jsfiddle.net/qny4A/1/

Upvotes: 3

ryanlutgen
ryanlutgen

Reputation: 3051

Assuming you are talking about pure JS, and not C# or VB events:

"The onkeypress attribute can be used within ALL HTML elements, EXCEPT:

<base>, <bdo>, <br>, <head>, <html>, <iframe>, <meta>, <param>, <script>, <style>, and <title>.

Source: http://www.w3schools.com/jsref/event_onkeypress.asp

Upvotes: 1

Related Questions