CSS, JavaScript and XHTML Explained

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

 

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:

 
 

3 browser testing tools you can’t live without December 1, 2008

Filed under: Browsers, IE7, Web Development, firebug — Estelle Weyl @ 9:16 am

Firefox 2 and Firefox 3 don’t render the same. Also, Firebug 1.0 is less buggy than Firebug 1.2. So, at this point, it really is necessary to run multiple versions of Firefox in your development environment, similar to how most of us have been running IE6 and IE7 on the same machine for years.  What? You haven’t been running IE6 and IE7 on the same machine? Didn’t know it was possible? Here are three tools or links that you need to check out if you do any cross browser testing (which I hope you do).

Here are some links to help you out:

  • Multiple Firefox: I have both FF2 and FF3 installed on my laptop. I develop in FF2 with Firebug 1.0, and have FF3 with FB1.2 for testing. Instructions for running multiple Firefox apps on the same box can be found here: http://jeroencoumans.nl/journal/multiple-firefox-versions.
  • IE6 on Mac: I have a mac, so for quick IE6 checks I have IE6 installed in my Mac OSX. This isn’t a perfect rendition of IE6, but it’s good enough for quick tests, not final QA. To install IE6 on your mac, go to http://www.kronenberg.org/ies4osx/
  • Multiple IEs: To install IE7 and IE6 on your PC, or in your Parallels or VMWare Windows environment on your mac, you must install IE7 as your main IE application, and then you can go to http://tredosoft.com/Multiple_IE to install earlier versions - IE6, and even earlier.It does not support IE7, which is why IE7 (or IE8) needs to be a regular installation.

Unfortunately there are a few quirks with running MultipleIE and IE6 on Mac- but I would say MultipleIE matches the crappiness of IE6 at about 99.9%.

These are links that I am always forwarding to people, so I figured I would finally blog them. Cheers!

-Estelle Weyl

 
 

My Experience with Scott La Plant, Apptastik

This post is about my awful experience with Scott La Plant of Apptastik, on the ContactApp application. While I prefer this blog to be only about web technology implementation, I fear I must stray from the implementation perspective for one post and focus on a web technology personnel warning. Unfortunately, I feel it is my duty to inform and warn the web technology world about Scott La Plant, Apptast!k, LLC. (other Apptastik projects include CalendarApp, InvoiceApp, LettersApp and GreatCareersHere).

I worked with Scott La Plant on the CSS for ContactApp, a 37signals Highrise knock-off for a little under a week. My role was to create CSS that worked in grade-a browsers on Mac and PC. Which is exactly what I did. While I was actively working on the project, Scott La Plant made himself very available: he was always online, provided quick feedback, and was fairly easy to work with. He gave me positive feedback, and was impressed at the speed I made edits he suggested. However, once he was in receipt of the completed files, Scott La Plant became difficult to reach, put himself on stealth mode on IM, and, when he did communicate he was abusive, irate and irrational.

When he told me that he wanted to go in a different direction I was more than happy to terminate the working relationship with what I considered to be a bi-polar creep.  I maintained my professionalism, let him know how much he owed, and wished him well. Although he is currently using the CSS I wrote and the images I created, he has refused to pay me. He continues to refuse to pay, continues to be controlling, continues to use my work without payment, and has repeatedly threatened legal action against me. Therefore, I must tell the story.

It isn’t to say that all freelancing projects run perfectly, but Scott La Plant having issues with a contractors, especially female ones, seems to be the norm, not an isolated incident. To hopefully ensure that no one else has to endure what Uma, Rosy R., Ruchita, Nayana, and others have had to go thru with this individual, I am telling my story in full. It’s long and boring, so you don’t have to read any further. However, if you are considering working with Scott La Plant, or are thinking of purchasing or subscribing to any of his applications, including InvoiceApp, ContactApp, LettersApp, CalendarApp or GreatCareersHere, read the rest. When full names have been used in quotes, I have obfuscated the names of those involved.

The Introduction

On Labor day I received an email from a woman I know professionally, “I have a guy I know that needs some help with CSS… are you up for that? As in, he needs to hire you to fix whatever it is that he’s building.”

I connected with the client, a Mr. Scott La Plant, later that day. In his email he wrote “I believe we have a mutual friend in XXX , who I affectionately refer to as “X”. While I usually vet potential clients before working with them,  since this was a friend of a friend (or so I thought since he told me he had a pet name for her), I wanted to help out.

Scott La Plant sent me a zip file with 5 html files of pages. The contactApp files turned out to be a knock-off of the 37signals Highrise application. Having never used Highrise, I didn’t realize that this was an attempt at reverse engineering the site. Had I been familiar with Highrise, it would have been obvious that I should not have accepted such a project. I don’t intentionally work on stolen or copied work.

Today I signed up for a highrise account to write this post. With 20/20 hind-sight, the only apparent difference between the ContactApp application is the color scheme, name and logo.

ContactApp and Highrise compared

Something seems fishy with this ScottLaPlant

I started having my first reservations about working with Scott La Plant when we discussed pay,. Most small business owners try to negotiate pay rates. Scott La Plant didn’t. When Scott La Plant didn’t react I began wondering if he was a shyster: was he not negotiating since he wasn’t going to pay me? I did a Google search for “Scott La Plant” and found Scott La PlantScott La Plant, Ebay, Hardwarecomputer_user ripoff Dishonest racist seller on ebay sold me a computer many items were missing and lied about shipping costs. Rockford Michigan on Ripoff Report. My thought was that this was a different Scott La Plant, since the one in the article lived in Michigan.

This guy seemed overly nice: a little fishy. I should have gone with my gut reaction. Instead, I coded furiously over the next few days to get the site to him earlier than I had suggested.

Scott La Plant told me he was a programmer and insinuated that he did the work himself. He stated that in this project he had been preserving class names and ID’s, would be fixing some permission, etc. I presented my suggested timeframe based on the assumption that he knew how to code. When people know what that are doing, they can easily change border widths, font colors, etc. I presented a suggested timeframe based on getting the CSS working on the 5 pages from the zip (it was 7 in the end) — I would get the CSS working for the pages submitted to me in about a week, and would tweak anything that needed to be changed when the application was more complete.

The application I was given was not complete: I only received a few pages. I completed those pages, and told Scott La Plant I would complete the CSS for the new pages after they were developed. Makes sense?

Scott La Plant shows his darker side

I sent Scott La Plant the files repeatedly while I was working on the project. He had some edits. I made them. The work was 90% done. Everything seemed fine. I went to bed. I woke up to an email stating “wtf”: the issues included a button being floated left instead of right, and 5 other quick fixes, and I fixed them quickly. I sent him the revised files.

But something seemed off. He put me on stealth mode on his instant messenger for about 12 hours, responding at 9:00 pm that he had been sleeping. During the day, as I was waiting for feedback on whether he had enough CSS complete to continue on creating the back end, I did a google search and found more information. I found  Scott La Plant, Imedia Technology Ripoff, Racist, Liar, Thief Elizabethtown Pennsylvania and a bunch of oDesk job requisitions, including one for CSS help for a week before he contacted me, to which I assume the tweet “hates it when he hires someone to fix something, and it breaks, and then they charge you to fix what you hired them to do in 1st place. huh?” is in reference, and one posted that day for a CSS person to finish up the application I was currently working on. I also found out  that he used to live in Michigan, so the eBay RipOff report above was indeed about him.

During our evening conversation, Scott La Plant stated he wanted the CSS for the entire application to be complete. We discussed that it was not possible, or in his financial best interest, to pixel perfect code before the application at least had all the pages complete. He stated he understood, and put me on stealth mode from that point on. He was supposed to create the back end, and I was going to complete the CSS when the pages were available online. Looking back, I don’t understand how he expected me to pixel perfect pages when I didn’t have a design or code to work from.

Two days later Scott La Plant asked me if I wanted to work on InvoiceApp with him, and we could split earnings. I declined. He then asked me a CSS question, and I explained how to resolve the issue. As the CSS was now in his hands, and we did not have version control set up, he had to make the edits. I couldn’t. Otherwise there would have been code conflicts or overwrites.

He told me he was going to dinner, and we would review some more issues when he returned. He was on stealth mode on instant messenger, so I had to wait for him to initiate conversations. Three hours later I received an irate email, “I’m going another direction at this point because honestly, I’m tired of waiting.”

I didn’t really know what he was waiting for: I had completed all the files he had sent me, with commented out instructions in any area where the CSS might be confusing and in the HTML where any changes to the code needed to be made. Truthfully, I was glad to have an out of this relationship with a seemingly bi-polar client.  During the 6 days I had worked on the project I led Scott La Plant by the hand in explaining what I was doing, how he needed to implement the code, what he should expect, and gave details in the code as to how to implement and HTML changes. Now that he had all the files he had asked me to work on, the files we had worked on together and he had reviewed, he was demanding a new set of files — ones I did not have. I remained professional, wished him luck, and informed him how much he owed.

He responded with:

As for your invoice, I received it… Just because you sent it to me so expeditiously doesn’t mean I’ll pay it immediately. I’ll pay as much attention to that invvoice as you did to my pleas about my need for this project being done quickly. Remember, I hired you to deal with the css so I could focus on other things. If you needed access, it would have been provided but, it was pretty much made clear to me you weren’t interested and I don’t make it a habit of begging. I hire, I set expectations and I either have them met or I don’t…. I don’t waste time dicking about or arguing about this/that or the other thing. And I didn’t get what I was paying for. As for the invoice, I need a detailed, broken down invoice.”

He deleted my Paypal invoice.

I sent him a detailed invoice several days later when I was doing my billing. He quickly responded with “I figured I’d wait to see what other ignorant comments you want to tweet before I again cancel this invoice. I’m referring all further inquiries to my attorney on this matter. His name is YYY and his email address is ted@YYY.com. Direct all future correspondence to him please.” And, he deleted another PayPal invoice.

To be fair, I did make one comment about ScottLaPlant on twitter: “The chances of Scott La Plant paying me for the work I did on Apptastik are about the same as Sarah Palin getting into Mensa.” That was the only comment about him that I tweeted, which you can see it if you follow me on Twitter.

I corresponded with his attorney. His attorney stated “the work requested by Mr. LaPlant was not completed by the agreed upon deadline and, after the deadline past, the work received by Mr. LaPlant was so incomplete as to be unusable.” (Unusable? He’s currently using it! It’s live on the ContactApp website!)

I responded with:

“Scott La Plant agreed to an hourly rate. Although there was no contractually agreed upon completion date, the work was performed and delivered to Mr. La Plant earlier than estimated during correspondence on September 2, 2008. Mr. La Plant provided feedback on work performed throughout the time I was working on the project, confirming that work was actually performed, not “allegedly performed”. In addition, when seeking another independent contractor, Mr. La Plant advertised the project as being “90% complete” and just needing “finishing touches.” Since it appears from your email below, that you only discussed the situation with Mr. La Plant and have not yet had an opportunity to view written correspondence involved, I can supply written correspondence which corroborate all of which I have stated above.

Due the fact that the agreement was based on an hourly rate alone, payment is due. In addition, since the work was provided in a more than timely manner, feedback was given on the work, changes were made based on the feedback, and all this was all before the estimated completion time, had this been a fixed rate instead of hourly project, payment would be due.”

Scott La Plant’s attorney did not ask for corroborating evidence, but did send another email stating that he Mr. LaPlant was clear that the requested work needed to be completed, in full, by a specific deadline, that the specified deadline was a material aspect of the agreement, that “despite multiple communications, the work was not completed by the agreed deadline and the work provided was substantially incomplete”, and that “Mr. LaPlant was forced to hire another independent contractor to perform the work” at a cost of $1,300. His attorney stated that they had no evidence other than [my] statements that would contradict the above.”

So, I provided transcripts of the conversations between Scott La Plant and myself contradicting every statement made by Scott La Plant’s attorney on his behalf.

No specific timeline was set:

Me: “When do you want this by. When do you need it by (sometimes those are 2 different things) and what do you need first.”

Scott: “well, what is a realistic time-frame for you?”

Me: “I hope to have it done by Sunday”

Scott: “No worries”.

I made Scott La Plant aware of my progress on the project on an ongoing basis. I provided Scott La Plant with updated files, with a link to see the progress live on the Internet, and provided Scott La Plant with written updates on a regular basis. Work was completed to the agreed up level as set forth in communication between myself and Scott La Plant by the roughly estimated date of Sunday

I had informed Mr. LaPlant that the back end needed to be coded before completion of the CSS would be possible, so provided transcripts. The correct order of developing web site is to first develop the content, or HTML layer and then develop the presentation, or CSS, layer. Since the content layer was not 100% complete, tweaks would have to be made after completion. Mr. LaPlant and I discussed this. On September 7, 2008, we had an additional conversation about this fact, the work and the timeline:

Me: “it makes more sense to get it 90% there…. code, and then fix up the last 10%”, (with code being a reference to the content layer which Mr. LaPlant was still working on.

Scott: “Yes, it does. honestly, it does :) “

Mr. LaPlant provided positive feedback on progress thru the the morning of September 6, 2008:

Scott: holy crap

Me: what?

Scott: you’re like…. fast

Scott: or I’m terribly inefficient

Scott: probably both

Scott: I’m usually open with all im clients on adium unless I’m just in “do not bother mode” for coding etc.. or a poor mood which I have been in for a few days. think lack of sleep is getting to me

Scott La Plant: pagination looks good. not as harsh. nice choice on colors

Me: ty

Me: the add buttons? the hover?

Scott: yep, looks good, ty

Me: subtle enough?

Scott: very much.. again, nice touch

Scott: on this page: http://url.com/contact.htm did you remove the style you had for the names being centered against the image (top of it)?

Me: on the tasks page there is a very, very subtle double line between the sections, that was intentioanl

Scott: I did notice that

Me: ah, must have overwritten it last night…

Me: when i was doing the other page…. need to fix

Scott: np

Scott: as for the double line on tasks and the subleness of it. again, I’d just stick with it. Looks very good. again, nice touch

Scott: on this page: http://url.com/contact.htm — the line seperating each contact…. what do you think about maybe making the divider line a little softer? what are your thoughts?

Me: if you notice down on the left of tasks there is the delete

Scott: yep, caught it

Me: the instructions are in the css on how to make it work

Scott : very clear instructions too :)

Me: oh, good

The conversation above is from September 6, 2008. Scott LaPlant was pleased with my work on his project, was getting updates, was providing feedback, and was able to view progress being made on the Internet. At no time did he tell me that he was not satisfied with the speed of work. Only once he was in possession of my files to the agreed upon level of completion did he complain.

On September 7, less than a week after initial contact, Mr. La Plant was in possession of the agreed upon files, that were “90% complete”. The agreement was that the server produced code needed to be in a more complete state prior to continuing any CSS work.

In hiring an independent contractor to complete the work, Mr LaPlant stated in his announcement of September 13, 2008, that the work was 90% complete. I attached the advertisement seeking a CSS contractor that ScottLaPlant placed at oDesk. Mr. La Plant advertised the project as being “90% complete” and just needing “finishing touches”

The live version of ContactApp is currently using the images and the CSS produced by me. I informed his attorney that am in possession of the original files sent to me, the CSS and images provided to him by me, and a copy of the CSS — which includes the CSS I marked up — currently in use on his server.

Scott La Plant agreed to an hourly rate. Although there was no contractually agreed upon completion date, the work was performed and delivered to Mr. La Plant earlier than estimated. Mr. La Plant provided feedback on work performed throughout the time I was working on the project, confirming that work was actually performed, not “allegedly performed”. I informed the attorney that due the fact that the agreement was based on an hourly rate, payment was due on this basis. Since the work was provided in a more than timely manner, feedback was given on the work, changes were made based on the feedback, and all this was all before the estimated completion time, had this been a fixed rate instead of hourly project, payment would have been due. In addition, Scott LaPlant is currently using the code and images created by me under the agreement, so payment was due.

I asked Scott La Plant’s attorney to provide the specifics of his statement, “Mr. LaPlant was clear that the requested work needed to be completed, in full, by a specific deadline,” to provide me with material proof that I was made aware of any alleged “specific deadline”, and to provide an explanation as to how it could be concluded that “the specified deadline was a material aspect of the agreement.” I also asked for communications demonstrating that the work was not completed by the agreed deadline and demonstrating that the work provided was “substantially” incomplete, how his perceived timeline was not met and contact information for an independent contractor that was allegedly hired and allegedly paid $1,300 — because looking online it seems that Scott La Plant has a tendency to not pay his contractors: I am not his first victim.

The attorney did not respond. Instead I received a response from Scott La Plant stating that he wont be paying me, that he was hoping to “we’d be able to be reasonable and deal in an amicable fashion” - how is not paying me amicable? How were his emails to me either reasonable or amicable? He instructed his attorney to “not accept further correspondence with [me]“, and told me that I should have my counsel contact him. My take is that since he doesn’t have anything stating his perceived deadline (to this date, I don’t know what his perceived timeline was), since he likely doesn’t have proof of having paid Joseph M, or anyone else $1,300 for CSS work, and he has no proof that the work was substantially incomplete (since he’s using it and it seems to work well, there goes that claim), his attorney likely told him to pay me, which is not what he wanted to hear. So, he told his attorney not to respond and decided to continue being ornery

Since his attorney was told not accept any additional correspondence from me, the amount of money being discussed in definitely small claims, and, at least in CA, you can’t have an attorney present in small claims court, there is no reason for me to hire an attorney. I have transcripts of the communications that occurred between Scott La Plant and myself. I provided proof showing the accuracy of my clais. Scott La Plant provided no proof for his unsubstantiated arguments for, as far as I can tell from re-reading all correspondence and transcripts, he had no proof to substantiate what he told his attorney.

There was an introductory email, and then two emails from his attorney to me, and two emails from myself to the attorney in response to his emails, before Scott La Plant terminated direct conversation between myself and the attorney

I sent Scott La Plant a final payment request, with the statement:

“I would hate to have to publicize the facts our interaction. If I don’t receive payment, I have no other option: I will have an obligation to inform other people of your failure to make payment on your obligations. Please pay in full. Thank you.”

He responded,

Please have your legal counsel contact either myself or my attorney, YYY. Just an fyi, I have attempted on numerous occasions, thru my attorney attempt to resolve this disagreement, to no avail.

Seeing how you want to attempt some sort of blackmail and threaten to disparage me, my intention is to pursue this legally. I would suggest you get an attorney if you’ve not done so already.

Please have your attorney contact mine so we can get on with this. Make no mistake, I have no intention of paying you. I was pretty clear in my instructions and you want payment?

It’s funny how people fuck stuff up, disgregard instructions, deadlines yet, seem to demand payment for things that didn’t get completed. So, post your diatribe and be prepared to spend out the ass - I am!

So, as promised, I have followed thru on my obligation to inform other people of his failure to make payment.

Additional Information

In the first section I mentioned InvoiceApp, ContactApp, LettersApp, and GreatCareersHere:

I have never seen CalendarApp, so cannot confirm that is a copy of 37 Signals’ Calendar Application.

Perhaps he had permission to use the CSS and reverse engineer these applications. If you plan on purchasing any of these applications, I would recommend doing your homework on whether permission was granted and whether contractors were paid.

Note: This is the Scott La Plant or Scott LaPlant, a.k.a ScottLaPlant, who currently resides near Elizabethtown, PA, formerly from Michigan. Sorry to others with the same name sake.

 
 

XHTML Elements, their parent, children, attributes and default browser presentation November 21, 2008

Filed under: Browsers, DTD, HTML, Web Development — Estelle Weyl @ 12:12 am

XHTML Elements, their meaning, semantics and attributes
<ELEMENT> Element Name Block, Inline, etc. Element’s Parents Element’s Children 3 Browser Presentation

Attributes1

Comments
Elements occuring outside the body element
<!DOCTYPE> Document Type Declaration Not Displayed first line none -   Required. Should be first in the document
<html> html   root element <head> and <body> - xmlns Required
<head> document head Not Displayed <html> <base>, <link>, <meta>, <style>, <script>, <title> other than the title, all the other child elements are not visible to user profile, id, dir, lang. NOT class, style, title Required
<base /> url base for links Not Displayed <head> Empty3 - href, no standard attributes1  
<link /> link Not Displayed <head> Empty3 - href, charset, hreflang, type, rel, rev, media  
<meta /> meta Not Displayed <head> Empty3 - content, name or http-equiv, scheme  
<style> style Not Displayed <head> text - type, media  
<script> script Not Displayed <head> (allowed in <body> too. text or src attribute, not both - type, charset, src, defer do NOT self close with slash. Use end tag
<title> document title   <head> text only seen in the chrome of browser id, dir, lang. NOT class, style, title Required
Elements Occuring in the <body>
<body> document body block <html> Block3   all non-core attributes are deprecated Required
<a> Anchor inline inline or semantic block Text and inline3 except <a> underlined and colored href, hreflang, rel, charset, type, name, rel, rev, shape (rect), coords cannot contain other <a> children

<abbr>

Abbreviation inline inline or semantic block only text / inline3 dotted underline with cursor, tooltip title  
<acronym> acronym inline inline or semantic block only text / inline3 dotted underline with cursor, tooltip title  
<address> address blocktext <blockquote>, <div>, <body>, <form> inline3 elements, <p> italic, block -  
<area /> image map area Not Displayed <map> Empty3 makes hot areas on image alt, shape, coords, href, nohref ‘rect’ is default shape if omitted
<bdo> bi-directional override inline inline or semantic block only text / inline3 reversed text dir, lang  
<blockquote> long quote blocktext   block3 margin: 1em 40px; cite  

<br />

break return or forced line break inline   none line-break does not take internationalizaion attributes use as linebreak in poetry or addresses, not to separate paragraphs.
<button> push button inline   any inline3, except form elements and <a> push button disabled, name, type 2, value, accesskey, tabindex Cannot contain <input>, <select>, <textarea>, <label>, <button>, <form>, <fieldset>, <iframe> or <isindex> as children.
<caption> caption   <table> text and inline3 centered above table - must be first child of the table
<cite> citation inline phrase element text and inline 3 italicized text - -
<code> code inline phrase element text and inline 3 monospace font - -
<col /> column Not Displayed <table> Empty3 - char, charoff, span align & valign allowed, but use CSS instead
<colgroup> column group Not Displayed <table> zero or more <col>   span, char, charoff. align & valign allowed, but use CSS instead while empty, close with an ending </colgroup> tag.
<dd> definition description block <dl> Flow3 indented with a left margin - -
<del> delete inline or block inline or block Flow3 strikethrough cite, datetime don’t put block content in a <del> that is inline

<dfn>

definition inline phrase element only text italic - -
<div> generic block element block   Flow3 - - -
<dl> definition list lists (block)   one or more <dd> and <dt> only - - -
<dt> definition term block <dl> text and inline3 only - - cannot have block elements as children!
<em> emphasized text inline phrase element text and inline3 only italics - -
<fieldset> field set block <form> <legend>, Flow 3 box around child elements with legend, if any - -
<form> form Block block element block elements and block form elements - action, method, enctype, accept, accept-charset cannot nest a <form> within a <form>
<h1-6> headers heading (block) body or block inline and text varying font sizes and bold - -
<hr /> horizontal rule blocktext (block) body or block Empty horizontal line - -
<iframe> internal frame         longdesc,
name,
src,
frameborder,
marginwidth,
marginheight,
scrolling,
align,
height,
width
 
<img /> image inline inline or semantic block Empty The image identified in the src src, alt, longdesc, usemap, ismap height and width are optional attributes best omitted.
<input /> input inline inside a semantic block located in <form> Empty depends on type type, name, value, check, disabled, readonly, size, maxlength, src, alt, usemap, accept type defaults to text if not declared, but you should declare it
<ins> Insert inline or surrounding blocks   Flow underlined cite, datetime don’t put block content in a <del> that is inline
<kbd> keyboard inline phrase element text (and inline) monospace font - should really just be text
<label> label inline semantic block within a <form> text and inline - for, accesskey cannot contain child <label> elements
<legend> caption for fieldset   <fieldset> inline and text top left section of the fieldset box -  
<li> list item block <ul> or <ol> Flow bulleted new line -  
<map> image map Not Displayed   one or more <area> OR block - ID, name  
<object> object     <param>, if included, should come first. Flow   declare, classid, codebase, date, type, codetype, archive, standby, usemap, name, tabindex allowed in <head> by spec. height and width are optional attributes best omitted.

<ol>

ordered list lists (block) block one or more <li> elements indented <li>s with numeric bullets -  
<optgroup> option group   <select> one or more <option> bold, non-selectable header for a group of indented options. label, disabled  
<option> option   <select>, or within <optgroup> textnode appears within the select drop down as new row selected, disabled, label, value if value is omitted, submitted value is the text node value
<p> paragraph block block inline and text new line of text - -
<param /> parameter invisible <object> none not visible, though may cause visual effects id, name, value, valuetype, type can place params as name/value pairs in the object element
<pre> preformatted text blocktext (block)   inline, except <img>, <object>, <sub> & <sup> monospace font and nowrap whitespace - Cannot contain <img>, <object>, <sub>, or <sup> elements
<q> inline quotation inline inline or semantic block inline and text quotes at start and end of content cite (URL) quote style depends on language. Poor browser support of quotes
<samp> sample computer code inline phrase element inline monospace font - -
<select> option selector inline inline or semantic block within <form> one or more <option> required, optional <optgroup> drop down list name, size, multiple, disabled, tabindex  
<span> span (generic non-semantic container) inline inline or semantic block text or inline - -  
<strong> strong emphasized text inline phrase element text or inline bolder text - don’t use in <h1-6> as those are already emphasized
<sub> subscript inline inline or semantic block text or inline smaller, subscripted text - do not include in <pre>
<sup> superscript inline inline or semantic block text or inline smaller, superscript text - cannot be a child of <pre>
<table> data table block block or body <caption>?, (<col>*|<colgroup>*), <thead>?, <tfoot>?, (<tbody>+|<tr>+)) 4 data table summary (width, border, frame, rules, cellspacing, cellpadding)

width, border, cellspacing, cellpadding are allowed, but better to use CSS.

 

<tbody> table body block <table> one or more <tr> appears between thead and tfoot char, charoff in code flow, comes AFTER <tfoot>
<td> table data cell block <tr> Flow vertical align middle, text-align: left abbr, axis, headers, scope, rowspan, colspan,
width, align & valign allowed, but use CSS instead
 
<textarea> text area block <form> or block within form textnode or no text multi-line text field displaying textnode if there is one rows, cols, name, disabled, readonly  
<tfoot> table footer block <table> only one or more <tr> appears at bottom of table char, charoff, width, align & valign allowed, but use CSS instead comes before <tbody>
<th> table header cell block <tr> only Flow bold and center abbr, axis, headers, scope, rowspan, colspan, char, charoff. width, align & valign allowed, but use CSS instead  
<thead> table head block <table> only one or more <tr> only at top of table char, charoff. width, align & valign allowed, but use CSS instead follows opening <table> or <caption> if there is one.
<tr> table row block <table>, <thead>, <tfoot> or <tbody> one or more <th> or <td> new line char, charoff. width, align & valign allowed, but use CSS instead if any of the parent elements are present, there must be at least one <tr>
<ul> unordered list lists (block) block one or more <li> elements indented, bulleted on <li>s - -
<var> variable inline phrase element text (and inline) italic - No reason to include inline elements. Should be just text as child
Elements you should not be using, that are still valid
<tt> teletype inline inline or semantic block text (and inline) monospace - Purely presentational. Should be deprecated, but aren’t yet.
<i> italic italic
<b> bold bold
<big> big font bigger font
<small> small font smaller font
<frame /> frame block <frameset> Empty page within a page

name, src, longdesc, security. frameborder,
marginwidth,
marginheight,
noresize,
scrolling also allowed.

only allowed in frameset DTD
<frameset> frameset block <body> <frame>, <frameset>, <noframes> divides the browser window cols, rows. only allowed in frameset DTD
<noframes> no frames block <frameset> Flow - - can be found outside of frameset (for no iframe support)
<noscript> no script block Flow Flow - - Your site should work without scripts, so should not be necessary

Note:

  1. Attributes: All elements accept the standard and internationalization attributes of id, class, title, style, dir, and lang unless otherwise noted. The attributes column lists elements specific attributes and exceptions to the core attributes. Required attributes have been emphasized.
  2. Even though the type attribute is not required by the specifications, always define type because IE is stupid.
  3. Inline: <a>, <br>, <span>, <bdo>, <map>, <object>, <img>, <tt>, <em>, <strong>, <dfn>, <code>, <q>, <samp>, <kbd>, <var>, <cite>, <abbr>, <acronym>, <sub>, <sup>, <input>, <select>, <textarea>, <label> and<button>
    Block:
    <p>, <h1>, <h2>, <h3>, <h4>, <h5>, <h6>, <ul>, <ol>, <dl>, <pre>, <hr>, <blockquote>, <address>, <fieldset>, <table>
    Flow: text < form > and all the inline and block elements
    Empty: self closing element, include a slash before the end of the opening tag to self close. Contains no children
  4. Table elements: 0 or 1 optional <caption> element, 0 or more optional <col> elements OR 0 or more optional <colgroup> elements, 0 or 1 optional <thead> element, 0 or 1 optional <tfoot> element, and REQUIRED either one or more <tbody> elements OR one or more <tr> elements.
 
 

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%;}

 
 

http-equiv: Meta Attribute Values for http-equiv September 25, 2008

Filed under: Browsers, HTML, Web Development — Estelle Weyl @ 3:47 am
The http-equiv attribute is used by servers to gather information about a page using the HTTP header. The meta tag’s http-equiv attribute set is similar to a http header. The attribute lets you to send additional information to the browser in the http header. I rarely use any http-equiv meta elements other than content-type, and had never really thought about them for any purpose other than caching, So, as I looked deeper into the possible values, I thought I would “share”. There isn’t as much depth to this post as my usual endeavors, but hopefully this will make a good resource to bookmark.

Structure of Meta Element

The structure of the meta element is:

<meta http-equiv=”value” content=”value” />

Do not include the name attribute in the meta when the http-equiv attribute is included.

Do include the content attribute. Below are the various values for the http-equiv attribute:

Values for http-equiv

<meta http-equiv=”content-type” content=”type; charset=charset” />
http-equiv=”content-type” indicates the type of data sent to the browser, enabling the browsers to know what to do with data received. The <meta> element, in all its forms, are optional. Content-type is the one you really don’t want to omit. For English sites use <meta http-equiv=”Content-Type” content=”text/html; charset=ISO-8859-1″ />. There are many other possible values for content, such as <meta http-equiv=”content-type” content=”text/html; charset=ISO-2022-JP” /> for Japanese sites.
<meta http-equiv=”expires” content=”date” />
The date indicates the date and time that the document is set to expire. When the date is reached, the document will be reloaded even if the document is stored in the cache. This <meta> element is used to disable caching of the document: simply put a date that has passed in the date, and this will cause the browser to fetch new files. Put a date far into the future if you want the page to be cached. Note that IE6 will fetch the content of a users home page when a new browser window is opened, even if you set it to cache.

<meta http-equiv=”set-cookie” content=”name=value; expires=date; path=url“” />
The name is the name of the cookie.The value is the value to be set for that named cookie. The date is the date and time when the cookie will be deleted from the the computer. The date is optional. If you don’t include an expiration date and time, the cookie will be deleted when you exit the browser. You can include more than one http-equiv=”set-cookie” if you need to set more than one cookie name/value pair.
<meta http-equiv=”content-encoding” content=”data encoding” />
Indicates the encoding of the returned data; usually the compression type. For g-zipped documents, use <meta http-equiv=”content-encoding” content=”gzip” />
<meta http-equiv=”allow” content=”methods” />
Supposedly you include methods supported by server, but I’ve never seen this in action.
<meta http-equiv=”date” content=”date” />
Include the date and time that the page was created.
<meta http-equiv=”last-modified” content=”date” />
The content is the date and time the page was last modified.
<meta http-equiv=”location” content=”n; url” />
<meta http-equiv=”refresh” content=”n;url=url” />
ex. <meta http-equiv=”refresh” content=”12″ />
ex. <meta http-equiv=”refresh” content=”3;url=http://www.evotech.net/blog” />n is the interval at which time the page should be refreshed: in our example, the page will refresh every 12 seconds. If included, url is the location the page will redirect to. Our second example would cause the page to redirect to Community MX after 3 seconds. Please do NOT use this method to redirect to a new URL. It is not accessible.

<meta http-equiv=”window-target” content=”location” />
The http-equiv=”window-target” specifies the “named window” of the current page. The main use is to prevent a page from appearing inside another framed page: <meta http-equiv=”window-target” content=”_top” />. Usually this means that the Web browser will force the page to go the top frameset.

<meta http-equiv=”www-authenticate” content=”" />
http-equiv=”www-authenticate” is one method of providing basic access authentication, but providing such authentication in such a visible manner is not recommended for security reasons.
<meta http-equiv=”pics-label” content=’labellist‘ />
The Platform for Internet Content Selection (PICS) is a standard for labeling online content: basically online content rating. To generate the labelist, visit safesurf or another labellist generator. Note that the content attribute uses single quotes, because the PICS label syntax uses double quotes.

<meta http-equiv=”pragma” content=”option” />
<meta http-equiv=”cache-control” content=”option” />
You can use the http-equiv=”expires” with a past date to ensure that the browser retrieves fresh files from the server (rather than caching). Since not all client browsers and caching devices (e.g. proxy servers) are known to successfully implement all no-caching options, include multiple no-caching options, including:

<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="cache-control" content="no-store" />
<meta http-equiv=”content-language” content=”language-Country” />
Enables language specification, enabling search engines to accurately categorize the document into language and country. The language is the main language code, and the country is the country where the dialect of the language is more specific, such as en-US versus en-GB, US English versus English spoken in Great Britain. <meta http-equiv=”content-language” content=”de-AU” /> would be German as is spoken in Austria.

<meta http-equiv=”content-script-type” content=”language“>
The default script language for the script element is javascript. If you aren’t using JavaScript as your default, declare <meta http-equiv=”content-script-type” content=”text/VBscript”> informs the browser which type of scripting language you are using by default: is this case, Visual Basic.

<meta http-equiv=”page-enter” content=”revealtrans(duration=seconds,transition=num)” />
<meta http-equiv=”page-exit” content=”revealtrans(duration=seconds,transition=num)” />
Page-enter and page-exit are Microsoft proprietary transitions that only work in Internet Explorer. The seconds is how long the transition should take, and num is an integer between 0 and 23, correlated with a specific type of transition (23 is random).<meta http-equiv=”page-enter” content=”revealtrans(duration=2,transition=6)”>. There are 23 transitions, from 0 - 22. A transition with value of 23 is allows Internet Explorer to randomly select from the 23 available transitions. <meta http-equiv=”page-enter” content=”blendTrans(duration=sec)” /> is another value.

<meta http-equiv=”imagetoolbar” content=”no”>
Another IE specific (which means you shouldn’t use it) http-equiv value is “imagetoolbar”. In some versions of Internet Explorer, when an image is hovered, an image toolbar appears. <meta http-equiv=”imagetoolbar” content=”no”> enables the disabling of the image toolbar.

Notes:

  • The following characters appearing within the content must be escaped using SGML entities:
    single quote
    & & ampersand
    > > greater than
  • Note: Dates take the following format:
    Thu, 25 Nov 2008 16:15:30 GMT
 
 

CSS Hack for Google Chrome and Safari 3.1 September 2, 2008

Filed under: Best Practices, CSS (including hacks), Web Development — Estelle Weyl @ 9:29 pm

Valid CSS filter targeting Google Chrome and Safari 3.1

Non-compliant selectors can be used and a valid way to target individual browsers. Chrome supports every selector, just like Safari 3.1. My recommendation is to use the body:first-of-type hack, the CSS hack/filter for Safari as a filter for Safari 3+ and Chrome. There should be no reason to target Chrome with the exclusion of Safari 3.1, but if you want to target both, filtering out Safari 3.0, I would try using:

body:nth-of-type(1) p{
   color: #333333;
}

Only the Google Chrome and Safari 3.1 browsers will show paragraphs as grey. The logic is:

  • web pages only have one body element
  • only those two browsers support the pseudo-class of :nth-of-type()
  • body:nth-of-type(1) will match the first, and only, body element.

Use it as a predecessor to more specific selectors targeting the body’s children.

 
 

Google Chrome Browser CSS Selector Support

Filed under: Browsers, CSS (including hacks), Web Development — Estelle Weyl @ 5:27 pm

"Google Chrome," a browser based on the Webkit engine used by Safari, was released today. Chrome uses AppleWebKit/525.13. Safari 3.1 uses a slightly newer version: AppleWebKit/525.18. Below are the various CSS selectors, including CSS3 selectors, and current browser support.

  • Green / √ means current support.
  • Orange / Δ means that the browsers have some support for the selector.
  • Red / Χ means that the browser is non-compliant.

See also: CSS Hack for Google Chrome and Safari 3.1

    Browsers
Pattern Meaning IE6 IE7 IE8 FF Op
9
Sf Op FF NS CHROME
E:active
E:hover
E:focus
Dynamic pseudo-classes
Matches E during certain user actions.
Δ Δ
Δ Δ
Χ Χ
E:before
E:after
Static pseudo-classes
See generated content
Χ Χ Δ 3
Χ Χ Δ 3
  iPhn Windows XP Mac OSX
Selector Saf 3.0 Chrome FF 3.0 FF 2.0 FF 1.5 Op
9.0
Saf
3.0
IE8 IE7 IE6 Saf 3.1 Saf 1.3 Op FF 2 NS 7.1
*
E
.class Δ
#id
E F 1.
E > F Χ
E + F Χ
E[attr] Δ Δ Χ Δ
E[attr=val] Δ Δ Δ Δ Δ Χ Δ Δ Δ Δ
E[attr~=val] Δ Δ Δ Δ Δ Δ Χ Δ Δ Δ
E[attr|=val] Δ Δ Δ Δ Δ Δ Χ Δ Δ Δ
:first-child Δ Δ Δ Δ Δ Δ Δ Χ Δ Δ Δ
:link Χ
:visited Χ √<