简体   繁体   中英

Cleaning and Merging Inline CSS styles

I am trying to clean up user entered HTML code that has a lot of inline CSS especially spans with styles and I'm not sure where to start. Does anyone know of a way to merge the spans and the styling using JavaScript? I have found ways to convert inline styles by moving all the styling to a style sheet, but that is not yet possible to store the CSS page in our system as it is right now. (Hopefully that will be a goal in the near future, but not my call)

An example - turn this mess:

<span style="font-size: large;"><span style="font-family: arial black,avant garde;"><span style="font-size: xx-large;"><span style="font-size: large;"><span style="font-family: arial black,avant garde;"><span style="font-size: xx-large;"><span style="color: #000000;"><span style="font-size: x-large;"><span style="font-size: large;"><span style="font-family: arial black,avant garde;"><span style="font-size: xx-large;"><span style="color: #000000;"><span style="font-size: x-large;"><a href="index.php?p=75">Home</a></span></span></span></span></span></span></span></span></span></span></span></span></span>

into this:

<span style="font-size: x-large;color: #000000;font-family: arial black,avant garde;"><a href="index.php?p=75">Home</a></span>

How about this?

window.onload = function(){
    var spans = document.querySelectorAll('span');

    for (var i = 0; i < spans.length; i++)
    {
        if (spans[i].hasChildNodes() && spans[i].childNodes.length == 1
            && spans[i].firstChild.tagName == 'SPAN')
        {
            var parent = spans[i];
            var child = spans[i].firstChild;

            // Copy new properties to child.
            for (var j = 0; j < parent.style.length; j++)
            {
                var prop = parent.style[j];
                if (child.style.getPropertyValue(prop) === "")
                {
                    child.style.setProperty(
                        prop,
                        parent.style.getPropertyValue(prop),
                        ''
                    );
                }
            }

            // Replace parent with child.
            parent.parentNode.insertBefore(child, parent);
            parent.parentNode.removeChild(parent);
        }
    }
}

This will find all spans, and merges those which only have a single span child.

This will disregard the use of !important , but I presume that's not being used anyway.

Also, it won't return exactly the same property values since getPropertyValue normalizes them.

Edit:

The above example code reduces the 13 spans in your example down to just one for me, though, Safari throws away some of the styles in the process.

It's fairly simplistic, of course, and just based on one example, since I have no idea what kind of span soup you might be running into, or what kind of results exactly you might be looking for.

For example, you might want to merge spans like this too: <p>foo<span style="font-size: x-large"> <span style="font-size: small">bar</span></span></p> ? You'd end up losing the font size on that space, but that'll only make a tiny difference.

I'm sure there are plenty more cases like that, so it'll come down to how clean you want the end result to be, and how much time you want to spend on fixing all the corner cases.

You can find more information about the DOM methods I used in Mozilla's DOM reference for CSSStyleDeclaration and element , for example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM