首先,请注意,从Word(或任何其他HTML源)粘贴而来的HTML会因源而异。甚至不同版本的Word也会给您根本不同的输入。如果您设计的某些代码完全适合您所拥有的MS Word版本中的内容,则对于其他版本的MS Word可能根本不起作用。
另外,某些来源会粘贴看起来像HTML的内容,但实际上是垃圾。当您将HTML内容粘贴到浏览器中的RTF区域时,您的浏览器与HTML的生成方式无关。不要以您的想象力期望它是有效的。另外,当将HTML插入到RTF区域的DOM中时,您的浏览器将对其进行进一步调整。
由于潜在的输入变化很大,并且由于难以定义可接受的输出,因此很难为这种情况设计合适的滤波器。此外,您无法控制MS Word的未来版本将如何处理其HTML内容,因此您的代码将很难过时。
但是,振作起来!如果世界上所有的问题都是容易解决的,那将是一个非常无聊的地方。有一些潜在的解决方案。可以保留HTML的好部分而丢弃坏的部分。
看起来您基于HTML的RTE就像大多数HTML编辑器一样工作。具体来说,它具有一个iframe,并且在iframe中的文档上,已将designMode设置为\“ on \”。
当iframe内部文档的document4ѭ元素中发生paste事件时,您将想要捕获该事件。我在这里非常具体,因为我必须做到:不要将其捕获在iframe中;不要将其捕获在iframe的窗口中;不要将其捕获在iframe的文档中。将其捕获到iframe中文档的“ 4”元素上。很重要。
var iframe = your.rich.text.editor.getIframe(), // or whatever
win = iframe.contentWindow,
doc = win.document,
body = doc.body;
// Use your favorite library to attach events. Don\'t actually do this
// yourself. But if you did do it yourself, this is how it would be done.
if (win.addEventListener) {
body.addEventListener(\'paste\', handlePaste, false);
} else {
body.attachEvent(\"onpaste\", handlePaste);
}
请注意,我的示例代码已附加了一个名为handlePaste的函数。接下来,我们将继续。粘贴事件很有趣:有些浏览器在粘贴之前将其触发,有些浏览器随后将其触发。您将需要对其进行规范化,以便始终在粘贴之后处理粘贴的内容。为此,请使用超时方法。
function handlePaste() {
window.setTimeout(filterHTML, 50);
}
因此,在粘贴事件后的50毫秒内,将调用filterHTML函数。这是工作的重点:您需要过滤HTML并删除所有不良样式或元素。您在这里有很多烦恼!
我亲自看到MSWord粘贴在以下元素中:
meta
link
style
o:p(不同名称空间中的段落)
shapetype
shape
注释,例如。
font
当然是MsoNormal班。
filterHTML函数应在适当的时候删除它们。您可能还希望删除您认为必要的其他项目。这是一个示例“ 18”,它删除了我上面列出的项目。
// Your favorite JavaScript library probably has these utility functions.
// Feel free to use them. I\'m including them here so this example will
// be library-agnostic.
function collectionToArray(col) {
var x, output = [];
for (x = 0; x < col.length; x += 1) {
output[x] = col[x];
}
return output;
}
// Another utility function probably covered by your favorite library.
function trimString(s) {
return s.replace(/^\\s\\s*/, \'\').replace(/\\s\\s*$/, \'\');
}
function filterHTML() {
var iframe = your.rich.text.editor.getIframe(),
win = iframe.contentWindow,
doc = win.document,
invalidClass = /(?:^| )msonormal(?:$| )/gi,
cursor, nodes = [];
// This is a depth-first, pre-order search of the document\'s body.
// While searching, we want to remove invalid elements and comments.
// We also want to remove invalid classNames.
// We also want to remove font elements, but preserve their contents.
nodes = collectionToArray(doc.body.childNodes);
while (nodes.length) {
cursor = nodes.shift();
switch (cursor.nodeName.toLowerCase()) {
// Remove these invalid elements.
case \'meta\':
case \'link\':
case \'style\':
case \'o:p\':
case \'shapetype\':
case \'shape\':
case \'#comment\':
cursor.parentNode.removeChild(cursor);
break;
// Remove font elements but preserve their contents.
case \'font\':
// Make sure we scan these child nodes too!
nodes.unshift.apply(
nodes,
collectionToArray(cursor.childNodes)
);
while (cursor.lastChild) {
if (cursor.nextSibling) {
cursor.parentNode.insertBefore(
cursor.lastChild,
cursor.nextSibling
);
} else {
cursor.parentNode.appendChild(cursor.lastChild);
}
}
break;
default:
if (cursor.nodeType === 1) {
// Remove all inline styles
cursor.removeAttribute(\'style\');
// OR: remove a specific inline style
cursor.style.fontFamily = \'\';
// Remove invalid class names.
invalidClass.lastIndex = 0;
if (
cursor.className &&
invalidClass.test(cursor.className)
) {
cursor.className = trimString(
cursor.className.replace(invalidClass, \'\')
);
if (cursor.className === \'\') {
cursor.removeAttribute(\'class\');
}
}
// Also scan child nodes of this node.
nodes.unshift.apply(
nodes,
collectionToArray(cursor.childNodes)
);
}
}
}
}
您包括了一些想要过滤的示例HTML,但是没有包括您希望看到的示例输出。如果您更新问题以显示过滤后想要的示例,我将尝试调整filterHTML函数以使其匹配。目前,请考虑将此功能作为设计自己的过滤器的起点。
请注意,此代码不会尝试将粘贴的内容与粘贴之前存在的内容区分开。它不需要这样做;它删除的内容无论出现在哪里都被视为无效。
另一种解决方案是使用正则表达式针对文档正文的“ 20”来过滤这些样式和内容。我走了这条路,建议我在此提出解决方案,以反对它。您将通过粘贴收到的HTML差异很大,以至于基于正则表达式的解析将很快遇到严重的问题。
编辑:
我想我现在知道了:您正在尝试自己删除内联样式属性,对吗?如果是这样,您可以在filterHTML函数中通过添加以下行来做到这一点:
cursor.removeAttribute(\'style\');
或者,您可以定位要删除的特定内联样式,如下所示:
cursor.style.fontFamily = \'\';
我已经更新了filterHTML函数以显示这些行的位置。
祝您好运,编码愉快!