CSS, JavaScript and XHTML Explained

Estelle Weyl’s Blog of quirks, random thoughts and funky finds discovered in day-to-day coding

 

Web Development for the iPhone: HTML, CSS & JS Support December 5, 2009


Safari and Safari for the iPhone support all HTML elements, including deprecated elements and even some proprietary elements that were never part of any W3C specifications. In addtion, Safari is supporting some HTML5 elements, even though the HTML5 specifications have not been finalized. I’ve also added the attributes that each element supports. I didn’t include id, class, style, dir & title, since all elements basically support those, but I did include element specific attributes as well as some webkit only attributes.

iPhone Support for CSS3 Selectors

All CSS Selectors are supported by Safari on the iPhone. See CSS browser support for a chartcomparison of all the selectors. Selectos include:

  • *
  • E
  • .class
  • #id
  • E F
  • E > F
  • E + F
  • E[attribute]
  • E[attribute=value]
  • E[attribute~=value]
  • E[attribute|=value]
  • :first-child
  • :link
  • :visited
  • :lang()
  • :before
  • ::before
  • :after
  • ::after
  • :first-letter
  • ::first-letter
  • :first-line
  • ::first-line
  • E[attribute^=value]
  • E[attribute$=value]
  • E[attribute*=value]
  • E ~ F
  • :root
  • :last-child
  • :only-child
  • :nth-child()
  • :nth-last-child()
  • :first-of-type
  • :last-of-type
  • :only-of-type
  • :nth-of-type()
  • :nth-last-of-type()
  • :empty
  • :not()
  • :target
  • :enabled
  • :disabled
  • :checked
  • see them all

iPhone Support for CSS3 properties

Almost all CSS2.1 properties and values are supported by Safari on the iPhone, except for some keyword values for content. Position: absolute is supported, but due to the viewport, does not appear to be supported. See the list of all CSS2.1 properties and values by browser for more details. In addition, the iPhone Safari browser supports some CSS3 type properties and values including:

Some CSS3 including the following, which will be discussed in future blog posts.

  • hsl(), rgba(), hsla() color support
  • native rounded corners (-webkit-border-radius)
  • IE box model (-webkit-box-sizing)
  • Shadows on text (text-shadow was in CSS2.0)
  • Shadows on elements (-webkit-box-shadow)
  • multiple background images
  • opacity /gradient transparency
  • @font-face web fonts
  • CSS Animation
  • Media Queries
  • namespaces

iPhone & Safari Support for HTML elements, including HTML5

includes HTML attributes for the iPhone and Safari

Below is a grid of all of the elements, including deprecated elements (at the way bottom), and HTML5 elements interspersed with HTML4 elements in alphabetical order.

<ELEMENT> Element Name Safari
Version
iPhone Support Attributes (and Notes in italic)
Elements occuring outside the body element
<!DOCTYPE> Document Type Declaration 1.0 1.0  
<html> html 1.0 1.0 manifest (Saf. 4, iphone 2.2)
<head> document head 1.0 1.0 profile
<base /> url base for links 1.0 1.0 href, target
<link /> link 1.0 1.0 charset, href, media, rel, rev, target
<meta /> meta 1.0 1.0 content, name, http-equiv, scheme
<style> style 1.0 1.0 media, type
<script> script 1.0 1.0 charset, defer, language, src, type
<title> document title 1.0 1.0  
Elements Occuring in the <body> in HTML 4.01 and HTML5
<body> document body 1.0 1.0 bgproperties (value: fixed)
<a> Anchor 1.0 1.0 different event handlers for iPhone than Safari
accesskey, charset, href (required), hreflang, rel, rev, shape (rect/cirlce/poly), target (deprecated, but useful), type

<abbr>

Abbreviation 1.0 1.0 title shows on hover in Safari
<acronym> acronym 1.0 1.0 title shows on hover in Safari
<address> address 1.0 1.0 italic
<area> image map area 1.0 1.0 accesskey, alt (required), coords, href (required), hreflang, shape (rect/cirlce/poly), target
<article>       HTML5
<aside>       HTML5
<audio> audio 3.1 3.0 HTML5: Similar to object, can nest sources and content to cascade until supported found.
Audio support includes AAC, M4A, MP3, Wave, AIFF , Apple Lossless, Quicktime, but not OGG;

autoplay, controls, end, loopend, loopstart, playcount, src, start
<bdo> bi-directional override 1.0 1.0  
<blockquote> long quote 1.0 1.0 cite

<br>

break return or forced line break 1.0 1.0  
<button> push button 1.0 1.0 accesskey, disabled, type, value
<canvas> canvas drawing region 1.3 1.0 HTML5: Stroke and fill colors, rgba/hsla colors, paths, rectangles, shadows, gradients, patterns, translations, rotation and scale
<caption> caption 1.0 1.0  
<cite> citation 1.0 1.0  
<code> code 1.0 1.0  
<col /> column 1.0 1.0 char, charoff, span
<colgroup> column group 1.0 1.0 char, charoff, span
<dd> definition description 1.0 1.0  
<del> delete 1.0 1.0 datetime

<dfn>

definition 1.0 1.0  
<div> generic block element 1.0 1.0 aria-checked, aria-level, aria-pressed, aria-valuemax, aria-valuemin, aria-valuenow, role (Safari 4.0)
<dl> definition list 1.0 1.0  
<dt> definition term 1.0 1.0  
<em> emphasized text 1.0 1.0  
<fieldset> field set 1.0 1.0  
<figure>       HTML5
<footer>       HTML5
<form> form 1.0 1.0 accept, accept-charset, action, enctype. method, target
<frame /> frame 1.0 1.0 frameborder, longdesc, marginheight, marginwidth, noresize, scrolling (yes/no/auto), src
<frameset> frameset 1.0 1.0 cols, rows
<h1-6> headers 1.0 1.0  
<header>       HTML5
<hgroup>       HTML5
<hr /> horizontal rule 1.0 1.0  
<iframe> internal frame 1.0 1.0 frameborder, longdesc, marginheight, marginwidth, scrolling (yes/no/auto), src
<img /> image 1.0 1.0 alt (required), composite, ismap, longdesc, src, usemap
<input /> input 1.0 1.0 accept, accesskey, alt, autocapitalize (iphone 1.1, values: on/off), autocomplete, autocorrect (iphone 1.1, values: on/off), autosave (safari), checked, disabled, incremental (safari), ismap, max, maxlength, min, placeholder, results, src, type, usemap, value
<ins> Insert 1.0 1.0 datetime
<kbd> keyboard 1.0 1.0  
<keygen> key generation 1.0 1.0 challenge, keytype
<label> label 1.0 1.0 accesskey, for
<legend> caption for fieldset 1.0 1.0 accesskey
<li> list item 1.0 1.0 type, value
<map> image map 1.0 1.0  
<mark>       HTML5
<meter>       HTML5
<object> object 1.0 1.0 archive, classid, codetype, data, declare, loop, type, usemap

<ol>

ordered list 1.0 1.0 type
<optgroup> option group 1.0 1.0 disabled, label
<option> option 1.0 1.0 disabled, label, selected, value
<p> paragraph 1.0 1.0  
<param> parameter 1.0 1.0 type, value, valuetype
<pre> preformatted text 1.0 1.0  
<progress>       HTML5
<q> inline quotation 1.0 1.0 cite
<samp> sample computer code 1.0 1.0  
<select> option selector 1.0 1.0 disabled, multiple
<source>   3.1   HTML5
media
<span> span (generic non-semantic container) 1.0 1.0 aria-checked, aria-level, aria-pressed, aria-valuemax, aria-valuemin, aria-valuenow, role (Safari 4)
<strong> strong emphasized text 1.0 1.0  
<sub> subscript 1.0 1.0  
<sup> superscript 1.0 1.0  
<table> data table 1.0 1.0 frame (values: above, below, hsides, vsides, rhs, lhs, box, border), rules (values: none, groups, rows, cols, and all), summary
<tbody> table body 1.0 1.0 char, charoff
<td> table data cell 1.0 1.0 abbr, axis, char, charoff, colspan, headers, rowspan, scope
<textarea> text area 1.0 1.0 accesskey, cols, disabled, readonly, rows, wrap
<time>       HTML5
<tfoot> table footer 1.0 1.0 char, charoff
<th> table header cell 1.0 1.0 abbr, axis, char, charoff, colspan, headers, rowspan, scope
<thead> table head 1.0 1.0 char, charoff
<tr> table row 1.0 1.0 char, charoff
<ul> unordered list 1.0 1.0  
<var> variable 1.0 1.0  
<video> video 3.1 3.0 HTML5
autoplay, controls, end, loopend, loopstart, playcount, poster, src, start
Elements you should not be using, that are still valid
<tt> teletype 1.0 1.0  
<i> italic
<b> bold
<big> big font
<small> small font
<noframes> no frames 1.0 1.0  
<noscript> no script 1.0 1.0  
Elements that are deprecated or were never in a W3C spec, but you may still see on older websites
<applet> applet 1.0    
<center> center 1.0 1.0  
<dir> direction 1.0 1.0  
<embed> embed 1.0 1.0 use object instead
hidden, loop, pluginpage, pluginspage, pluginurl
<font> font 1.0 1.0  
<layer> layer 1.0 1.0  
<listing> listing 3.0 1.0 use <pre> instead. from HTML 3.2
<marquee> ,arquee 1.0 1.0 behavior, direction, loop, scrollamount, scrolldelay, truespeed
<menu> menu 1.0 1.0  
<nobr> no break 1.0 1.0  
<noembed> no embed 1.0 1.0  
<nolayer> no layer 1.0 1.0  
<plaintext> plaintext 1.0 1.0  
<strike> strikethrough 1.0 1.0 use <del>
<u> underline      
<wbr> with breaks 1.0 1.0  
<xmp> sequence of literal characters 1.o 1.0  


Safari and iPhone Event Handlers:

Event Safari iPhone Explanation
onabort 1.0 1.0 When an image element is aborted during load. (for <img /> elements)
onbeforecopy 1.3   before the element is copied.
onbeforecut 1.3   before the element is cut.
onbeforepaste 1.3   before the element has something pasted into it.

onbeforeunload 1.3   before the element is unloaded from the page.

onblur 1.0 1.0 when the element loses focus.

onchange 1.0 1.0 when the element changes its value.

onclick 1.0 1.0 when the element is clicked.

oncontextmenu 1.1   when the element is right-clicked or when the mouse button is held down long enough to generate a contextual menu.

oncopy 1.3   when the element is copied.

oncut 1.3   when the element is cut.

ondblclick 1.0   when the element is double-clicked.

ondrag 1.3   when the element is dragged.

ondragend 1.3   when the element is done being dragged.

ondragenter 1.3   when a drag has entered the element.

ondragleave 1.3   when a drag has left the element.

ondragover 1.3   when a drag is over the element.

ondragstart 1.3   when the element has started to be dragged.

ondrop 1.3   when the element is dropped.

onerror 1.0 1.0 when the element has an error in loading.

onfocus 1.0 1.0 when the element gets focus.

ongesturechange   2.0

When fingers are moved during a gesture.

(proprietary)

ongestureend   2.0

When the gesture ends (when there are 1 or 0 fingers touching the surface).

(proprietary)

ongesturestart   2.0

When two or more fingers touch the surface.

(proprietary)

oninput 1.3 1.0 when text is entered into the element.
onkeydown 1.0 1.0 when a key is pressed over the element.

onkeypress 1.0 1.0 when a key is pressed and released over the element.

onkeyup 1.0 1.0 when a key is released over the element.

onload 1.0 1.0 when the element finishes loading.

onmousedown 1.0 1.0 when the mouse button is pressed over the element.

onmousemove 1.0 1.0 when a key is moved within the element.

onmouseout 1.0 1.0 when the mouse leaves the element.

onmouseover 1.0 1.0 when the mouse is over the element.

onmouseup 1.0 1.0 when the mouse button is released over the element.

onmousewheel 1.0 1.0 when the mouse wheel button is rotated.

onorientationchange   1.1

When the orientation of the device changes.

onpaste 1.3   when the element is pasted.

onreset 1.0 1.0 when the form element is reset.

onresize 1.0 1.0 when the element is resized.

onscroll 1.2 1.0 when the element is scrolled (a text box would use this, for example).
onsearch 1.3  

when a search is performed.

(proprietary)

onselect 1.0 1.0 when text within the element is selected.

onselectstart 1.3   when the element begins to be selected. You can use this to prevent selections.

onsubmit 1.0 1.0 when the form element is submitted.

ontouchcancel   2.0

When the system cancels tracking for the touch.

(proprietary)

ontouchend   2.0

When a given event lifts from the surface.

(proprietary)

ontouchmove   2.0

When a finger for a given event moves on the surface.

(proprietary)

ontouchstart   2.0

When a finger for a given event touches the surface.

(proprietary)

onunload   2.1 when the element is unloaded from the page.

 

Other iPhone posts in my blog

 
 

iPhone Screen Orientation: Portrait and Landscape September 11, 2009

Filed under: Browsers, Character Entities, HTML, JavaScript, Web Development, iPhone — Estelle Weyl @ 12:22 am

When you tilt your iPhone, the screen changes orientation. The website you developed for the default portrait orientation may not look good in landscape mode, especially if you developed your page for the 480 (h) x 320 (w) screen.

In my original iPhone post, I instructed detecting the width of the screen at regular intervals to detect the orientation of the iPhone. That post was written within a week of the launch of v1 of the iPhone. There is now a better method: use the onOrientationChange method to change the class of your body based on the page’s orientation. Include CSS for both normal page layout, and then include a series of overrides for when the screen is displaying your iPhone application in landscape mode.

What you want to include is the unobstrusive javascript equivalent of:

<body onOrientationChange="changeMyClass();">

In this case, we’ll call

switch(window.orientation){
   case 0:
       //handle portrait actions
       //document.getElementsByTagName('body')[0].className = ‘portrait’;
       break;
  case -90:
  case 90:
       // handle landscape actions
       //document.getElementsByTagName(’body’)[0].className = ‘landscape’;
       break;
} //end switch


 
 

More CSS, XHTML and JavaScript at Community MX September 9, 2009

Filed under: CSS (including hacks), JavaScript, Web Development, firebug — Estelle Weyl @ 12:55 pm

I have been somewhat prolific as a technical writer for Community MX over the past 12 months. If you are interested in any of the articles, they are listed below. I will add new articles to this list as they get published (and as I get around to it). While Community MX is a subscription based website, you can get a one week free trial, and several of the articles (as noted below) are accessible without a subscription, and without logging in.


Most articles are part of a series. These four random ones are standalone:

There is a lot of interest in my IE8 post. It was a basic post, and I couldn’t get my butt in gear to write more. By writing for community MX, I kind of forced myself to research IE8. This seried has just begun… there will be a bunch more.

Based on my blog post on all XHTML elements, their attributes and their semantic meaning that I was wrote for this blog, I wrote an 18 part series going into each element in greater detail. The Object and input element (free) ones are the most intersting. The table of XHTML elements (also free) is the most useful:


While simple, the Three Column layout series teaches the reader how to make a three column layout, with the columns being able to be rearranged into any order without touching the HTML source code. If you don’t know how to make a CSS 3-column layouts, this series is definitely worth the read.

My firebug tutorial has already had over 100,000 views. Obviously there is interest. My Community MX Firebug series is only half way done, but as you can imaging, it’s going deeper into this most excellent tool. Similar to the IE8 series, I am still in the middle of this series. There should be several more.

The EMail Setup series is especially useful for anyone using CPanel or anyone trying to manage several email to and from accounts:

The CSS for Absolute Beginners series is very basic, and likely to simplistic for readers of this blog: as noted, it’s fore beginners. However, if you do want the basics, I am including the list of articles for those of you who are interested:

Don’t worry. Obviously I am still writing here too. Just wanted to share these in case anyone is interested.

 
 

hover pseudoclass for the iPhone December 28, 2008

Filed under: Best Practices, CSS (including hacks), HTML, IE7, JavaScript, Web Development, iPhone — Estelle Weyl @ 9:38 pm

Since you’re not hovering, there is no hover pseudo class on the iPhone. instead they have touch events. To simulate the :hover pseudo class, include javascript similar to this:

var myLinks = document.getElementsByTagName('a');
for(var i = 0; i < myLinks.length; i++){
   myLinks[i].addEventListener(’touchstart’, function(){this.className = “hover”;}, false);
   myLinks[i].addEventListener(’touchend’, function(){this.className = “”;}, false);
}

and in your CSS add something similar to:

a:hover, a.hover { /* whatever your hover effect is */ }

Notes:

  • onTouchStart is similar to onMouseOver and onTouchEnd is similar to onMouseOut
  • You’ll likely want something more complex than simply removing the class on touch end. This is just a very simple example that will replace all classes on all your links with a "hover" class, which is probably not what you want. But you get the idea.
  • You can use this on all elements, not just links.

-Estelle Weyl

Note:

 
 

jQuery Tutorial: DOM Manipulation and sorting November 15, 2008

Filed under: JavaScript, Web Development — Estelle Weyl @ 5:26 pm

JQuery is a lightweight JavaScript library that helps you quickly develop events, animations, and AJAX interactions.

In this tutorial we go over the following:

Note that the test javascript files associated with each section go with the same XHTML file.

Setting up your environment for this tutorial:

  • Download the JQuery library Generally you will want the minified version, but for today, download the uncompressed version so you can read some of the code if you so choose.

  • Save it locally in a directory (let’s call it "js" for this tutorial)

  • Create a new HTML page (Sample file)

  • Link to the JQuery file - <script type="text/javascript" src="js/jquery-1.2.6.js"></script>
    You may need to change the 1.2.6 part to whatever the current release number is.

  • Create a new javascript file, and call it "myCode.js"

  • Link to your javascript file - <script type="text/javascript" src="js/myCode.js"></script>

  • Add some HTML to your page (this is what we’re going to manipulate).

  • You can also add some CSS.

ready method in anonymous function

The first step is to create an anonymous function withing your myCode.js file to encompass all of your javascript. If you take a look at your JQuery file, you’ll note that the entire file is in an anonymous function:

(function(){
 // code here

})();

All of your the code that you create should be included in it’s own anonymous function. This ensures that the jQuery variables are local: your variable declarations will not break the jQuery library, and the jQuery library will not overwrite your variables, methods and properties.

For our own javascript, we are going to encapsulate all our code in an anonymous function. However, since we are accessing elements of the DOM, we need to ensure that the DOM is loaded. We can’t use the parenthesis at the end as in the code above, which executes the anonymous function immediately, since our DOM isn’t loaded yet. We should only execute our anonymous function once we have the DOM. Without jQuery, and without much Javascript skill, the usual route is to include a document.onLoad event. Instead of using onLoad, which makes us wait until all the images are loaded, we’re going to use jQuery’s ready function — $(document).ready() — which executes when the DOM is ready.

The $(document).ready() function has advantages over other load time event handlers. Everything inside it will load as soon as the DOM is loaded, without having to wait for the page contents to be completely loaded. Ready is fired as soon as the DOM is registered by the browser, which allows for hiding and showing effects and other effects as soon as the user sees the page elements. Unlike the onLoad method, which is limited to only one function, the jQuery ready method allows for multiple functions to be loaded within it.

$(document).ready(function() {
 // code here
 });

Add the code above to your myCode.js file.jQuery

Targeting elements in the DOM with CSS and XPath

jQuery enables selecting elements with the same syntax that you would use to target that element with CSS. For example, we can target the first <h2> in our html file these two ways among others: (test js)

  • $("h2:first")
  • $("#mainContent > h2")

Take a look at the official jQuery Selectors page to get a better understanding of how you can use CSS syntax to target elements.

DOM Manipulation

The following are explanations and examples of the DOM manipulation methods provided by the jQuery core. The jQuery domentation for the DOM manipulation methods can be found at http://docs.jquery.com/Manipulation

jQuery’s version of innerHTML and textNodes

jQuery replaces innerHTML with the html() method to both return and set innerHTML with (and without) HTML elements. To return or set text, similar to retrieving and setting textNodes, use jQuery’s text() method. The main difference between the two involves the returning and rendering of HTML elements. (test js)

  • html()
    returns the HTML content of an element. This is directly equivalent to the innerHTML property commonly used by JavaScripters.
    var myHTMLContent = $("#mainContent").html(); // "<h2>My jQuery te…. (to) …functionality</p>
  • html(myString)
    Sets the innerHTML for an element to myString.
    $("h2:first").html(’This is new <em>header</em> content’); // changes the h2, and adds some emphasis
  • text()
    returns the text content, or text nodes, of an element without any markup as one string
    var myTextContent = $("#mainContent").text(); // returns same as html(), but without tags;
  • text(myString)
    Resets the text node value for an element to myString.
    $("h2:first").text(’Ugly <em>header</em>); // escapes ‘>’ and ‘<’ instead of rendering italics

Child & Sibling nodes

append() and prepend() methods: similar to appendChild, except jQuery accepts a string, a DOM element, or a jQuery object as valid arguments. jQuery converts the argument into a text node or element depending on what is passed. (test js)

  1. $("#leftNav ul").append("<li>after the last &lt;li&gt;</li>"); // adds <li> at the end of <ul>
  2. $("#leftNav ul").prepend("<li>before the first &lt;li&gt;</li>"); // adds <li> at the start of <ul>
  3. $("#leftNav ul").append($("#mainContent h2")); // moves headers from the mainContent to the leftNav

  4. $("#leftNav ul").append($("#mainContent h2").html()); //copies text of the first h2, adds it to leftNav

There are two similar methods — appendTo() and prependTo() — which are basically inververted verstions of append() and prepend(). A.append(B) is about equal to B.appendTo(A)

Note: As shown in example 3, if you try to append an element that already exists in the DOM, that element will first be removed from DOM before being reinserted, or appended, in the new location.

before() and after() methods: similar to insertBefore() method (and the non-existant, but found in many javascript libraries, includeing this one, insertAfter()). The after() method inserts a node after a selected one. The before() method inserts a node before a selected one, like the javascript standard method of insertBefore().

  1. $("#leftNav ul").before("<h2>Left Navigation</h2>"); // adds header before the <ul>
  2. $("#leftNav ul").after("<h4>New Header</h4>"); // adds header after the <ul>
  3. $("#leftNav h4").before($("#mainContent h2").html()); //copies text of the first h2, adds it to leftNav before our new <h4>

There are two similar methods — insertBefore() and insertAfter() — which are basically inververted versions of before() and after(). A.before(B) is about equal to B.insertBefore(A)

Parent nodes

wrap(), wrapAll() and wrapInner() methods: wrap selected element or elements in another element. The argument can be an XHTML or DOM element as a string. If the element has child nodes, the element being wrapped will be put in the deepest child node of the first element. (test js)


  1. $("#leftNav ul").wrap("<div class=\"red\"></div>"); // the <ul> gets wrapped in a <div>
  2. $("#mainContent h2").wrap("<blockquote class=\"blue\"></blockquote>"); // the 2 <h2>’s get wrapped in a two separate <blockquote>s
  3. $("#mainContent h2").wrapAll("<blockquote class=\"blue\"></blockquote>"); // the 2 <h2>’s get wrapped in a single <blockquote>, moving the second <h2> up to be the nextSibling to the first <h2>
  4. $("#mainContent h2").wrap(’<div class="shell"><div class="blue"></div><ul class="red"><li></li></ul></div>’); // puts the H2s in two "blue" divs, the LIs will be empty.
  5. $("#mainContent h2").wrapAll(’<div class="shell"><div class="blue"></div><ul class="red"><li></li></ul></div>’); // puts the H2s in ONE "blue" div, the LI will be empty.
  6. $("#mainContent p").wrapInner("<a href=\"#\"></a>"); // puts an <a> between the <p> and the <p>’s first child.
  7. $("#mainContent").wrapInner("<blockquote class=\"blue\"></blockquote>"); // wraps all the children of #mainContent into one parent <blockquote>

remove() and empty()

remove(), empty() and replace() methods: similar to the native javascript removeChild() method, use remove() to remove element(s) from the DOM. Use the empty() method to keep the element, but remove the element’s children.
Note that remove() can take a parameter, but empty() does not. (test js)

  1. $("#leftNav li:first").remove(); // removes the first LI
  2. $("#leftNav li").remove(); // removes all the LIs from the #leftNav
  3. $("#leftNav li").remove(":contains('Second')"); //remove the LI containing the term.
    Note that the string is case-sensitive
  4. $("#mainContent h2:first").empty(); //removes the text in the first H2, but the h2 is not removed from the DOM
  5. $("#mainContent h2:contains('second')").empty(); //removes the text node child of the H2 containing the letters "second"

replaceWith(), replaceAll() and ncloe()

replaceWith() and clone() methods: Cloning creates copies of the DOM elements copied, including the new elements in the DOM, but does not append them to the page. To append the clone to the page, use one of the methods above.

  1. $("#leftNav li:first").replaceWith("<li>new first <em>LI</em></li>"); //text changed, LI is emphasized

  2. $("#leftNav li:first").text().replaceWith("new first <em>LI</em>");// grabs text, and replaces it. No <li> needed
  3. var navCopy = $("#leftNav").clone(); //copies it
    $("#mainContent").append(navCopy); //apends it

    The problem with cloning is that IDs are copied too, and ID’s need to be unique!


Effects with JQuery

The above was an overview of all the DOM manipulation functions. If you’re doing a simple site, those are likely all the javascript helpers you need. But, if that was all you could do with JavaScript, then you really wouldn’t need javascript libraries. The power of the libraries is in everything else they do for you. With jQuery you can create drag and drop, autocomplete, sorting, etc., the is unobtrusive and works cross browser in less than 10 lines of javscript. Proof? Here are two examples:

Sorting a table with javascript:

  1. Create a table in plain old XHTML, and populate that table with data. Give your data table the class of sort with: (sampleFile)

    <table class="sort">
  2. Download the jquery libary and the jquery.tablesorter.js file.

  3. Attach the two jQuery files and your own JavaScript file to your XHTML file by including the following in the header of your XHTML file:

    <script type="text/javascript" src="jquery-1.2.6.js"></script>
    <script type="text/javascript" src="jquery.tablesorter.js"></script>
    <script type="text/javascript" src="myTableCode.js"></script>
  4. In your JavaScript file (called myTableCode.js above) include the simple script:

    $(document).ready(function() {
        $("table.sort").tablesorter();
     });
  5. Literally, the previous step is all there is to sorting tables bu column content in However, that just sorts it based on the content of the HTML. So, if you have an <em> or <p> in one table cell and not in another, it may not sort the way you want. To sort based on a portion of your code inside a cell, use the textExtraction utility provided by jQuery:
    $(document).ready(function() {
    
     $("table.sort").tablesorter({
            // define a custom text extraction function
           textExtraction: function(node) {
                // if there is a link, return the content of the link
    		if(node.getElementsByTagName('a')[0]){
    				return node.getElementsByTagName(’a')[0].innerHTML;
        			}
            return node.innerHTML;
            }
        });
     });

See my example

Making a list sortable

Similar to the sortable table, you can make a make a list that is sortable by dragging list items around. (example)

  1. Create a list, give it the class of "sortable".

    <ul class="sortable">
      <li>This is my first list item</li>
      <li>second list item</li>
      <li>Brief 3</li>
      <li>Long 4</li>
    </ul>
  2. Go to the jQuery Download Builder and select “sortable”. You’ll note that the other required library elements are automatically selected.

  3. Attach the three javascript files downloaded from the builder, and your own javascript file, to your page with the list.

    $(document).ready(function() {
         $("ul.sortable").sortable();
       });

 

Userful Links

 
 

15 JavaScript Gotchas October 19, 2008

Filed under: Best Practices, JavaScript, Web Development — Estelle Weyl @ 2:02 am

We all know that JavaScript can trip you up. Here are a 15 common traps that can trip you up when coding javascript. You likely know most of the code on the page, but if you keep these 15 gotchas in your mind, coding and debugging will be less of a headache:

  1. Case sensitivity: Variable names, properties and methods are all case sensitive
  2. Mismatching quotes, parenthesis or curly braces will throw an error
  3. Conditional Statments:3 common gotchas
  4. Line breaks: Always end statements in semi-colons to avoid common line break issues
  5. Punctuation:Trailing commas in object declarations will trip you up
  6. HTML id conflicts
  7. Variable Scope: global versus local scope
  8. string replace function isn’t global
  9. parseInt should include two arguments
  10. ‘this’ and binding issues
  11. Function overloading: Overwriting functions, as overloading doesn’t exist
  12. Setting default values for parameters in case you omit them
  13. For each loops are for objects, not arrays
  14. switch statements are a little tricky
  15. Always check for Undefined before checking for null
Case Sensitivity
Variables and function names are case sensitive. Like mismatched quotes, you already know this. But, since the error may be silent, here is the reminder. Pick a naming convention for yourself, and stick with it. And, remember that native javascript function and CSS properties in javascript are camelCase.

getElementById(’myId’) != getElementByID(’myId’); // it should be “Id” not “ID”
getElementById(’myId‘) != getElementById(’myID‘); // “Id” again does not equal”ID”
document.getElementById('myId').style.Color; // returns “undefined”
Mismatching quotes, parenthesis and curly brace
The best way to avoid falling into the trap of mismatched quotes, parentheses and curly brackets is to always code your opening and closing element at the same time, then step into the element to add your code. Start with:

var myString = ""; //code the quotes before entering your string value
function myFunction(){
     if(){   //close out every bracket when you open one.

	 }
}

//count all the left parens and right parens and make sure they're equal
alert(parseInt(var1)*(parseInt(var2)+parseInt(var3))); //close every parenthesis when a parenthesis is open

Every time you open an element, close it. Put the arguments for a function into the parenthesis after you’ve added the closing parenthesis. If you have a bunch of parenthesis, count the opening parenthesis and then the closing parenthesis, and make sure those two numbers are equal.

Conditional statements (3 gotchas)
  1. All conditional comments must be within parentheses (duh!)
    if(var1 == var2){}
  2. Don’t get tripped up by accidentally using the assignment operator: assigning your second argument’s value to your first argument. Since it’s a logic issue, it will always return true and won’t throw an error.
    if(var1 = var2){} // returns true. Assigns var2 to var1
  3. Javascript is loosely typed, except in switch statements. JavaScript is NOT loosely typed when it comes to case comparisons.
    var myVar = 5;
    if(myVar == '5'){ // returns true since Javascript is loosely typed
      alert("hi");  //this alert will show since JS doesn't usually care about data type.
    }
    switch(myVar){
      case '5':
      alert("hi"); // this alert will not show since the data types don't match
    }
Line Breaks
  • Beware of hard line breaks in JavaScript. Line breaks are interpreted as line-ending semicolons. Even in a string,if you include a hard line break in between quotes you’ll get a parse error (unterminated string).
        var bad  = '<ul id="myId">
                       <li>some text</li>
                       <li>more text</li>
                    </ul>'; // unterminated string error
    
        var good = '<ul id="myId">' +<li>some text</li>‘ +
                       ‘<li>more text</li>‘ +
                   ‘</ul>’; //correct
  • The line break being interpreted as a semi-colon rule, discussed above, does not hold true in the case of control structures: line breaks after the closing parenthesis of a conditional statement is NOT given a semi-colon.

Always use semi-colons and parenthesis so you don’t get tripped up by breaking lines, so your code is easier to read, and, less thought of but a source of quirks for those who don’t use semicolons: so when you move code around and end up with two statements on one line, you don’t have to worry that your first statement is correctly closed.

Extra commas
The last property in any JavaScript object definition must never end with a comma. Firefox won’t barf on the trailing, unnecessary commas, but IE will.

HTML id conflicts
The JavaScript DOM bindings allow indexing by HTML id. Functions and properties share the same namespace in JavaScript. So, when an id in your HTML has the same name as one of your functions or properties, you can get logic errors that are hard to track down. While this is more of a CSS best practice issue, it’s important to remember when you can’t solve your javascript issue.

var listitems = document.getElementsByTagName('li');

var liCount = listitems.length; // if you have <li id="length">, returns that <li> instead of a count.

If you’re marking up (X)HTML, never use a javascript method or property name as the value for an ID. And, when you’re coding the javascript, avoid giving variables names that are ID values in the (X)HTML.

variable scope
Many problems in javascript come from variable scope: either thinking that a local variable is global, or overwriting a global variable unwittingly with what should be a local variable in a function. To avoid issues, it’s best to basically not have any global variables. But, if you have a bunch, you should know the “gotchas”.

Variables that are not declared with the var keyword are global. Remember to declare variables with the var keyterm to keep variables from having global scope. In this example, a variable that is declared within a function has global scope because the var ke

anonymousFuntion1 = function(){
	globalvar = 'global scope'; // globally declared because "var" is missing.
	return localvar;
}();

alert(globalvar); // alerts 'global scope' because variable within the function is declared globally

anonymousFuntion2 = function(){
	var localvar = 'local scope'; //locally declared with "var"
	return localvar;
}();

alert(localvar); // error "localvar is not defined". there is no globally defined localvar

Variable names that are introduced as parameter names are local to the function. There is no conflict if your parameter name is also the name of a global variable as the parameter variable has local scope. If you want to change the global variable from within a function that has a parameter duplicating the global variable’s name, remember that global variables are properties of the window object.

var myscope = "global";

function showScope(myscope){
  return myscope; // local scope even though there is a global var with same name
}
alert(showScope('local'));

function globalScope(myscope){
  myscope = window.myscope; // global scope
  return myscope;
}
alert(globalScope(’local’));

You should even declare variables within loops

for(var i = 0; i < myarray.length; i++){}
string replace
A common mistake is assuming the behavior of the string replace method will impact all possible matches. Infact, the javascript string replace method only changes the first occurrence. To replace all occurrences, you need to set the global modifier.

  var myString = "this is my string";
  myString = myString.replace(/ /,"%20"); // "this%20is my string"
  myString = myString.replace(/ /g,”%20″); // “this%20is%20my%20string”
parseInt
The most common error with parding integers in javascript is the assumption that parseInt returns the integer to base 10. Don’t forget the second argument, the radix or base, which can be anything from 2 to 36. To ensure you don’t screw up, always include the second parameter.

parseInt('09/10/08'); //0parseInt('09/10/08',10); //9, which is most likely what you want from a date.
‘this’
Another common mistake is forgetting to use ‘this‘. Functions defined on a JavaScript object accessing properties on that JavaScript object and failing to use the ‘this’ reference identifier. For example, the following is incorrect:

function myFunction() {
  var myObject = {
     objProperty: "some text",
     objMethod: function() {
		alert(objProperty);
		}
     };
  myObject.objMethod();
} 

function myFunction() {
  var myObject = {
     objProperty: "some text",
     objMethod: function() {
		alert(this.objProperty);
		}
     };
  myObject.objMethod();
}

There’s an A List Apart article that puts this binding issue into plain English

Overwriting functions / overloading functions
When you declare a function more than once, the last declaration of that function will overwrite all previous version of that function throwing no errors or warnings. This is different from other programming languages, like java, where you can have multiple functions with the same name as long as they take different arguments: called function overloading. There is no overloading in javascript. This makes it vitally important to not use the names of core javascript functions in your code. Also, beware of including multiple javascript files, as an included script may overwrite a function in another script. Use anonymous functions and namespaces.

(function(){
	// creation of my namespace
    // if namespace doesn’t exist, create it.	if(!window.MYNAMESPACE) {		window['MYNAMESPACE'] = {}; 		}

    // this function only accessible within the anonymous function
    function myFunction(var1, var2){
		//local function code goes here
    }

    /* attaches the local function to the namespace
       making it accessible outside of the anoymous function with use of namespace */
    window['MYNAMESPACE']['myFunction'] = myFunction; 

 })();// the parenthesis = immediate execution	  // parenthesis encompassing all the code make the function anonymous
Missing Parameters
A common error is forgetting to update all the function calls when you add a parameter to a function. If you need to add a parameter to handle a special case call in your function that you’ve already been calling, set a default value for that parameter in your function, just in case you missed updating one of the calls in one of your scripts.

function addressFunction(address, city, state, country){
      country = country || “US”; // if country is not passed, assume USA
      //rest of code
    }

You can also get the length of the argument array. But we’re focusing on “gotchas” in this post.

For each

The “for” loop in javascript will iterate it over all object attributes, both methods and properties, looping thru all of the property names in an object. The enumeration will include all of the properties—including functions and prototype properties that you might not be interested in—so filter out the values you don’t want using hasOwnProperty method and typeof to exclude functions. Never use for each to iterate thru an array: only use for each when needing to iterated thru object properties and methods.

  • for each (var myVar in myObject) iterates a specified variable over all values of object’s properties.
  • for (var myVar in myObject) iterates a specified variable over all the properties of an object, in arbitrary order. The for...in loop does not iterate over built-in properties. For each distinct property the code is executed
  • for (var 1=0; i < myArray.length; i++) iterates thru all the elements of an array.

To fix the problem, generally you’ll want to opt for for ... in for objects and use the for loop for arrays:

listItems = document.getElementsByTagName('li');

for each (var listitem in listItems){
    // this goes thru all the properties and methods of the object,
    // including native methods and properties, but doesn't go thru the array: throws error!
   }

//since you have an array of objects that you are looping thru, use the for loop
for ( var i = 0; i < listItems.length; i++) {
    // this is what you really wanted
   }
Switch statements
I wrote a whole blog post on switch statement quirks, but the gist is:

  • there is no data type conversion
  • once there is a match, all expressions will be executed until the next break or return statement is executed, and
  • you can include multiple cases for a single block of code
Undefined ≠ null
Null is for an object, undefined is for a property, method or variable. To be null, your object has to be defined. If your object is not defined, and you test to see whether it’s null, since it’s not defined, it can’t test, and will throw an error.

if(myObject !== null  && typeof(myObject) !== 'undefined') {
	//if myObject is undefined, it can't test for null, and will throw an error
}

if(typeof(myObject) !== 'undefined' && myObject !== null) {
	//code handling myObject
}

Harish Mallipeddi has an explanation of undefined versus null

dt {font-weight:bold; font-size:116%;}

 
 

JavaScript Object Literals Simplified July 2, 2008

Filed under: JavaScript, Web Development — Estelle Weyl @ 1:11 am

Instantiating Objects

You are likely familiar with instantiating strings and arrays in javascript:

var myString = new String();
var myArray = new Array();

Array and String are both objects, extended from the Object object. String and Array are objects inheriting all the properties of the Object object, and adding new properties and methods that are specific to the Array and String objects respectively. In these cases, the new keyword creates a new instance of the String and Array objects respectively.

There are several ways to declare an object in Javascript, including:

var myObject = new Object();

var myObject = {};

JavaScript Dot Notation

If you are on this site, you have likely used javascript dot notation for properties and methods of objects. The following hopefully looks familiar to you:

var myFirstLink = document.getElementById('myDiv').getElementsByTagName('a')[0];
//returns the first link in the parent element with ID of “myDiv”

myFirstLink.className = “myClass”
// or, not as good, but still valid, myFirstLink.style.color = “#ff0000″

and if you have used any javascript libraries, or have coded more advanced javascript, you have likely used javascript dot notation in creating new methods, such as

myObject.somemethod = function(){
    // code here
}

Declaring methods and properties with Dot notation

Using dot notation your code may look something like this:

var myObject = new Object();
	myObject.myProperty = value;
	myObject.yourProperty = value;
	myObject.myMethod = function(){
	  //code here
	}
	myObject.yourMethod = function(){
	  //more code
	}

Note: remember that undefined properties of objects return undefined. Unlike undeclared variables, they do “exist”, so they don’t throw an error. If we us the examples above, (myString.typoed_property == undefined) returns true.

Declaring methods and properties using Object Literal syntax

You could declare the properties and methods listed above using cleaner Object Literal syntax:

var myObject ={
	myProperty : value,
	yourProperty : value,
	myMethod : function(){
	  //code here
	},
	yourMethod : function(){
	  //more code
	}
}

A few things to note:

  1. The Object literal notation is basically an array of key:value pairs, with a colon separating the keys and values, and a comma after every key:value pair, except for the last, just like a regular array. Values created with anonymous functions are methods of your object. Simple values are properties.
  2. if you are mixing code sources, using libraries or sharing code, you want to use static methods and properties rather than public methods and properties, to safeguard against overwriting functions or variables / methods or properties declared outside your current javascript file.
  3. Unlike public functions, which can appear anywhere in your code, including after lines using your function, methods declared using object literal notation do not exist until execution of that section of the script.
  4. This method instantiates a new object, so don’t try to create a instance using the new keyword
 
 

JavaScript Date Object Methods September 5, 2007

Filed under: JavaScript, Web Development — Estelle Weyl @ 11:44 pm

Methods of the JavaScript Date Object

This is the second half of a two part discussion of the javascript date object. The first half discusses creating, formatting, extending and converting the date object. This section focuses solely on the methods of the javascript Date oject. In the prior section we created a working and accurate date object. There is a great deal written on the methods of the Date object, but there were very few examples. As this is an entry about JavaScript, you will need to have javascript enabled to learn from this tutorial. There are examples. of all the methods: see below:

dt {font-family:”Courier New”, Courier, mono; font-weight:bold;padding-top: 8px; padding-left:8px;}

I will be using three sample dates for the following examples:

  • var auntsBirthday = new Date(”September 4, 1902″);
  • var currTime = new Date() // your computer’s time
  • var myTime = new Date(2003,8,21); // September 21, 2003

When we get to the setMethods, the dates will be changed as we set different values.

prototype
The prototype property is used to assign new properties and methods to instances of the Date object
See Date.prototype.customFormat(datestring) in javascript date object tutorial.
constructor
A reference to the function that created the instance of a Date object. Can be used to test if a variable is a Date.
if (myTime.constructor == Date) {}
parse(string)
The millisecond equivalent of the date specified in the correctly formatted string parameter.

UTC(year, month [, date, hours, minutes, seconds, ms])
Returns an integer — the UTC millisecond value of the date specified as parameters. The parameter values for the UTC() method must be in UTC time for the returned value to be accurate. This method does not generate a Date object. The Year and Month are required. The other parameters are optional. I have no clue why anyone would use this. Please let me know via comments. The difference between UTC and getTime(); may be the offset from GMT. I need to look more into this.
toString()
Returns a string value of the date. Different browsers return different strings, and usually the string value is returned in a format that is not suitable to return raw to the user.
toDateString()
Returns the date portion of an instance of a Date object as a string. The format is under the control of the browser, so I prefer the customFormat method.
toTimeString()
Returns the time portion of the instance of a Date object as a String. The format depends on the browser and language so I prefer the customFormat method.

toLocaleString()
Returns the local time zone value of both the date and time. The format may be localized, so this may be useful for internationalization. I prefer, again, to rely on an internationalized version of the customFormat, but I probably shouldn’t.
toLocaleDateString()
Returns the date portion of an instance of a Date object as a String. The format is based on the browser and language and differs between some browsers, so I prefer the customFormat method.

toLocaleTimeString()
Returns the time as a String, with the format controlled by the browser and language.
valueOf()
Returns the value of the instance of the date object as an integer in millisenconds from Jan. 1, 1970.
getTime()
Returns an integer — the number of milliseconds since January 1, 1970, to the date specified by the instance of the Date object. I do not know how this differs from valueOf()
getFullYear()
Returns an integer representing the actual year for the date. Use this instead of getYear()
getUTCFullYear()
Returns the year for the date of the instance of the Date object in the UTC time stored internally by the browser. My guess is that this only differs from getFullYear when it comes to December 31 and January 1.
getMonth()
Returns the integer corresponding to the month value for the date specified by the instance of the Date object. Avoid logic errors: remember that arrays start with zero, so this returns an integer 0 - 11. January is 0 and December is 11.
getUTCMonth()
Returns the integer corresponding to the month value for the date specified by the instance of the Date object. Avoid logic errors: remember that arrays start with zero, so this returns an integer 0 - 11. January is 0 and December is 11. The difference between getMonth() and getUTCMonth is that the UTC time stored internally by the browser.
getDate()
Returns the day of the month, 1 - 31, specified by the instance of the Date object.
getUTCDate()
Similar to getDate(), for the UTC time stored internally by the browser.
getDay()
Returns an integer between 0 to 6, corresponding to the day value for the date specified by the instance of the Date object. Avoid logic errors: remember that arrays start with zero: Sunday is 0, Saturday is 6.
getUTCDay()
Returns an integer between 0 to 6, corresponding to the day value for the date specified by the instance of the Date object for the UTC time stored internally by the browser. Avoid logic errors: remember that arrays start with zero: Sunday is 0, Saturday is 6.
getHours()
Returns the integer, 0 - 23, for the hour of the day specified by the instance of the Date object, using the 24-hour time system.
getUTCHours()
Returns the integer, 0 - 23, for the hour of the day specified by the instance of the Date object, using the 24-hour time system.(the UTC time stored internally by the browser).
getMinutes()
getUTCMinutes()
Returns an integer, 0 - 59, representing the minute value for the hour specified by the instance of the Date object.

getSeconds()
getUTCSeconds()
Returns an integer, 0 - 59, the seconds past the last full minute as specified by the instance of the Date object.
getMilliseconds()
Returns an integer, 0 - 999, the milliseconds past the last full second as specified by the instance of the Date object.
getUTCMilliseconds()
Same as above, for the UTC time stored internally by the browser.
getTimezoneOffset()
Returns an integer betweeing -720 and 720 corresponging to minutes between your the site visitor’s computer and GMT. If your visitor is west of GMT, getTimezoneOffset() will return a positive values; negative values for east of GMT. Note: this returns the value in minutes — beware of logic errors!.
setTime(time)
Takes as a parameter an integer of milliseconds. Sets the date instance to the number of milliseconds from January 1, 1970. A negative integer will be before 1/1/70, a positive integer will return a date later than 1/1/70. Returns the milliseconds from 1/1/1970

setMilliseconds(ms)
setUTCMilliseconds(ms)
Takes as a parameter an integer of milliseconds. Sets the milliseconds of the date instance to the number of milliseconds from the current second. If the number is greater than 999, or less than 0, the rest of the time stamp will be effected: not just the millisecond count. It returns the milliseconds not of the parameter passed, but rather the milliseconds since 1/1/1970, midnight, GMT. The first example removes one year worth of milliseconds from the millenium date instance. The second example adds 1500 milliseconds, or 1.5 seconds. Do take a look at setUTCMilliseconds for an interesting tidbit… the “from the current second” above is quoted for a reason. You’ll note from the getMilliseconds() that this is indeed “from the last second”, and not simply an addition of milliseconds. In the test value for setMilliseconds(), the last four digits of the return value is 1500 - the milliseconds that were added. In the example for setUTCMilliseconds(), the number of milliseconds subtracted is subtracted from the seconds set above, not the milliseconds, as would seem logical

setSeconds(sec [, ms])
setUTCSeconds(sec [, ms])
Takes a required seconds as integer parameter and an optional milliseconds as integer parameter. If a float is passed as a parameter, a parseInt is automatically performed prior to setting the time. Returns the number of milliseconds from 1/1/70 GMT

setMinutes(minute [, sec, ms])
setUTCMinutes(minute [, sec, ms])
Takes a required parameter of seconds as an integer (performs the equivalent of Math.floor if the parameter is a float), and optional integer parameters of seconds and milliseconds. If you are going to define milliseconds, you must pass a seconds parameter. Returns the number of milliseconds from 1/1/70 GMT.

setHours(hour [, minute, sec, ms])
setUTCHours(hour [, minute, sec, ms])
Takes a required parameter of minutes as an integer (performs the equivalent of Math.floor() if the parameter is a float.), and optional integer parameters of minutes, seconds and milliseconds. If you are going to define milliseconds, you must pass minutes and seconds parameters. Returns the number of milliseconds from 1/1/70 GMT. The third example shows what happends when your integers are logic errors. The fourth example demonstrates that if a parameter is NaN, the function sets the date to NaN, and returns NaN

setDate(dateInt)
setUTCDate(date)
Sets the date of the month. The dateInt parameter should be in the form of an integer. If there is a logic error, such as 31 for June, the Date object calculates it and will return July 1. This sets the date, so your date object is changed. It also returns the new date in milliseconds. Note that in the third example, depending on your time zone, you may get the last day of last month.

setMonth(month [, date])
setUTCMonth(month [, date])
Sets the month, and, optionally, the day in the month. The month parameter should be in the form of an integer. Remember that the month array starts at O, so currTime.setMonth(2) will set the month to the third month, which is March. If there is a logic error, and your month int is not between 0 and 11, then the year will be set too.

setFullYear(year [, month, date])
setUTCFullYear(year [, month, date])
Sets the year, and, optionally, the month and the day in the month. The year parameter should be in the form of an integer. See quirks about the month in the setMonth() explanation. Note that the method reads “setFullYear(),” which is different then the setYear method. Since the difference is important to remember, I’ll compare the two in the examples. The setYear() adds 1900 years for any year between 0 and 100, whereas setFullYear() sets the year to whatever integer is passed.

toUTCString()
Taking no parameters, this method does not alter the date object: it simply returns the UTC value of the Date instance in standard string format: the day of the week abbreviated … well, look at the example. You’ll notice currTime has not been altered, and the return value is the same value, but presented in the UTC time zone rather than the user time zone. This method is for newer browsers than the toGMTString();, so it is recommended that you use this method over the GMT method below.

toGMTString()
Taking no parameters, this method does not alter the date object: it simply returns the value of the Date instance in standard string format. I saw no difference between the toUTCString() and toGMTString() methods.


getYear()
You don’t want to use this. Instead, use getFullYear(). Why? for years between 1900 and 1999, the getYear() method will return an integer between 0 and 99. This method does not alter the date instance. It takes no parameters. It returns an integer. Don’t use this method.

setYear(year)
Sets the year. The year parameter should be in the form of an integer. If (0<=year && year<100), setYear() adds 1900 to the year passed as the parameter. It is recommended to not use setYear(). Instead, opt for the setFullYear() method. Returns the new date instance value in milliseconds since 1/1/1970.

Notes:

  • getFullYear() and getYear() are NOT the same. getFullYear() is the actual year. getYear() is years since 1900.
 
 

CSS & Javascript Character Entity Calculator August 25, 2007

Filed under: CSS (including hacks), Character Entities, JavaScript, Web Development — Estelle Weyl @ 10:38 am

Javascript and CSS Entity Conversion Calculator

Enter your HTML Entity Character number (such as &#2335 or just 2335 - ट) to get the CSS and JS values for that entity. Explanations on how to use the results are below.







(open in new window). named entities | numeric entities | 2,636 entities

Example of JavaScript Charater Entities and the DOM

Example Code (This is the code for the dynamically generated content in the button above).
var calc = document.getElementById("calculator");
var theButton = calc.getElementsByTagName(’button’)[0];
var buttonOptions = ['\u03a0\u03a1\u0395\u03a3\u03a3', '\u2660\u2663\u2665\u2666', '\u221a'];
var rand = Math.floor(Math.random()*buttonOptions.length);
var buttonText = document.createTextNode(buttonOptions[rand]);
var z = theButton.appendChild(buttonText);

The Explanation:
Line 1: gets the div containing the button.
Line 2: gets the button as an elementNode
Line 3: creates an array of strings that are made up of encoded entities. The could also read var buttonOptions = ['� ΡΕΣΣ', '� ♣♥♦', '√'];
Line 4: Creates a random number; in this case either 0, 1 or 2, since there are 3 elements in our array.
Line 5: creates a text node containing the string of javascript character entities.
Line 6: Appends the textNode created in line 5 to the elementNode targeted by line 2. We also create the variable z as a reference to the button’s textNode. I can then use that reference replaceChild() method.

Including Character Entities in JavaScript and CSS

The processes for including special characters in JavaScript and CSS are very similar:

  1. hex encode the numeric HTML entity value.
  2. Preced the hex-value with a slash "\" in CSS and a slash+U "\u" for JavaScript.
  3. Include your entity in your code/markup.

Javascript Character Entities

alert('M\u00E9nage \u00E0 trois.') Try it

CSS Character Entities

    #heart {list-style-type:none;}
    #heart li:before {content:'\2665 '; color:#FF33FF; padding-right:1em;}
  • In all but IE, this will be preceded by a heart

Notes:

  • Don’t know the numeric value of the entity you want to include? named entities in alphabetical order which may be a good place to start. Find the entity you are looking for there by appearance, then do a search for the numeric entity on the Named Entities in Numeric Order page. Or, you can simply search the first 5800 character Entities. At some point I’ll add the rest of ‘em.
  • Remember that IE doesn’t understand the :before pseudoclass with content, and you would have to set the list-style-type as none, or you would get 2 bullets in CSS compliant browsers.
  • In javascript you can also use octal values instead of hexadecimal values for the first 255 or so characters. Yup, that’s trivia!

Including Entities without Encoding them

The reason I always use encoded entities is because I have no clue how to use my keyboard to get the right letters. It’s faster for me to look up the letter from Named Entities in Numeric Order then it is for me to look up the keyboard sequence to display the same character. For the following sample, I pulled up the "character map" that came with my OS.
You can include odd characters if you correctly set your content-Type to UTF-8.
That is the setting for this page, which allows for the following code without HTML or JS encoding.

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

alert('Ế ế ∑ ở Ẅ ۹'); Try it

The question is, short of editing your .htaccess character set, how do you tell your external scripts to be served up in UTF-8? This is external and doesn’t work. I tried <script type="text/javascript" src="/articles/entitycalculator.js" charset="utf-8"></script>, but it doesn’t work.

 
 

JavaScript Date Object July 29, 2007

Filed under: JavaScript, PHP, Web Development — Estelle Weyl @ 11:18 am

Javascript: Things you should know

Note: This is part IV of a "Javascript: Things you should know" series. I assume readers have an understanding of the core language. This section goes over the creation of date objects. Most resources go over creating a current time date object. This goes over the rest. The previous entry was JavaScript Objects. The next entry list all the date object methods. Please let me know what you think and it there is anything I am missing. Enjoy.

Creating JavaScript Date Objects:

There are fours ways of instantiating a date object:

  1. Without parameters
    Returns the users current date based on client computer’s clock.

    new Date();

    Example:
    var currentTime = new Date();

  2. With a numeric parameter:
    Returns the date measured from midnight January 1, 1970 (+/- GMT diff) plus the time in milliseconds that was passed as the parameter

    new Date(milliseconds);

    Examples:
    var startTime = new Date(0); // Returns
    your time when GMT hit the new year.
    var millenium = new Date ((365*30 + 7)*24*60*60*1000); // returns the millenium at GMT, The +7 is for the leap days.

  3. With a string parameter:
    The string parameter must be a date correctly formatted in string format. The Date object only seems to accept 1 date string format, which is provided in the examples below. The flexibility is only in the day: the number may include a leading zero, but it is not required.

    new Date(dateString)

    Examples:
    var auntsBirthday = new Date("September 4, 1902") // She’s 105
    var modifiedTime = new Date("July 27, 2005 12:22:00") // format must be exact

  4. With an array of parameters:
    Pass the different date element parameters in the order above. If you don’t specify all the parameters, or a parameter is non-numeric, 0 is passed. If your value is numeric, but not a valid value (such as hours == 25) no error will be thrown, though it may be a logic error. The most common error is the month parameter: remember that the arrays start at index of 0, so January is 0 and December is 11.

    new Date(year, month, day, hours, minutes, seconds, milliseconds)

    var modifiedTime = new Date(2007,7,27)
    var modifiedTime = new Date(2007,7,27,13,22,0)

Here are a few examples and what gets returned (javascript must be enabled):

  • currentTime = new Date()
  • timeBasis = new Date(0)
  • lastYear= new Date(-365*24*60*60*1000)

  • var currentTime = new Date("November 4, 2008");

  • anniversary = new Date(2003,8,21)
  • exactTime = new Date(1969,0,3,16,4,12,500)

Note:

  • new Date(0) will not return midnight of January first unless your computer set to GMT.

Common JavaScript Date Object Errors

  • new date()
    //Error: Date is case sensitive
  • new Date("412")
    //
    Error: No data conversion
  • new Date("June 31, 2005 29:95:73 ")
    //Logic Error: Too many hours in your day, and there are only 30 days in June.
    Returns July 2, 2005; which is unlikely your intention.
  • new Date("July 27, 2005 12:22pm")
    // invalid date error - doesn’t understand PM
  • new Date("2007-7-27")
    //Invalid Date: - string in wrong format**
  • new Date(1969,12,3,16,4)
    //Returns January 3, 1970 instead of December 3, 1969. Logic Error: monthArray is 0 - 11.

Notes:

  • When passing the month as a number, remember that the array starts at 0. Optional values are 0-11. Javascript will not throw an error, but there will be a logic error.
  • The date string must be of the correct fomat. The minimum is "Month dd, yyyy", to "Month dd, yyyy hh:mm:ss". The Month doesn’t seem to be case sensitive in my tests, but I haven’t checked all browsers. Good coding practices dictate that it should be capitalized. .
  • JavaScript uses the date of midnight, January 1, 1970 UTC as a starting point for all of its calculations.

An Example of Converting a PHP/Unix date to a usable JavaScript date:

So my quandry was that the date I received was written in an unusable format: The date the server sent was similar to 2007-07-22T22:57:35Z - yyyy-mm-ddThh:mm:ssZ, which is the date in ISO 8601 format (see converting ISO 8601 dates in PHP for a completely different take on conversion). I had to convert an ISO 8601 date to a parameter I could use in the Date object constructor

My first thought was to replace the T and Z with spaces, 2007-07-22 22:57:35 , which looks correct, but isn’t.
As we learned above (see Date error example above), date strings much be in the "Month dd, yyyy" format. The yyyy-mm-dd format will not work.

var myStringDate = "2007-07-22T22:57:35Z";
var myStringDate = new Date(myStringDate.replace(/\D/g, " ")) //returns "invalid date".

My second thought was to split the string into parameters.

var myStringDate = "2007-07-22T22:57:35Z";
var myStringDate = myStringDate.replace(/\D/g, " ");
var dObj = myStringDate.split(" ");
          //array is (2007, 07, 22, 22, 57, 35)
var myDate = new Date(dObj[0], dObj[1], dObj[2],
           dObj[3], dObj[4], dObj[5]);

That works, but gives me the wrong date. We have a logic error. The month array starts at 0. month[07] is August, not July. The solution was to subtract 1 from the 2nd parameter

var myStringDate = "2007-07-22T22:57:35Z";
var myStringDate = myStringDate.replace(/\D/g, " ");
var dObj = myStringDate.split(" ");
var myDate = new Date(dObj[0], (dObj[1]-1), dObj[2], dObj[3], dObj[4], dObj[5]);
document.write("Making a date from a string: " + myDate);



Writing Pretty Dates

Javascript 1.2 gave us some prettier ways of writing out dates. Still, you might not find the format you need with the methods provided. Here are some arrays that you should feel free to cut and paste into your code.

dyOfWeek = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
daysOfWeek = new Array("Sunday", "Monday", "Tuesday", "Wednesday",
             "Thursday", "Friday", "Saturday");
monOfYear = new Array("Jan.", "Feb.", "Mar.", "Apr.", "May", "Jun.",
             "Jul.", "Aug.", "Sep.", "Oct.", "Nov.", "Dec.");
monthsOfYear = new Array("January", "February", "March", "April", "May",
    "June", "July", "August", "September", "October", "November", "December"); 

toLocaleDateString() works for much of what I need. But, sometimes you need something a little different. You can either edit using regular expressions, or you can create a pretty date from scratch.

Here are some formats and how to create them. I will use the date we created, the methods described above and the 4 arrays posted here.

(myTime.getMonth() + 1) + "/" + myTime.getDate() + "/" + myTime.getFullYear()
var hours =  myTime.getHours();
var ampm = (hours > 11)? "PM" : "AM";
hours = hours%12;
hours = (hours == 0)? 12 : hours;
time = hours + ":" + myTime.getMinutes() + " " + ampm;
July 2007
monthsOfYear[myTime.getMonth()] + " " + myTime.getFullYear()

Formatting Javascript Dates:

Want to extend the Date object to be nicely formated? Gavin Kistner did the work for us. Extending the Date Object which creates the a custormFormat for the date object. To use this prototype, include the function in your javascript, and call it this way:

var prettyDate = myDate.customFormat('#DDDD#, #MMM# #D#, #YYYY#');
var prettyTime = myDate.customFormat('#h#:#mm##ampm#');

Here’s the code:

Date.prototype.customFormat=function(formatString){ 
    var YYYY,YY,MMMM,MMM,MM,M,DDDD,DDD,DD,D,hhh,hh,h,mm,m,ss,s,ampm,dMod,th;
    YY = ((YYYY=this.getFullYear())+"").substr(2,2);
    MM = (M=this.getMonth()+1)<10?('0'+M):M;
    MMM = (MMMM=["January","February","March","April","May","June","July","August","September","October","November","December"][M-1]).substr(0,3);
    DD = (D=this.getDate())<10?(’0′+D):D;
    DDD = (DDDD=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"][this.getDay()]).substr(0,3);
    th=(D>=10&&D<=20)?’th’:((dMod=D%10)==1)?’st’:(dMod==2)?’nd’:(dMod==3)?’rd’:'th’;
    formatString = formatString.replace("#YYYY#",YYYY).replace("#YY#",YY).replace("#MMMM#",MMMM).replace("#MMM#",MMM).replace("#MM#",MM).replace("#M#",M).replace("#DDDD#",DDDD).replace("#DDD#",DDD).replace("#DD#",DD).replace("#D#",D).replace("#th#",th);
     h=(hhh=this.getHours());
    if (h==0) h=24;
    if (h>12) h-=12;
    hh = h<10?(’0′+h):h;
    ampm=hhh<12?’am’:'pm’;
    mm=(m=this.getMinutes())<10?(’0′+m):m;
    ss=(s=this.getSeconds())<10?(’0′+s):s;
    return formatString.replace("#hhh#",hhh).replace("#hh#",hh).replace("#h#",h).replace("#mm#",mm).replace("#m#",m).replace("#ss#",ss).replace("#s#",s).replace("#ampm#",ampm);
	 }