主题: 关于Table表格错乱及丢失标记问题(已解决,附解决方法)
作者: Zxxk, 发布日期: 2009-06-07 12:34:44, 浏览数: 6257

近来为公司开发一个资讯发布项目,需要HTML编辑器,选来选去,感觉kindeditor用起来还不错...

在测试过程中发现表格处理出现比较大的BUG,原本正常的表格经过编辑器处理后会导致表格错乱以及标记丢失..

在论坛上找到的解决方法是把filterMode设为false,但这样一来,就不能输出标准的xhtml代码,而这正是本人冲着这编辑器来的主要原因,如果不支持xhtml就没意义了.

由于项目已经接近完工,所以等不急开发者解决就决定自行研究了.

废话不多说了,正入主题:

首先,我用Firefox,Opera都会出现同样的错误,排除IE浏览器childNode兼容问题.

然后再进一步的分析转换xhtml代码,发现两处问题:

1,var startTags = []; var setStartTag...;var setEndTag...这3个定义是所有节点共用的...当每个ChildNode里有着相同的tagName名称的节点的时候,是会冲突的,应该按顶级节点处理,所以就需要重新定义,所以把它放在var scanNodes 里面

2,在用for列出所有的子节点(nodes),而此子节点无下属节点的时候,在结尾少了一个setEndTag();即是switch (node.nodeType) {}后面需要一个setEndTag();

 

解决后的代码:

    outputHtml: function(id, element) {
        var htmlTags = KE.g[id].htmlTags;
        var htmlList = [];
        var scanNodes = function(el) {
            var startTags = [];
            var setStartTag = function(tagName, attrStr, styleStr, endFlag) {
                var html = '';
                html += '<' + tagName;
                if (attrStr) html += attrStr;
                if (styleStr) html += ' style="' + styleStr + '"';
                html += endFlag ? ' />' : '>';
                if (KE.browser == 'IE' && endFlag && KE.util.inArray(tagName, ['br', 'hr'])) html += "\n";
                htmlList.push(html);
                if (!endFlag) startTags.push(tagName);
            };
            var setEndTag = function() {
                if (startTags.length > 0) {
                    var endTag = startTags.pop();
                    var html = '</' + endTag + '>';
                    if (KE.browser == 'IE' && KE.util.inArray(endTag, ['p', 'div', 'table', 'tr', 'ol', 'ul'])) html += "\n";
                    htmlList.push(html);
                }
            };

            var nodes = el.childNodes;
            for (var i = 0, len = nodes.length; i < len; i++) {
                var node = nodes[i];
                switch (node.nodeType) {
                    case 1:
                        var tagName = node.tagName.toLowerCase();
                        if (typeof htmlTags[tagName] != 'undefined') {
                            var attrStr = '';
                            var styleStr = '';
                            var attrList = htmlTags[tagName];
                            var endFlag = false;
                            for (var j = 0, l = attrList.length; j < l; j++) {
                                var attr = attrList[j];
                                if (attr == '/') endFlag = true;
                                else if (attr.charAt(0) == '.') {
                                    var key = attr.substr(1);
                                    var arr = key.split('-');
                                    var jsKey = '';
                                    for (var k = 0, length = arr.length; k < length; k++) {
                                        jsKey += (k > 0) ? arr[k].charAt(0).toUpperCase() + arr[k].substr(1) : arr[k];
                                    }
                                    if (key == 'border') {
                                        if (node.style.border) {
                                            styleStr += 'border:' + node.style.border + ';';
                                        } else if (node.style.borderWidth && node.style.borderStyle && node.style.borderColor) {
                                            styleStr += 'border:' + node.style.borderWidth + ' ' + node.style.borderStyle + ' ' + node.style.borderColor + ';';
                                        }
                                    } else if (key == 'margin') {
                                        if (node.style.margin) {
                                            styleStr += 'margin:' + node.style.margin + ';';
                                        } else {
                                            if (node.style.marginLeft) styleStr += 'margin-left:' + node.style.marginLeft + ';';
                                            if (node.style.marginRight) styleStr += 'margin-right:' + node.style.marginRight + ';';
                                            if (node.style.marginTop) styleStr += 'margin-top:' + node.style.marginTop + ';';
                                            if (node.style.marginBottom) styleStr += 'margin-bottom:' + node.style.marginBottom + ';';
                                        }
                                    } else if (key == 'padding') {
                                        if (node.style.padding) {
                                            styleStr += 'padding:' + node.style.padding + ';';
                                        } else {
                                            if (node.style.paddingLeft) styleStr += 'padding-left:' + node.style.paddingLeft + ';';
                                            if (node.style.paddingRight) styleStr += 'padding-right:' + node.style.paddingRight + ';';
                                            if (node.style.paddingTop) styleStr += 'padding-top:' + node.style.paddingTop + ';';
                                            if (node.style.paddingBottom) styleStr += 'padding-bottom:' + node.style.paddingBottom + ';';
                                        }
                                    } else {
                                        if (node.style[jsKey]) styleStr += key + ':' + node.style[jsKey] + ';';
                                    }
                                } else {
                                    var val = node.getAttribute(attr);
                                    if (val != null && val !== '') {
                                        if (tagName == 'td' && (attr == 'colspan' || attr == 'rowspan')) {
                                            if (parseInt(val) > 1) attrStr += ' ' + attr + '="' + val + '"';
                                        }
                                        else {
                                            if (typeof val == 'string' && val.match(/^javascript:/)) val = '';
                                            if ((tagName == 'a' && attr == 'href') || (tagName == 'img' && attr == 'src') ||
                                        (tagName == 'embed' && attr == 'src')) val = KE.util.removeDomain(id, val);
                                            attrStr += ' ' + attr + '="' + val + '"';
                                        }
                                    }
                                }
                            }
                            setStartTag(tagName, attrStr, styleStr, endFlag);
                        }
                        if (node.hasChildNodes()) {
                            scanNodes(node);
                        } else {
                            if (startTags.length > 0) {
                                var prevHtml = htmlList[htmlList.length - 1];
                                if (prevHtml.match(/^<p|^<div/) != null) {
                                    htmlList.push("&nbsp;");
                                    setEndTag();
                                }
                            }
                        }
                        break;
                    case 3:
                        htmlList.push(KE.util.escape(node.nodeValue));
                        break;
                    default:
                        break;
                }
                setEndTag();
            }
            setEndTag();
        };
        scanNodes(element);
        return htmlList.join('');
    }

 

最后测试,一切正常

PS:Tags定义的时候,td需要多加两个'colspan', 'rowspan'属性,否则跨多行或多列的表格会出现错误

作者: Roddy, 发布日期: 2009-06-07 17:12:28
 谢谢你分享经验,我会更新到新版本当中。
回复
发表新帖 发表回复