removeNode and appendNode Functions

First, for everyone following the JavaScript Game Engine project, I am putting it on hold for now. Building an engine to support dynamic games requires a lot of work… a lot more more time than I currently have to devote to the project, and I do not want to release code of questionable quality. I will, however, revisit it from time to time and complete the article series as I am able.

For todays article, I would like to introduce two of my favorite DOM extension methods, "removeNode" and "appendNode". They are basically, simple wrappers for "removeChild" and "appendChilde" with the added functionality to animate the addition/removal of a DOM nodes. I find these methods to be very useful in providing feedback to a user when they are taking an action that modifies the DOM. Most of the time (and the default animation of this method) an opacity fade does the trick, making the addition/removal of a DOM node tangible to the user, but sometimes you need a different animation, so the methods accept animation arguments as optional parameters. I build these methods on top of YUI animator and either add them to the "YAHOO.util.DOM" or Document Object.

Example 1: AppendNode

Document.appendNode = function(root, elem, ap, fn) {
    var node = $(elem),
        parent = $(root);

    if (parent && node) {
        parent.appendChild(node);

        var animParams = (isType(ap, object)) ? ap : {opacity: {from: 0.25, to: 1}},
            anim = new YAHOO.util.Anim(node, animParams, 0.5, YAHOO.util.Easing.easeIn);

        anim.onComplete.subscribe(function() {
            if (fn && isType(fn, function)) {fn(node);}
        });
        anim.animate();
    }

    return node;
};

The "appendNode" method has two required parameters: the root element to append to, and the node to append with. As usual, I have written the "YAHOO.util.Dom.get" method as the $ shortcut method. By default the method will animate with a fade in from 0.25 opacity to 1 opacity, but you can override it by passing in your own arguments for YUI animation. If you want an event to occur after the animation, then provide a Function as the last argument, however it is also not required; this Function will be passed the newly appended node as its only parameter.

Example 2: RemoveNode

Document.removeNode = function(elem, ap, fn, isRemoveListeners) {
    var node = $(elem),
        parent = node.parentNode;

    if (parent) {
        var animParams = (isType(ap, object)) ? ap : {opacity: {from: 1, to: 0.25}},
            anim = new YAHOO.util.Anim(node, animParams, 0.5, YAHOO.util.Easing.easeOut);

        if (isRemoveListeners) {Event.purgeElement(node, true);}

        anim.onComplete.subscribe(function() {
            parent.removeChild(node);
            if (fn && isType(fn, function)) {fn();}
        });

        anim.animate();
    }
};

The "removeNode" method is very similar to the "appendNode" method, with the noted exception that the animation must occur before the actual removal of the child-node. You do not need to pass in the root Element as we can extract that directly from the provided node. Lastly, if you have attached any listeners to the node or its children, you should probably remove them. I leveraged YUIs "YAHOO.util.Event.purgeElement" (shortcut name of "Event.purgeElement") method for this, which will recursively remove the events attached to your node and its children, when you pass true as the last parameters (isRemoveListeners), otherwise no events will be removed.

Again, these methods are simple, but very handy. I have found it is almost always useful to provide feedback to users when they are adding/removing DOM nodes, and these methods abstract the logic away, so that I can do just about anything I need. If you&rsquot;d like to give them a try, I have provided a test page.

Document CreateTag Function

As I worked on the GameEngine improvements, I realized that it would be nice to have a menu and several other DOM elements. Since the engine will be standalone, it is necessary to dynamically create the DOM elements required to run the game. For this task, I have use a method "document.createTag()", which I often refactor for various projects. In its most basic form, it looks like the following:

Example 1: document.createTag

YAHOO.lang.augmentObject(document, ...

YUI DateMath on JavaScript Date Object

In the Date Functions article, I mentioned that you could apply the methods on YAHOO.util.DateMath to the Date object direclty, instead of implementing a static class. A few people wrote in and requested that I do just that, so that is what I will write about today. For reference, please check out the DateMath class at YAHOO: DateMath The first step is to remove the constants from the static class and augment the ...

Extending Native Date

Like String, the native JavaScript Date object also does not have as many helper functions as you might like. Using a similar approach as we did with String, we can attach additional functionality to Date.

Example 1: Date Augmentation

YAHOO.lang.augmentObject(Date, { /** * Date constant for full month names * * @property MONTHS * @type string */ MONTHS: [January,February,March,April,May,June,July,August,September,October,November,December], /** * Returns a date object from the string; expects MonthName, DayNr Year Hrs:Min:Sec, ...

Extending Native String

Strings in JavaScript do not have as many helper functions as one might like. As a result you will probably need to write a collection of methods yourself. You can either create a static utility object (or functional functions) or extend the "String.prototype". String is one of the few objects that has little consequence when extending its prototype object, as you do not use "for … in" on strings. For today’s discussion, we will be ...

xJson Object Continued (Part II)

Today we are concluding our discussion of the xJSON object package. You should have read the following two articles and know what Model.js does, and understand the "extend" function with super class inheritance: Improving Extend With SuperXJSON ObjectsDownload the most up-to-date xJSON package. There are 4 JSON models in this package: JsonArray, JsonObject, XJsonArray, and XJsonObject. As a recap, the xJSON Objects are used to improve the performance of large, ...

xJson Objects

Alright everyone, I have finished the xJSON object suite, or at least a decent first pass. This was a bigger project than I expected and I apologize for dragging it out over the past couple weeks. It seemed like every time I was about to finish, I would uncover a corner case that would break an entire second of the project. Anyway, I was away over the passed weekend and had to do a lot ...

Improving Extend With Super

Alright, it looks like I will need to eat my words about not needing super class support in my extend Function, see Object Extension. As many of you know, I have been working on Objects to represent XJson in JavaScript. One of the changes from my original JSONObject Model is that I now use "Core.extend" to extend a core Model object. This object has an onChange event and an update function. Here is ...

Issues with JsonArray

My goal today was to finish most of the models that I have been working on and share this with you. However, it is turning out to be a much more complicated problem than I originally thought. I want the JsonArray object to dynamically create JsonObjects (as necessary) when retrieving elements out of the array. However, the JsonObject declaration requires that you know what Object is being passed, and more importantly, what keys to expect. ...

JsonObject Model Prototype

I have been doing a lot of server-side work in PHP and JAVA this past month. One of the design practices used by server-side webapp languages is the MVC (model-view-controller) framework. An MVC makes writing extensible and scalable code, much easier. In JavaScript I have seen a couple of attempts at a similar MVC framework, but most of the time it is overkill or poorly implemented. Shutterfly.com on the other-hand, has a lot ...