Recently in Javascript Category

Converting to an int without exception

By Luke Smith on November 25, 2007 11:25 PM

The comp.lang.javascript FAQ has a nifty little trick in the type conversion section for converting anything to an int and rather than possibly getting NaN, you will always receive a number.

It's all about the bitwise OR

The method uses the bitwise OR operator | with a non-impacting 0 operand to leverage the JavaScript native ToInt32 function otherwise unavailable within your code. Simply OR a variable and it will be a number.

var foo;
...much chaos ensues...

foo = foo|0; // convert foo to an int

Similar to the unary + operator, |0 will convert false and the empty string to 0 and true to 1. However, it will also convert invalids, such as undefined, "foo", or function foo() {} to 0.

Cryptic? Yes. Idiomatic? Yes. Nifty? I think so. I don't anticipate using it any time soon, as its applicability seems limited, but still something to have in the tool belt (and never use without annotation).

Check out the FAQ page for more info.

Private static class vars in javascript

By Luke Smith on June 19, 2007 9:40 PM

Here's an addition to the recently named Module Pattern. Let's add private static class vars.

Let's assume we want to create an object class that will be used via the new operator, but there's a need to have a shared but private data space between instances. Here's how:

Example code

// always contain your code in a namespace
var LSN = { example : {} };

LSN.example.Foo = function () {
    // vars and methods declared in this scope will be shared by instances
    var static_bar = 0;

    // private static functions
    function incrementBar() { ++static_bar; }
    function getBar() { return static_bar; }

    // Create a function that will be returned as the Foo class constructor
    // referencing static vars and methods along with instance 
    function InstanceConstructor(instance_seed) {
        // instance private variable
        var instance_bar = instance_seed;

        // instance private method (until exposed in the returned object)
        function incrementInstanceBar() { --instance_bar }

        // instance private method affecting the class static var
        function splitStaticBar() { static_bar = Math.floor( static_bar / 2 ); }

        return {
            incrementStaticBar : incrementBar, // method affecting static class vars
            decrementStaticBar : function () { --static_bar }, // another, less efficient way
            splitStaticBar : splitStaticBar, // slightly less inefficient way, but still not preferable
            getStaticBar    : getBar, // get the shared static value

            incrementInstanceBar : incrementInstanceBar, // method affecting instance private var
            decrementInstanceBar : function () { --instance_bar }, // another, less efficient way
            getInstanceBar : function () { return instance_bar } // get the instance private var
        }
    }

    // return the function that will be used to construct the instances
    return InstanceConstructor;
}();

// Proof is in the pudding.  Create two instances of Foo
var t1 = new LSN.example.Foo(10);
var t2 = new LSN.example.Foo(2);

t1.getStaticBar(); // returns 0
t2.getStaticBar(); // returns 0

// Have one instance modify the private class var
t1.incrementStaticBar();
t1.getStaticBar(); // returns 1
t2.getStaticBar(); // also returns 1

for (var i = 0; i < 5; ++i) {
    t2.incrementStaticBar();
}

// Modify the static var with a method declared in the instance function scope
t1.splitStaticBar();
t1.getStaticBar(); // returns 3
t2.getStaticBar(); // also returns 3

// Play with instance variables as well
t1.getInstanceBar();  // returns 10
t2.getInstanceBar();  // returns 2

t1.incrementInstanceBar();
t1.getInstanceBar(); // returns 11
t2.getInstanceBar(); // returns 2

Points of interest

It's a pretty simple change from the basic instance creator function. Just wrap the instance creator function in another function—what I'm calling a class creator function. All vars declared in the class creator function scope are shared across all instances created with the returned instance creator function.

The methods affecting the class vars can be declared in the instance creator function scope, but I think it's cleaner to have the class var accessor methods in the class creator scope unless they're also modifying instance variables.

In my example, I chose to use prototypeless instance creation, returning a simple object with function refs to modify private class and instance data. It is possible to use a prototyped instance creator function and assign methods to the prototype that will affect the private class vars (but not the private instance vars). For example

    ...
    function InstanceConstructor(instance_seed) {
        // instance private variable
        var instance_bar = instance_seed;

        // instance private method (until exposed in the returned object)
        function incrementInstanceBar() { --instance_bar }

        // instance private method affecting the class static var (dead code.  see NOTE below)
        function splitStaticBar() { static_bar = Math.floor( static_bar / 2 ); }

        this.incrementInstanceBar = incrementInstanceBar;
        this.decrementInstanceBar = function () { --instance_bar };
        this.getInstanceBar = function { return instance_bar }
    }
    InstanceConstructor.prototype.incrementStaticBar = incrementBar;
    InstanceConstructor.prototype.decrementStaticBar = function () { --static_bar };
    InstanceConstructor.prototype.getStaticBar = getBar;
    // NOTE: we can't reference the splitStaticBar function, since it was declared in the instance creator function scope, but we're back in class creator scope

    return InstanceConstructor;

Practical uses?

This would be useful when used with prototypeless instance construction where you want to create only one instance for a given set of construction params, and redistribute the cached instances on future calls to new. At the moment, I'm tired and that's all I can come up with. I'll let smarter people devise clever uses for it.

Update

Richard Cornford sent me an excellent and far more thorough write up on the idea. Good reading. I found the use of the much derided with particularly intriguing.

Broken lists

By Luke Smith on September 21, 2005 9:58 PM

So I discovered today that HTMLArea and FCKeditor both suffer from a nasty side effect of edit mode in IE and Mozilla/FF. They produce malformed html when nesting lists. Let's take FCKeditor, since I would figure it more likely to have caught this issue. If you don't have it installed, then you can take my word for it. I added some pretty pictures—so I can point and say "HA!" I'll use the default demo page that comes with a fresh installation (circa 10 minutes ago). Make sure you have access to the Source button. Use one of the list control buttons to open a list. Screen cap of the list control buttons in FCKeditor Enter values for a couple items, then either hit tab or click the indent button to indent into a nested list. Change the list type, just to reassure yourself that this is in fact a new list. Happy? Let's continue. Add values for a couple items in the nested list. Now shift-tab or use the outdent button to bring yourself back to the next item in your primary list. Enter a few values. Does your list look something like this? Now click on the Source button to view the source of your content. Screen cap of the 'Source view' control button Aaaaaaaand..... Screen cap of the produced source code Eh? What's this? That UL isn't in an LI tag. I'm pretty sure that's not according to spec. Also I noted that HTMLArea (at least the 2.x version installed in the application I work on) has a nasty habit of prefixing any content preloaded from the linked textarea with empty P tags. I'm not sure if this is an artifact of our particular usage, but I figure it's worth noting. So if you have an application that manages content via HTMLArea, you might want to update
(something)._textArea.value = editor.getHTML();
to*I can't recall the object variable name. This is all out of my lacking short term memory
var html = editor.getHTML();
  (something)._textArea.value = html.replace(/^(\s*<p ?\/>)*/gi, '');
Or better yet, add the empty P tag regex to the other collected HTMLArea.[something]_RE = /blah blah/i declarations earlier in the code.

Ajax + Client side XSLT

By Luke Smith on July 25, 2005 10:53 PM

Recently I had the pleasure of working with a web interface that simultaneously displayed a single XML data set in two ways, an navigable outline format, and a pure content format. The data itself was describing contract terms, clauses, and rates. Legalese. The interface up to that point was built using a good old fashioned table layout with a healthy side order of custom attributes and inline event handlers on non-standard elements. Ick! Ugly, yes, but there was technically nothing to raise any cross browser compatibility issues. It was designed for IE and didn't display all that well in FireFox, but it did display close to correctly, and all the functionality was there.

That is, until they added this interface. The UI framework loaded separately, then issued three Microsoft.XMLHTTP requests: one for the XML data, and two for the XSL stylesheets to be used to transform the XML.

All the code was IE specific, so I couldn't very well leave it alone, now could I? Besides, I like to develop in FF,*due to its plethora of wonderful extensions. Well that and it's a much faster, safer, and more standards compliant browser. Old news, I know. but was prevented from doing so by this unwarranted tryst with the unruly IE.

So I came up with a nice little library to manage the collection and transformation of XML data, and do it in a cross browser and OO way.

Use it like this:

function page_init() {
    // Create a new object.  Note this needs to be globally
    // scoped so the IO Bridge can reunite the response with
    // the calling object
    xml = new XMLData();

   // Define the source of your data. This can be any URI    // that returns valid xml data    xml.setDataSource("my_data.xml");
   // Also define a couple of stylesheets to transform the    // data once it's here    xml.addStylesheet("outline_view.xsl","outline");    xml.addStylesheet("content_view.xsl","content");
   // Tell the object to call build_view() when all the    // data and XSL files are ready to rumble    xml.setCallback(build_view);
   // Start things in motion    xml.load(); }
function build_view() {    var tree = document.getElementById('data_tree');    var content = document.getElementById('data_content');
   // flush the contents    tree.innerHTML = content.innerHTML = "";
   // Append the generated DOM structure to the target    // nodes    tree.appendChild(xml.transform("outline"));    content.appendChild(xml.transform("content")); }
// Using Keith Gaughan's EventManager library to separate // out the <body onload="page_init();">. EventManager.Add(window,"load",page_init,false);

After the page loads, this will send the ajax requests for each file

  1. my_data.xml, then
  2. outline_view.xsl, then
  3. content_view

Naturally it doesn't wait for one response before sending any other requests.

The two stylesheets are given labels for use in the call to transform(). Label assignment isn't strictly necessary. If you don't provide one to addStylesheet() or transform(), they will assume a label "default", so just don't call addStylesheet(url) with different urls and you should be fine.

Happy transforming!

Body onLoad done the separatist way

By Luke Smith on July 17, 2005 5:31 PM

I'm a big fan of separating content from functionality. Clean semantic markup doesn't have a place for javascript. That's icing. I like to keep to this sequence:
  1. Start with content
  2. Markup the content using the appropriate semantic tags
  3. Begin building your stylesheet to define the character of your presentation
  4. Add the necessary container elements to allow for the design/layout your going for*Ideally, you can create an effective space without adding extra tags, but this usually isn't realistic.
  5. Add the layout style to the stylesheet/s
  6. Build the javascript functionality to augment the site (in a separate file)
  7. Add any noscript section/s to replace "necessary" functionality
  8. Lather, rinse, repeat
Rather than clutter the markup with onBlah events and other stuff that doesn't celebrate the content, add the event handlers in a page_init() function. Then add this handy little code snippet to the end of your javascript file to purge that last remnant of markup+code, <body onload="page_init();">: your_javascript.js
if (window.addEventListener) {
     window.addEventListener('load',page_init,false);
} else if (window.attachEvent) {
     window.attachEvent('onload',page_init);
}
I won't take credit for this code. I copied it from some site a while back. I can't recall which, though. If I happen across it, I'll link it here. Now your <body> is clean and fresh.

ls.n

LucasSmith.name

Luke and Heidi

I'm Luke. I am a front end engineer at Yahoo! on the YUI team.

Mostly I write about code stuff, but occassionally I'll mix in some real life. You've been warned.

Archives

Tags

Feeds

Subscribe to feed Recent entries

Content licensed under Creative Commons

Code licensed under BSD license

©2005 - 2010 Lucas Smith

Powered by Movable Type