【引用】js 相对完美的跨浏览器获取对象的outerHTML

最近在写htmlEditor 有时候需要对 各个浏览器执行execCommand生成的 代码做些格式化操作.

对于ie 确实没啥话说 即有outerHTML又有 document.selection.createRange().htmlText .

但对于其他w3c浏览器 则 需要饶点弯路

即有的一个思路是 通过修改 对象原型.使htmlElement对象具备outerHTML属性

  我不喜欢这种方式.  所以还是剥离出来放到独立的方法中去使用的好.

并且 为了 使其支持 DocumentFragment 即文档片段 所以 我的方法可能有些庞大些. 不过 使用起来 确实可以应付所有需求了.

 

 不多废话了  放 出方法

function getOuterHTML(root, _isDocumentFragment) {
    if (!(root = ID(root))) throw new Error(ns + ‘:getOuterHTML方法 参数有误.’);
    var html = “”;
    if (root.outerHTML) return root.outerHTML; //ie
    else if (ns.clientBrowser.is_ie && root.nodeType==11) {
        for (var i = 0; i < root.childNodes.length; i++) {
            html += root.childNodes[i].nodeType == 1 ? root.childNodes[i].outerHTML : root.childNodes[i].data;
        }
        return html;
    }
    if (XMLSerializer) {  //串行化xml dom对象.实现outerHTML
        var xml = new XMLSerializer();
        html = xml.serializeToString(root);
        xml=null;
        return html;
    }

    //不支持outerHTML 又不支持xmlSerializer xml核心方法 则 使用递归+循环遍历+节点类型判断 获取outerHTML
    var moz_check = /_moz/i;
    switch (root.nodeType) {
        case Node.ELEMENT_NODE:
        case Node.DOCUMENT_FRAGMENT_NODE:
            var closed;
            if (!_isDocumentFragment) {
                closed = !root.hasChildNodes();
                html = ‘<‘ + root.tagName.toLowerCase();
                var attr = root.attributes;
                for (var i = 0; i < attr.length; ++i) {
                    var a = attr.item(i);
                    if (!a.specified || a.name.match(moz_check) || a.value.match(moz_check)) {
                        continue;
                    }
                    html += ” ” + a.name.toLowerCase() + ‘=”‘ + a.value + ‘”‘;
                }
                html += closed ? ” />” : “>”;
            }
            for (var i = root.firstChild; i; i = i.nextSibling) {
                html += getOuterHTML(i);
            }
            if (!_isDocumentFragment && !closed) {
                html += “</” + root.tagName.toLowerCase() + “>”;
            }
            break;

        case Node.TEXT_NODE:
            html = root.data;
            break;
    }
    return html;
}

该方法 需要的ID方法 你可以替换为 document.getElementById .或干脆去掉 if (!(root = ID(root))) return false;

不过 我仍然给出 ID  方法 .此方法也为 我自己的类库的核心方法之一. 虽然没有 prototype 和jquery 等优秀类库的 $() 那样强大 的选择多样性. 但也还不错.支持多参. 并如果传入参数为对象时,直接返回该对象.

所以 才方便 在其他方法中.需要获取对象时 使用 if (!(root = ID(root))) return false; 来兼容参数. 即可以为对象 或id 字符串.

 //getElementByID()的代替函数. 并可同时接受多个对象参数.
    function ID() {

        if (arguments.length == 0) return false;
        var Elements = [];
        for (var i = 0; i < arguments.length; i++) {
            var Element = arguments[i];
            if (typeof (Element) == ‘string’) Element = document.getElementById(Element);
            if (arguments.length == 1) return Element;
            Elements.push(Element);
        }
        return Elements;
    }

以上方法 都写了些简单注释. 应该可以看得明白了

如果您也试图写一个自己的htmlEditor 或 您常使用document.createDocmentFargment() 方法 去做dom操作

则相信您会喜欢 我提供的这个方法… 希望他对您有些帮助.