Reputation: 3032
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
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
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
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