近来为公司开发一个资讯发布项目,需要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(" ");
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'属性,否则跨多行或多列的表格会出现错误