4
\$\begingroup\$

I wrote this JavaScript function to change an element tag name to a div.

function divilize(elem) {
    var elemDiv = document.createElement("div");
    var elemAttrs = elem.attributes;
    for (var attr = 0; attr < elemAttrs.length; attr++)
        elemDiv.setAttribute(elemAttrs[attr].name, elemAttrs[attr].value);
    elemDiv.className += 'divilize-'+elem.tagName.toLowerCase();
    while (elem.firstChild)
        elemDiv.appendChild(elem.firstChild);
    elem.parentNode.replaceChild(elemDiv,elem)
}

divilize(document.getElementById('one'));

Basically, it receives an element, creates a div, copies the attributes, adds in a class with the original tag name for styling purposes (I can make a .divilize-span {display: inline;}), and copies over all of the child elements. I designed with fast reusable code in mind and to avoid losing any event handlers.

Let me know your thoughts...

\$\endgroup\$
2
\$\begingroup\$

You will have a css concatenation issue if the passed element already has a class, for example :

<div class="test" id="one"></div>

will turn into :

<div class="testdivilize-span" id="one"></div>

Then on the actual efficiency of the function, I would use standard calls and quicker logic to speed things up :

function divilize(elm) {

   var clone = elm.cloneNode(true);
   var tagName = clone.tagName.toLowerCase(); 

   clone.className += " divilize-"+tagName; 
   elm.outerHTML = clone.outerHTML.replace(tagName, "div");   

}  

@ Fiddle

|improve this answer|||||
\$\endgroup\$
  • 1
    \$\begingroup\$ Unfortunately, the outerHTML method unbinds event listeners. Try commenting/uncommenting the call function here: jsfiddle.net/ckb11fuL/2 \$\endgroup\$ – henryaaron Mar 20 '17 at 22:13
1
\$\begingroup\$

You don't specify for what purpose you're using this function. But if this should work generically, I would address two issues:

Valid HTML

With the current solution, you tend to produce invalid HTML or even unexpected behavior. Consider these examples:

<ul>
    <li id="target">1</li>
</ul>

<form id="target">
    <input type="text">
</form>

<input type="text" id="target">
  1. Will create a div as a direct child of an ul, which is invalid.
  2. Will remove the form-element and create orphan form fields.
  3. Removes a GUI element completely.

To address that, you can create a list of elements that can't be converted, like:

var invalidNodeNames = ['UL', 'LI', 'FORM', 'INPUT', 'TD', 'IMG', …];

And test for these:

if (-1 != invalidNodeNames.indexOf(elem.nodeName)) {
    return;
}

Valid attributes

Actually a div-element can only have Global attributes. Furthermore notes on invalid documents say:

If a user agent encounters an attribute it does not recognize, it should ignore the entire attribute specification (i.e., the attribute and its value).

But this doesn't mean, that an invalid attribute will have:

  • a CSS meaning [type="checkbox"] { border: 1px solid red; }
  • a meaning and behavior in the feature, when it becomes a valid attribute.

That being said, it doesn't do much harm, but you could cleanup invalid attributes. If you think you need them at some point in the future, you can still add them as valid data-*-attributes. For example:

var validAttributes = ['accesskey', 'class', 'contenteditable', …];

if (-1 != validAttributes.indexOf(attribute.name) ||
     0 == attribute.name.indexOf('data-') ||
     0 == attribute.name.indexOf('aria-') {
    element.setAttribute(attribute.name, attribute.value);
} else {
    element.setAttribute('data-divilized-' + attribute.name, attribute.value);
}

Which results in:

<blockquote style="color: red;" cite="http://www.w3.org">…</blockquote>

<div style="color: red;" data-divilized-cite="http://www.w3.org">…</div>
|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Thanks, yes for now it will be more primitive for my use. I do plan on making it more sophisticated if I push it to git. \$\endgroup\$ – henryaaron Mar 21 '17 at 19:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.