Archive for the Category 'javascript'

Parameters string and the Prototype Ajax.Request method

I just noticed something that's a little funny about Prototype 1.6>. I've successfully deployed a number of projects with v1.5 of the library, with all of the improvements I've been reading about with v1.6, I decided to keep up with the times and use the newest version for a project that is very DOM Scripting intensive.

While making a request with either new Ajax.Request or new Ajax.Updater something kept going wrong.

Though the Prototype API Docs were giving examples such as this:

JavaScript:
  1. new Ajax.Updater('products', '/some_url', { method: 'get' });

Firebug was throwing me an error. Hooray for Firebug for doing it's job. Well, that's what I thought at first, until it was time to see what this error was about. Long story short, Google returned nothing...

CODE:
  1. pair has no properties
  2. http://projectname.localhost/js/prototype.js
  3. Line 417
  4.  
  5. [Break on this error]  if ((pair = pair.split('='))[0]) {

It turns out that this error was being thrown by Prototype's toQueryParams method. toQueryParams was being called by Ajax.Base's initialize method...

JavaScript:
  1. if (Object.isString(this.options.parameters))
  2.     this.options.parameters = this.options.parameters.toQueryParams();
  3. else if (Object.isHash(this.options.parameters))
  4.     this.options.parameters = this.options.parameters.toObject();

I said to myself (in the third person) "Nater, you're not passing any params, the request URL is specified elsewhere, AND it's 'friendly' anyway... this seems silly". Looking up a couple of lines it turns out that the default Ajax.Base.options.parameters key is set to an empty string by default. Since toQueryParams() is not happy when it's passed an empty (albeit default) string, what else can we do? The simple answer is to pass an empty object instead!

JavaScript:
  1. new Ajax.Updater('products', '/some_url', { method: 'get' ,parameters:{}});

Voila! Since this seems like it's something that's way too easy to come across, I haven't yet figured out if it's a bug or I'm just missing something that's even more basic.

Clearing the contents of a DOM Element

Sometimes we get lazy, we decide not to care about a couple of K of our user's RAM and we do silly things like replacing the content of a DOM Element with innerHTML. It's not a huge deal, in fact I'm a fan of using the AHAH method of inject pre-formatted XHTML into my document when memory consumption is small or not an issue. AHAH is easy. You can take advantage of all the fancy parsing resources you have with with serverside development, expose no actual data to the client. It's quick and dirty, and that's often times ok. Thing is, when you are writing an application that may ping a webservice and update content on a regular basis (whether it's an AIR application or just something that runs in a browser) it's not cheap. Since you can't have quick, cheap and dirty, you end up paying for the repeted injection of chunks and use of innerHTML through memory loss, and browser performance suffers.

CODE:
  1. var Someobject = {
  2.     clearElement : function(el){
  3.         if (!el) return false;
  4.         var el = (typeof el === 'string') ? document.getElementById(el) : el;
  5.         var i = 0;
  6.         while (el.hasChildNodes())
  7.         {
  8.           el.removeChild(el.firstChild);
  9.         }
  10.         delete el;
  11.         return true;
  12.     }
  13. };

Make sure you know what you're removing

If you're not using firebug or firebug lite, or a webkit nightly. You might want to be able to generate console-like output to give you a clue as to what elements you're actually removing from the DOM. If that's the case, you can just add something like this trace function to SomeObject.

CODE:
  1. var Someobject = {
  2.     trace : function(str){
  3.         if (window.console) {
  4.             return console.log(str);
  5.         } else {
  6.             if (!document.getElementById("clearElementOutput")){
  7.                 var output = document.createElement("div");
  8.                 output.id = "clearElementOutput";
  9.                 document["body"].appendChild(output);
  10.             }
  11.             // dirty
  12.             document.getElementById("clearElementOutput").innerHTML += str + "<br />";
  13.             return true;
  14.         }
  15.        
  16.     },
  17.     clearElement : function(el){
  18.         if (!el) return false;
  19.         var el = (typeof el === 'string') ? document.getElementById(el) : el;
  20.         var i = 0;
  21.         while (el.hasChildNodes())
  22.         {
  23.           //comment this out to suppress output
  24.           this.trace(i++ + "deleting " + el.firstChild.nodeName);
  25.           el.removeChild(el.firstChild);
  26.         }
  27.         delete el;
  28.         return true;
  29.     }
  30. };

A demo file can be found here.

Scriptless Day 2007

You may notice that I have a new little banner running on the top right corner of this site... Some folks got a lovely idea recently that for one day, all supporting sites will run without and client-side scripting.

As time has gone by, more and more sites have come to depend on javascript for their basic functionality to work and in my opinion it's a shame. I admit that even my portfolio (which was thrown together in about 2 days) was dependent for a little bit, but that quickly changed as soon as I started actually using my brain about a year and 1/2 ago.

Why this is such a good idea

It's a responsible thing to do. If a developer cares about their users or their client's users, they will build apps using "traditional" methods (GET POST and the like) and then add any client-side scripting to compliment the already functional app or website. Progressive enhancement in my opinion should be a standard, at least unofficially by now.

I hope developers everywhere step-up, and do what they need to to "make it right" and participate on July 7th 2007

http://www.scriptlessday.com/ They're on twitter as well.

Still hiring developers at Ultra16

originally posted here http://www.krop.com/jobs/48c5y/

Client-side developer (mid-level or wizard)

Lemme break it down for you

  • Love what you do, we do and that’s why we’re here.
  • Be great at what you do, we try our best to be great, so it’s fair to ask it of those we work with.
  • Never claim you know it all, unless I’ve bought a book with your name on it.

We’re not just looking for a specific skill-set, it’s all about your smarts, personality, and what you can bring to the table.

So let us know if you can answer a few of the following, or have any other interesting stuff notched on your belt:

  • Do you know all the basic standards compliant, unobtrusive, semantic and accessible stuff?
  • Can you tell us what browser likes *:first-child+html ?
  • Know $()? can you .bind()?
  • Are you friends with designers? Did you used to be one?
  • Have you worked on the agency side before? If not, tell us why.
  • Solid knowledge of AS 2.0+ a plus
  • LAMP, .NET, or Rails. a plus

We are Ultra16, we have a big green wall, an office in NoHO, AirTunes, andoften hang out at the office just because we want to. We also have beenaround since the 90’s and work with clients who you’ve probably heardof.

To apply just hit us up at humanresources@ultra16.com with your resume, some links to your work, a code sample if you feellike it, and a paragraph or two about yourself (don't be afraid to showyour personality)

IE7 Quirks

Max over at OpenLaszlo was writing about some browser/quirk detection that he put together for v4.0. He listed in his post a number of quirks for IE7, some of which I was aware of, and some I wasn't.

  • Can't set opacity on any div that contains <input type="text"/> or <textarea/> without getting nasty visual artifacts in the text field.
  • Must use the AlphaImageLoader if we want opacity to apply to a div and all its children.
  • AlphaimageLoader must have its src property set to the URL of an image to prevent a red x/missing image icon from appearing
  • AlphaimageLoader does not send onload/error events - instead we have to use the img tag mentioned above
  • IE 7 still has memory leaks for apps loaded in iframes
  • Empty divs with style.backgroundColor set appear ~10px tall unless they contain an img (for less than 2px tall) or have style.fontSize = '0px' applied.
  • IE does not support ' when setting a div's innerHTML property
  • IE does not send onclick/onmouse* events for divs without a blank image attached

One of my favorite IE7 quirks has to do with z-index being overrided by the order in which the element appears in the DOM. If a div has a z-index of any positive number and it's followed by a div with a z-index of anything less, and they are positioned in an overlapping manor, the div that comes second in the DOM appears in front of the div with the higher z-index value.

What are some of your "favorite" IE7 bugs / quirks? I'd like to put together a comprehensive list.

Alpha PNG Backgrounds in IE, another sleight update…

A couple years ago Drew McLellan created his version of Youngpup’s Sleight script for enabling PNG transparency in Internet Explorer. It's a handy little thing, it's called bgsleight.js and I found myself using it for a recent project that required a decent amount of transparency in background images throughout. The great thing about bgsleight is that you don't have to generally create a separate css file for IE6 filled with progid:DXImageTransform.Microsoft.AlphaImageLoader garbage.

Some of these background images were specifically positioned, and some were repeating (not for pattern, but just coverage of their element's area). After putting Drew's work to use, I found that the background images that were being repeated in my css, were now basically gone (or just being displayed as the very small versions of themselves that they are, just a couple of pixels large). I looked into the pngfix function, and added a check against whether or not the background image was supposed to be repeating or not.

JavaScript:
  1. function fnFixPng(obj) {
  2.     var bg  = obj.currentStyle.backgroundImage;
  3.     var src = bg.substring(5,bg.length-2);
  4.     var sizingMethod = (obj.currentStyle.backgroundRepeat == "no-repeat") ? "crop" : "scale";
  5.     obj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='" + sizingMethod + "')";
  6.     obj.style.backgroundImage = "url(path/to/transparent.gif)";
  7. }

One thing that I forgot to mention is that a transparent 1x1 pixel gif is required to make this script work. i changed the references to it which had previously been x.gif and blank.gif to path/to/transparent.gif... a generic reference (for you understand to replace with whatever path you'd like).

You can grab my copy of bgsleight.js here.

hooray for oopyjs!

Jonathan Snook over on Digital Web wrote a lovely little article on what i like to call Oopy (Object Oriented) JavaScript. Oopy JavaScript is much over looked subject for most folks unless they write their own library, extend someone elses and/or happen to know what they're doing in general. Writing JavaScript in an Object Oriented way requires a slightly different approach over Java or other typically Oopy-friendly languages simply do to the fact that Classes are not specified for ECMAScript v3. Macromedia when releasing actionscript 2 jumped ahead of the game by providing much needed class and namespace implementation. where as with JavaScript, we basically have to fake it by using wrappers to keep our object references organized.

Jonathan goes to talk further about the use of prototype property and other than letting us create references to the guts of an object's template, it reduces the risk of memory leaks due to the browser being saved from having to duplicate any objects needlessly.

We can add to the template’s prototype at any time, and the new properties will automatically be available, even on object’s we’ve already created. Let’s rearrange the last example to demonstrate:

CODE:
  1. function Animation(element){
  2.    this.animationLength = 30;
  3.    Animate.element = element;
  4.  }
  5.  var animateLogin = new Animate(loginform);
  6.  
  7.  Animation.prototype.onStart = function() {
  8.    alert("The animation is beginning!");
  9.  };
  10.  Animation.prototype.onEnd = function() {
  11.    alert("The animation is ending!");
  12.  };
  13.  
  14.  animateLogin.onStart();

Even though we create the new Animation before we define the onStart and onEnd methods, we can still use them! This is a huge advantage of the prototype-based approach.

So alright kids, get crackin!

Progressive Enhancement, Accessibility, Semantics and Flash

This next monday On Monday October 2 I will be giving a presentation to the lovely folks at ULTRA16 on Progressive Enhancement, Accessibility, Semantics and also how to make it happen with Flash. After monday, the presentation will be available here for anyone who may have interest.

doing simple things without a code library

So I just was reading this article written by David Talbot on Devx.com about Yahoo's UI libraries aiming to make crossbrowser development a bit easier for some folks.

The only notable feature that I could seem to find, was the simplification of setting the opacity of a DOM element in an elegant way. An entire library for that? I got a little curious and took a further look.

Here's an exerpt from the artile:

The DOM and Event Libraries
YUI's capabilities in regard to core DOM and event handling are incredibly rock-solid, perform as expected, and cover a broad range of capabilities. Most surprisingly, this API gives you simple cross-browser transparency control. Most developers aren't even aware that magic tricks even exist (via DirectX calls) to make semi-transparency work in IE, much less the Mozilla-based equivalents, but YUI enables access to most, if not all, of the CSS properties you'd ever want. Here's an example:

YAHOO.util.Dom.setStyle('MyDivID', 'opacity', .5);

Suprizingly? Are you kidding me? Maybe I just don't get what the big deal is. I've been developing crossbrowser DHTML in one way or another since the beginnings of the last browser wars. And back in 99-2000 when everyone was bitching about the diversity in W3C support between the version 4 browsers, I was just doing what needed to be done to make everything work the way it needed to.

So despite Mr. Talbot's enthusiasm for what I considered to be not much of a big deal at all I headed over to Yahoo's Developer Center poked around their lousy documentation and downloaded the most recent build here on Sourceforge. I took a peek at the source, and it turns out that Yahoo and I have almost the same exact approach, thing is, running their entire library is pretty needless.

Here's what I came up with to put together a fade in effect for the items being loaded into my portfolio via xmlHttpRequest.

here's the very simple browser check:

JavaScript:
  1. var ua = navigator.userAgent.toLowerCase();
  2. var isOpera = (ua.indexOf('opera') != -1);
  3. var isIE = (ua.indexOf('msie') != -1 && !isOpera);

and here's an exerpt from my getPortfolioDetail function:

JavaScript:
  1. xhrPortfolioDetail.onreadystatechange = function() {
  2.     if (xhrPortfolioDetail.readyState == 4 && xhrPortfolioDetail.status == 200) {
  3.         portfolioDetail.innerHTML = xhrPortfolioDetail.responseText;
  4.         var fader;
  5.         for(count = 1;count <= 10; count++){
  6.             fader = setTimeout(function(){
  7.                 val = count*0.1;
  8.                 if (isIE && typeof portfolioDetail.style.filter == 'string'){
  9.                     portfolioDetail.style.filter = 'alpha(opacity=' + val * 100 + ')';
  10.                     if (!portfolioDetail.currentStyle || !portfolioDetail.currentStyle.hasLayout) {
  11.                     portfolioDetail.style.zoom = 'normal'; // if you use '1' it distorts things
  12.                 }
  13.             } else {
  14.                 portfolioDetail.style.opacity = val;
  15.                 portfolioDetail.style['-moz-opacity'] = val;
  16.                 portfolioDetail.style['-khtml-opacity'] = val;
  17.             }
  18.         },100*count);
  19.     }
  20.     xhrPortfolioDetail = null;
  21. }

Pretty simple eh? One thing that you can't see is where I use the same approach to lower the opacity to 0.1 while loading, so there isn't any flashing of the loaded content before it fades in.

I know that there are tons of AJAX Frameworks out there that provide fade in type effects, but I'm not quite there on implementing one. Noteables include Dojo, MochiKit, and of course the ever popular script.aculo.us.

I'm still working on making it work a little more smoothly and efficient as the delay in setting the opacity while i'm doing the xmlHttpRequest is inconsistant at best.

is Spry the way to go?

Framework this, framework that. RoR or CakePHP? bah, what about somthing else? Well Adobe Labs has introduced the Spry Framework for Ajax prerelease 1.1. And their demos look pretty good.

Photo Gallery
Photo Gallery
Product Table
Product Table
RSS Reader
RSS Reader
The release addresses issues reported by testers since Spry first came out. You can find the change log here, the overview here, and find the download here.

Even though Spry's UI effects make it quite attractive for my playful and easily distracted side. I wonder how it would hold up with my use of XHTML return data instead the clientside XML parsing that i talked about in this previous post.


Nater Kane naterkane personal http://www.naterkane.com LinkedIn Profile Web Technologist personal nater@naterkane.com 1978-09-12 voice 845.234.6698 | fax 707.922.0593
964 Flushing Ave. Brooklyn, NY 11206