View RSS Feed

Twey

DOM manipulation code

Rating: 9 votes, 3.22 average.
Here's some of my personal DOM manipulation code:

Code:
Object.extend = function(o1, o2) {
  for (var x in o2)
    if (o2.hasOwnProperty(x))
      o1[x] = o2[x];

  return o1;
};

Object.extend(Object, {
  copy: function(o) {
    return Object.extend({}, o);
  },

  fromArray: function(o) {
    var r = {};

    Array.map(function(pair) { r[pair[0]] = pair[1]; }, a);

    return r;
  }
});

Object.extend(Function, {
  id: function(a) { return a; }
});

Object.extend(Array, {
  map: function(f, a) {
    for (var i = a.length - 1, r = []; i >= 0; --i)
      r[i] = f(a[i], i);

    return r;
  }
});

Object.extend(String,
  upperFirst: function(s) {
    return s.charAt(0).toUpperCase() + s.substr(1);
  },

  trim: function(s) {
    return s.replace(/^\s+/, "").replace(/\s+$/, "");
  }
});

var Css = (function() {
  var jsEquivs = {
    'float' : "css-float"
    // &c.
  };

  function cssToObject(s) {
    return Object.fromArray(Array.map(textToPair, s.split(";")));
  }

  function textToPair(s) {
    var r = Array.map(String.trim, s.split(":"));

    r[0] = propertyToCss(r[0]);

    return r;
  }

  function propertyToJs(s) {
    return Array.map(String.upperFirst, (jsEquivs[s] || s).split("-")).join("");
  }

  function apply(el, style) {
    if (typeof x === "string")
      el.setAttribute("style", el.style.cssText = style);
    else
      Object.extend(el.style, style);

    return el;
  }

  return {
    propertyToJs: propertyToJs,
    cssToObject: cssToObject,
    apply: apply
  };
})();

var Dom = (function() {
  function get(a) {
    return document.getElementById(a);
  }

  var attrmap = {
    'class': "className"
    // &c.
  };

  function applyAttributes(el, attrs) {
    for (var x in attrs)
      if (attrs.hasOwnProperty(x))
        if (x === "style")
          Css.apply(el, attrs[x]);
        else
          el[attrmap[x] || x] = attrs[x];

    return el;
  }

  function addChildren(el, children, filter) {
    Array.map(function(child) {
      if (!child) return;

      if (child = create(child))
        el.appendChild(child);
    }, children);
  }

  function create(el, filter) {
    if (typeof el === "string")
      return document.createTextNode(el);

    if (!(el instanceof Array))
      return el;

    filter = filter || Function.id;

    var r        = document.createElement(el[0]),
        attrs    = el[1] || {},
        children = el[2] || [];

    applyAttributes(r, attrs);

    addChildren(r, children, filter);

    return filter(r);
  }

  function clear(el) {
    while (el.hasChildNodes())
      el.removeChild(el.firstChild);

    return el;
  }

  return {
    create: create,
    get: get,
    clear: clear
  };
})();
I'll add bits onto it as I need them.

Submit "DOM manipulation code" to del.icio.us Submit "DOM manipulation code" to StumbleUpon Submit "DOM manipulation code" to Google Submit "DOM manipulation code" to Digg

Updated 04-06-2009 at 12:47 AM by Twey

Tags: 1'", zvwqendc Add / Edit Tags
Categories
JavaScript & Ajax , Post a JavaScript

Comments

  1. mburt's Avatar
    It should be called Javascript 2.0, because that's pretty much what it is. I can't get over how incredibly efficient your DOM functions are compared to the regular ones.
  2. Twey's Avatar
    I presume you're referring to create(). I haven't really focussed on efficiency here; I'm just trying to make it less horrible to work with than the flat DOM methods. The format I'm using here is actually not my own: it's a simple (possibly incomplete?) implementation of JsonML. Ideally, for efficiency and readability, it's better to include the templates in HTML and then make copies of them with cloneNode() as necessary. However, sometimes we really do need to create chunks of markup in code, and this aims to allow the simplicity of innerHTML without sacrificing the standards compliance, readability, and ease of formatting and transformation.