Fri 05 Sep 2008
10:13AM
compton

Javascript Snippets

Preventing Users Entering Certain Characters

  <input id="checkinput" onkeypress="return checkValid(this, event);">  
<script> function checkValid(inputfield, e) { if (!e) var e = window.event var keycode; if (e.keyCode) { keycode = e.keyCode; } else { if (e.which) { keycode = e.which; } } if ((keycode < 32 || keycode > 126) && keycode != 8 && keycode != 9 && keycode != 8 && keycode != 13 && keycode != 27) { alert('Sorry, "' + String.fromCharCode(keycode) + '" is an illegal character'); return false; } else { return true; } } </script>

Finding an Element's X and Y Position

The following JavaScript function will return an array containing the X position of an element's left edge, the Y position of the element's top edge (these two are the element's top left corner), the element's right edge's X value and its bottom edge's Y value (and these two are the element's bottom right corner).
<script> function getCoords(element) { var curleft = curtop = 0; var originalObj = element;   if (element.offsetParent) { do { curleft += element.offsetLeft; curtop += element.offsetTop; } while (element = element.offsetParent); }   return [curleft, curtop, curleft + originalObj.offsetWidth, curtop + originalObj.offsetHeight]; } </script>  
To demonstrate it, the following mouse handler has been attached to the page. Click on any item to see a pop-up window with the clicked-on element's co-ordinates.
<script> document.onmouseup = function(e) { if (e.target) clickedItem = e.target; else if (e.srcElement) clickedItem = e.srcElement; var loc = getCoords(clickedItem); alert(clickedItem.id + ' top left: ' + loc[0] + ',' + loc[1] + '\nbottom right: ' + loc[2] + ',' + loc[3]); }; </script>  
Thanks to quirksmode for the basics of the above getCoords() function.

Preloading Images

Many web sites load images dynamically in response to user actions, e.g. changing an image when the user hovers over an element. Usually the image that you're changing to will need to be fetched from the server, and this will result in a delay between the user action and the image actually being changed.

In some cases, you can circumvent this whole issue by using a single background image that is moved by changing background-position through CSS hover selectors. In other cases the best way to enhance your user experience is to preload images.

To do this, we can create a JS Image object for each image we want to preload. We set each Image object's src attribute to a different image URL, and then, crucially, we wait for each of them to complete loading.

Here's the code:
var preloading = false; var safteyvalve = 1000;   function preload() { if (document.images) { // Set flag to indicate preload is occuring preloading = true;   // This array lists all the images we want to preload myImageList = ['http://mywebsite.com/images/image01.jpg', 'http://mywebsite.com/images/image02.jpg', 'http://mywebsite.com/images/image03.jpg'];   // Create an Image object for each image imagePreloader = new Array(); for (var offset = 0; offset < myImageList.length; offset++) { imagePreloader[offset] = new Image(); imagePreloader[offset].src = myImageList[offset]; }   // Check images in quarter of a second window.setTimeout(checkpreload, 250); } }   function checkpreload() { if (safteyvalve > 0) { safteyvalve--; } else { preloading = false; }   if (preloading) {   // Loop through image array to see if any are not yet loaded preloading = false; for (offset = 0; offset < imagePreloader.length; offset++) { if (!imagePreloader[offset].complete) { preloading = true; break; } } }   if (preloading) { // Check again in another 0.25 secs window.setTimeout(checkpreload, 250); } else { // Preloading complete - let user begin document.getElementById('startlink').innerHTML = 'Start'; }   }

Trimming Whitespace with Javascript

Here is a quick Javascript trim() function. Pass text to the function and it returns the text with leading and trailing whitespace removed. Spaces, tabs, and line-breaks before and after the text are stripped out. Click the HTML View button in the top-right corner of the code view below to try it out:
<script> <!-- function trim(text) { for (var first_nonwhite = 0; first_nonwhite < text.length && (text[first_nonwhite] == ' ' || text[first_nonwhite] == '\t' || text[first_nonwhite] == '\n' || text[first_nonwhite] == '\r'); first_nonwhite++); for (last_nonwhite = text.length-1; last_nonwhite > first_nonwhite && (text[last_nonwhite] == ' ' || text[last_nonwhite] == '\t' || text[last_nonwhite] == '\n' || text[last_nonwhite] == '\r'); last_nonwhite--); return text.substring(first_nonwhite, last_nonwhite+1); } --> </script>   <textarea id="textarea" rows="10" cols="70">   Enter some   text containing whitespace into this box. Click the button and   only whitespace at the end and the beginning will be stripped.   </textarea>   <input type="button" onclick="document.getElementById('textarea').value = trim(document.getElementById('textarea').value);" value="trim" />
The key elements of the function are two 'empty' for loops. The two loops contain no code and their purpose is simply to locate the first non-whitespace character and the last, respectively. The first loop loops while the character pointed at by first_nonwhite is one of the whitespace characters. It starts at the beginning, and advances one character at a time up to the end or the first non-white character.

The second loop does a very similar thing, but this time looking for the last character of text which is non-white. To do this it starts at the end, and moves one character at a time towards the beginning, stopping at the first non-white. If no non-white characters were found by the first loop, this second loop won't do anything.

The text we want to return is everything that falls between the first non-whitespace character and the last. We get this using the substring(i, j) method, which returns the string between the ith and the jth character. (There's a similar method called substr(i, j), which returns the string which starts at the ith character and is j characters in length.)

/xkcd/ METAR