0

I wonder what's the effectiviest way of creating an element with id='id' class='class' attr='attr' .. and appending it to another element and have it available as a variable?

So far I can do it with one line of code. But it requires a new set of javascript framework. I just want to make sure that there is no effectivier way first.

My solution is to create a javascript framework, which got the following syntax:

var variable = elementTagAppend/Prepend/After/Before('JQuerySelector', elementToAppend/Prepend/After/BeforeTo);

For instance, if I want to create an div element with id='id', class='class', attr='attr' and append it to an another element called "another"

var variable = divAppend('#id.class[attr = "attr"]', another); Very effective right?

Or if I want to prepend a form element with id='inputForm', class='inputForms':

var variable = formPrepend('#inputForm.inputForms', another);

einstein
  • 13,389
  • 27
  • 80
  • 110

3 Answers3

4
var element = $("<div/>", {
    id: "id",
    class: "class",
    attr: "attr"
}).appendTo("#element");

appendTo returns a JQuery object, you can read more on http://api.jquery.com/appendTo/

Edit: It looks like you're asking if an effective way to create elements is having methods for all HTML tags, so that your library doesn't have to do any sort of text parsing/regex.

This isn't a solution as it makes development a lot slower.

Peeter
  • 9,282
  • 5
  • 36
  • 53
  • @Wogo87: add `var myDiv = ...` before it if you need a reference to it. – RoToRa Apr 15 '11 at 09:47
  • @RoToRa: But I think Jquery needs to determine first that it is a div element, which makes rendering very uneffective – einstein Apr 15 '11 at 10:02
  • @Woho87: I don't understand at all what you are asking with that comment (or with your updated question). What do you mean with "determine first that it is a div"? And rendering nothing to do with jQuery. – RoToRa Apr 15 '11 at 10:16
  • creating an element using $('
    ') is not faster than documen.createElement('div'), since JQuery needs to determine if there is html tags first and then which tag.
    – einstein Apr 15 '11 at 10:28
  • 1
    Creating a new layer ontop of document.createElement('div') will not give you any boost in performance or productivity. If you're worried about performance at this level, use pure javascript. – Peeter Apr 15 '11 at 10:43
0

One way is to use a function and DOM methods:

<script type="text/javascript">

var elementData = {
  tagName: 'div',
  properties: {
    id: 'div0',
    onclick: function(){alert(this.id);},
    className: 'someClass'
  },
  content: '<h1>New Div</h1>'
}


function elementBuilder(obj) {
  var el = document.createElement(obj.tagName);
  var props = obj.properties;

  for (var p in props) {
    if (props.hasOwnProperty(p)) {
      el[p] = props[p];
    }
  }

  if (typeof obj.content == 'string') {
    el.innerHTML = obj.content;
  }
  return el;
}

</script>

<button onclick="
  var newElement = elementBuilder(elementData);
  document.body.insertBefore(newElement, this.nextSibling);
">Insert element</button>

The above could be expanded to create more than one element per call, I'll leave that you.

Another method is to take an HTML string, convert it to an element (or elements) and return it in a document fragment:

<script type="text/javascript">

var htmlString = '<p><b>paragraph</b></p>' +
                 '<p>Another p</p>';

function byInnerHTML(s) {
  var d = document.createElement('div');
  d.innerHTML = s;
  var frag = document.createDocumentFragment();

  while (d.firstChild) {
    frag.appendChild(d.firstChild);
  }
  return frag;
}

</script>

<button onclick="
  var newContent = byInnerHTML(htmlString);
  document.body.insertBefore(newContent, this.nextSibling);
">Insert element</button>

The second one returns a document fragment that can be inserted into the page. Of course if you want to generate parts of a table, the second method isn't quite so good.

RobG
  • 142,382
  • 31
  • 172
  • 209
0

In tune with a pure JavaScript implementation, here's my take on the problem:

    function createElement(type, attributes, parent){
    var node = document.createElement(type);

    for (i in attributes){
        node.setAttribute(i, attributes[i])
    }

    if (parent && parent.__proto__.appendChild){
        parent.appendChild(node)
    }

    return node;
}

And you use it like this:

createElement("span", { "id": "theID", "class": "theClass", "title": "theAttribute"}, document.getElementById("theParent"))

I kept one of your initial requirements: append the node to some other element and also return it.

I particularly like RobG's second example with the fragment. Definitely something I'd try if I were using plain strings to represent HTML.

If it doesn't warrant the use-case, it doesn't always make sense to import a JS framework. jQuery is no exception. Should you decide more complex workflows are needed, that's your warrant! ;)

Razvan Caliman
  • 4,509
  • 3
  • 21
  • 24