HTML - DOM

最近在做一个web前端的项目,其中有一个需求便是,如何将HTML与DOM互相转换。


DOM  --->  HTML

DOM向HTML的转换相对比较简单, 因为DOM节点是树状的,我们只需要利用递归遍历整个DOM树,就可以生成比较完整的HTML。

在firebug中有一个相当完善的解决方案,其中对某些类型的节点做了escape, 如果你的生成的结果要求并不是那么严格的话,可以去掉一些代码。

firebug.lib.js
this.getElementHTML = function(element)
{
    var self=this;
    function toHTML(elt)
    {
        if (elt.nodeType == Node.ELEMENT_NODE)
        {
            if (unwrapObject(elt).firebugIgnore)
                return;

            html.push('<', elt.nodeName.toLowerCase());

            for (var i = 0; i < elt.attributes.length; ++i)
            {
                var attr = elt.attributes[i];

                // Hide attributes set by Firebug
                if (attr.localName.indexOf("firebug-") == 0)
                    continue;

                // MathML
                if (attr.localName.indexOf("-moz-math") == 0)
                {
                    // just hide for now
                    continue;
                }

                html.push(' ', attr.nodeName, '="', escapeForElementAttribute(attr.nodeValue),'"');
            }

            if (elt.firstChild)
            {
                html.push('>');

                var pureText=true;
                for (var child = element.firstChild; child; child = child.nextSibling)
                    pureText=pureText && (child.nodeType == Node.TEXT_NODE);

                if (pureText)
                    html.push(escapeForHtmlEditor(elt.textContent));
                else {
                    for (var child = elt.firstChild; child; child = child.nextSibling)
                        toHTML(child);
                }

                html.push('</', elt.nodeName.toLowerCase(), '>');
            }
            else if (isElementSVG(elt) || isElementMathML(elt))
            {
                html.push('/>');
            }
            else if (self.isSelfClosing(elt))
            {
                html.push((isElementXHTML(elt))?'/>':'>');
            }
            else
            {
                html.push('></', elt.nodeName.toLowerCase(), '>');
            }
        }
        else if (elt.nodeType == Node.TEXT_NODE)
            html.push(escapeForTextNode(elt.textContent));
        else if (elt.nodeType == Node.CDATA_SECTION_NODE)
            html.push('<![CDATA[', elt.nodeValue, ']]>');
        else if (elt.nodeType == Node.COMMENT_NODE)
            html.push('<!--', elt.nodeValue, '-->');
    }

    var html = [];
    toHTML(element);
    return html.join("");
};


但是其实这个方法还是遗漏了HTML中的一部分信息: doctype。

为了完全的支持HTML的生成,我又加了一个简单的方法来处理doctype,当然也可以在这个方法体里面进行改动,但基本思路是一样的。

doctype string generate
  createDocTypeString : function (doc) {
    if(!doc.doctype) return "";
    
    var doctype = "<!DOCTYPE";
    
    if(doc.doctype.name) {
      doctype += " " + doc.doctype.name;
    }
    
    if(doc.doctype.publicId) {
      doctype += " PUBLIC \"" + doc.doctype.publicId + "\"";
    }
    
    if(doc.doctype.systemId) {
      doctype += " \"" + doc.doctype.systemId + "\"";
    }
    
    return doctype += ">"
  }

如果是想在原方法里面处理,则可以采用 elt.nodeType == Node.DOCUMENT_TYPE_NODE 这样的方式。

HTML  --->  DOM

HTML转换成DOM相对比较复杂, 基本上有两种思路:

1. 将HTML中的数据转化成DOM节点树,再通过模糊匹配找到DOM中相应的节点。
2. 在DOM节点中添加额外的attribute,然后通过该attribute属性来实现反向检测。

实现起来两者都比较复杂,但是基本思想还是很简单的。

你可能感兴趣的:(JavaScript,html,Web,Firebug)