Monday, October 2, 2006

How to detect Enter key event

At the end of the page add this javascript:

function enterPressed(evn) {
if (window.event && window.event.keyCode == 13) {
alert("IE: Enter is pressed");
} else if (evn && evn.keyCode == 13) {
alert("Netscape: Enter is pressed");
document.onkeypress = enterPressed;


Here is modified cross browser version of the code above:

function doWhenEnterPressed(evn) {
var enterWasPressed = false;
if (window.event && window.event.keyCode == 13) { // IE
enterWasPressed = true;
} else if (evn && (evn.keyCode == 13 || evn.which == 13 )) { // FF
enterWasPressed = true;
if (enterWasPressed) {
alert('Enter pressed'); // your action code

document.onkeydown = function(evn) {

Monday, September 4, 2006

Get Element By Tag and Name attribute (getElementsByName sort of)

Cross browser function to get element(s) by "name" attribute.

/** getElementsByTagAndName: to avoid missing getElementsByName in IE */
function getElementsByTagAndName(tag, name) {
    var elem = document.getElementsByTagName(tag);
    var arr = new Array();
    for(i = 0, iarr = 0; i < elem.length; i++) {
        att = elem[i].getAttribute("name");
        if(att == name) {
            arr[iarr] = elem[i];
    return arr;

Saturday, August 5, 2006

Various heights in html document

Just keep in mind how you can use and control height of different DOM elements. I consider:

offsetTop, offsetLeft

Take a look at simple self-explanatory demo and
more comprehensive event and height demo.

Tuesday, August 1, 2006

Drag-and-drop sortable and animated accordion menu

This is the illustration of sortable lists by drag and drop in combination with expandable/collapsible animated accordion.

Animation, some event handling and some object access are based on Yahoo! UI Library.
Accordion menu implementation idea was taken from here.
Core drag and drop function is dom-drag.js. About it you can read here. It's been used as is.
I also used some ideas from here. This page uses dom-drag.js as well.

Here is my demo of the result I've got.

It features:

  • Grip for drag-and-drop.

  • Save/retrieve state (expanded or collapsed) and order of bars in cookies.

  • MS Internet Explorer and Mozilla Firefox similar behavior.

  • Customizable: allowMultipleExpand, expandAllOnload.

  • Pure javascript implementation.

If I'm not get lazy I'll publish the documentation and API.

Monday, July 10, 2006

Getting text node recursively

This code extracts text (nodeValue) of first text node presented in DOM tree.
It works with complex structure of DOM trees, but somehow it appeared to be a quite complicated code. Can anyone improve it? :

/** Return text node if exists in hierarchy */
function findChildTextNode(startNode) {
   if (startNode.nodeType == 3) return startNode;
    var childList = startNode.childNodes;
    for (var i=0; i < childList.length; i++) {
        return findChildTextNode(childList[i]);
   return null;
/** Returns text node recursively */
function findTextNode(inerestNode) {
    var foundTextNode = null;
    var tags = inerestNode.getElementsByTagName("*");
    for (var i = 0; i < tags.length; i++) {
        foundTextNode = findChildTextNode(tags[i]);
        if (foundTextNode) return foundTextNode;
    return null;

var interestTextNode = findTextNode(interestNode);

Wednesday, June 7, 2006

Javascript RegExp: replace parameter value in query string

Task: change the value of parameter 'tid' in given querystring.
Original querystring:

var linkParam = 'tid=8&id=11008&location=news';

New 'tid' parameter value:

var tagId = 12;

You can do it using 'replace' function. Final code to replace:

var tagIdReg = /[tid=](\d+)[&]/i;
document.write(linkParam.replace(tagIdReg, '='+tagId+'&'));

But if you need just extract 'tid' value use 'exec':

var tagIdReg = /[tid=](\d+)[&]/i;
var regResult = tagIdReg.exec(linkParam);

Friday, June 2, 2006

Functional desktop background

While ago I created this extremely useful :), yes, that's right, for probably every web developer, the Windows desktop backgroud. It should fit most of the today's desktop screens resolutions. Dimensions of background is: 1680x1200. For more compatibility the format of the file is windows bitmap. Download it, unzip and copy to your C:\windows folder. It will become available on "Desktop" tab of "Display Properties" window.

It looks like this (but bigger, yeah):

Tuesday, May 30, 2006

Delete all children nodes

To remove all children nodes (from childNodes list) use:

while(listNode.firstChild) { // delete all nodes

Of course innerHTML will work too:

listNode.innerHTML = '';

Saturday, May 27, 2006

Traverse/walk DOM tree recursively

Task definition: You have a DOM tree (startNode which can be the whole document), and need to find first specific tag in this tree.

Here is the recursion function to do this:
function findNodeByTag(startNode, tagName) {
    if (startNode.nodeName.toLowerCase() == tagName.toLowerCase()) return startNode;
    var childList = startNode.childNodes;
    for (var i=0; i<childList.length; i++) {
        return findNodeByTag(childList[i], tagName);
    return null;

And you call it:
findNodeByTag(myDOMobj, "img");

Add, delete and manipulate DOM nodes

Here are examples taken from some of my code just to memorize common use node functions. I hope they are self-explanatory.

// Clone DOM node
var movingUrl = urlLineSPAN.cloneNode(true);
// Get Parent node
var urlList = urlLineSPAN.parentNode;
// Delete DOM Node
// Add DOM node
// or
urlAreaObj.insertBefore(newNode, existingNode);

Swap DOM nodes

To swap DOM nodes you can use this example:

var oldNodeAtPosition = document.getElementById(existingNode);
var newNodeAtPosition = document.getElementById(retrievedNode);
// swap DOM nodes
// API: replaceChild(child1,child2) -- replace node child2 by node child1
oldNodeAtPosition.parentNode.replaceChild(newNodeAtPosition.cloneNode(true), oldNodeAtPosition);
newNodeAtPosition.parentNode.replaceChild(oldNodeAtPosition.cloneNode(true), newNodeAtPosition);

Monday, May 15, 2006

DHTML: Dynamic Navigation through DOM element with scrollTop

I had a task to implement vertical navigation by the long list of items which does not fit the browser window. It has to be hidden if list of items shorter than height of the window. Note also I has to use frames.

Okey, let's start. First, I disabled standard scrollbars within the window:

html,body { overflow: hidden; }
body { position: absolute; top: 0; left: 0; }

Then I disabled scrollbars in DIV area which should be navigated:

#taglist{ width:100%; overflow:hidden; }

Then I created DIV area with up/down buttons bound to right lower corner of the window. I wrote in CSS file:

.sbnav { position: absolute; bottom: 5px; right: 5px; text-align:right; background-color: #fbffba; padding:3px; }
.sbnav-up { margin-bottom: 6px; }
.sbnav-down { margin-top: 6px; }

and in HTML (the simpliest piece):

<div id="taglist"></div>

Couple more tricks in this work:
1. Shift displayed area. For this purpose I have to control scrollTop DOM property. I wrote two functions for that: sbNavUp() and sbNavDown()
2. I found very useful: setInterval and clearInterval on mouse events (onmousedown and onmouseup).

Below is Javascript implementation. You will also need graphics for up and down buttons, and some HTML to define DOM object to be navigated, and DOM object which contain navigation.
NOTE that I had to put 110 and 115 values because area which should be navigatable is lower (shorter) than whole size of frame (window).

So, HTML for navigation arrows looks like this:

<div class="sbnav" id="sbnav">
<a href="#" id="sbnav_up" title="Up"><img src="/static/images/nav_up.gif" alt="Up" height="7" slass="sbnav-up" width="14" /></a><br />
<a href="#" id="sbnav_down" title="Down"><img src="/static/images/nav_down.gif" alt="Down" height="7" class="sbnav-down" width="14" /></a> </div>

Javascript calls on HTML page:
window.onload = sbNavControl;
window.onresize = sbNavControl;

Thus, I show or hide buttons on window resize.

Javascript implementation:

getWindowHeight function is available under the link.

/** Sidebar navigation */

var navStep = 2; // in pixels
var navSpeed = 10; // in milliseconds

/** Navigate list of interests up */

function sbNavUp() {
try {
var taglistObj = top.frames['sidebarcontent'].document.getElementById('taglist');
var offset = taglistObj.scrollTop;
if (offset > navStep) taglistObj.scrollTop -= navStep;
else if (offset <= navStep && offset > 0) taglistObj.scrollTop = 0;
} catch(e) {jsErr(e)}

/** Navigate list of interests down */

function sbNavDown() {
try {
var taglistObj = top.frames['sidebarcontent'].document.getElementById('taglist');
var offset = taglistObj.scrollTop;
if (offset+navStep < taglistObj.scrollHeight) taglistObj.scrollTop += navStep;
else if (offset+navStep >= taglistObj.scrollHeight && offset < taglistObj.scrollHeight) taglistObj.scrollTop = taglistObj.scrollHeight;
} catch(e) {jsErr(e)}

/** Show/hide navigational buttons */

function sbNavControl() {
try {
var taglistObj = top.frames['sidebarcontent'].document.getElementById('taglist');
var sbnabObj = top.frames['sidebarcontent'].document.getElementById("sbnav");
if (!taglistObj || !sbnabObj) return;
// reset height to default = '';
// display/hide nav buttons
var taglistHeight = taglistObj.offsetHeight;
if (taglistHeight > getWindowHeight()-110) = '';
else = 'none';
// set height in order to make navigation work = (getWindowHeight()-115) + "px";

// onMouseDown and onMouseUp events
var btnUp = top.frames['sidebarcontent'].document.getElementById("sbnav_up");
var btnDown = top.frames['sidebarcontent'].document.getElementById("sbnav_down");
if (!btnUp || !btnDown) return;
var sbNavUpInterval = ''; var sbNavDownInterval = '';
function sbNavUpStart() { sbNavUpInterval = self.setInterval("sbNavUp()", navSpeed); }
function sbNavDownStart() { sbNavDownInterval = self.setInterval("sbNavDown()", navSpeed); }
function sbNavUpStop() { self.clearInterval(sbNavUpInterval); }
function sbNavDownStop() { self.clearInterval(sbNavDownInterval); }
btnUp.onmousedown = sbNavUpStart;
btnUp.onmouseup = sbNavUpStop;
btnDown.onmousedown = sbNavDownStart;
btnDown.onmouseup = sbNavDownStop;
} catch(e) {}

DHTML: Add event dispatcher to HTML form field

Sure you can use this function with any DOM object. Not only a form field.

/* event dispatcher */
function installAC(frm, fld) {
a = document.forms[frm].elements[fld];
if (a.addEventListener) {a.addEventListener("keyup", PerformActions, false)} // firefox
else if (a.attachEvent) {a.attachEvent("onpropertychange", PerformActions)} // ie

/* actions to do */
function PerformActions(h) {
// your code here

DHTML: Get Height of window and DOM element

offsetHeight property of DOM element will let you get its height.

Following javascript function will return the height of the window:

/* Get window height. To get DOM element height use offsetHeight. */
function getWindowHeight() {
var windowHeight = 0;
if (typeof(window.innerHeight) == 'number') {
windowHeight = window.innerHeight;
} else {
if (document.documentElement && document.documentElement.clientHeight) {
windowHeight = document.documentElement.clientHeight;
} else {
if (document.body && document.body.clientHeight) {
windowHeight = document.body.clientHeight;
return windowHeight;