首先,請注意,從Word(或任何其他HTML源代碼)粘貼的HTML會因源而異。即使不同版本的Word也會給你提供完全不同的輸入。如果您設計了一些完全適用於MS Word版本的內容的代碼,則對於不同版本的MS Word可能完全不起作用。
此外,一些來源將粘貼看起來像HTML的內容,但實際上是垃圾。將HTML內容粘貼到瀏覽器的富文本區域時,瀏覽器與生成HTML的方式無關。不要指望它在任何想象中都是有效的。另外,當您的瀏覽器插入到您的富文本區域的DOM中時,您的瀏覽器將進一步探索HTML。
由於潛在的輸入變化很大,而且由於可接受的輸出很難定義,因此很難爲這類事情設計合適的過濾器。此外,您無法控制未來版本的MS Word將如何處理其HTML內容,因此您的代碼將難以面向未來。
但是,請記住!如果所有的世界問題都是簡單的問題,那將是一個相當無聊的地方。有一些潛在的解決方案。 可以保留HTML的好的部分並丟棄不好的部分。
它看起來像您的基於HTML的RTE像大多數HTML編輯器那樣工作。具體來說,它有一個iframe,並且在iframe中的文檔中,它已將designMode
設置爲「on」。
如果發生在該iframe中文檔的<body>
元素中,您將要捕獲paste
事件。我在這裏非常具體,因爲我必須這樣做:不要將其困在iframe上;不要把它放在iframe的窗口上;不要將其記錄在iframe的文檔中。將其捕獲到iframe中文檔的<body>
元素上。很重要。
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
- 評論,如
<!-- comment -->
。
font
- 當然還有
MsoNormal
這個類。
filterHTML函數應該在適當的時候刪除它們。如果您認爲有必要,您也可以刪除其他項目。這裏是一個例子filterHTML
,它刪除我上面列出的項目。
// 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函數以匹配。目前,請將此功能作爲設計您自己的過濾器的起點。
請注意,此代碼不會嘗試將粘貼內容與粘貼前存在的內容區分開來。它不需要這樣做;無論它出現在哪裏,它所移除的東西都被認爲是無效的。
另一種解決方案是使用正則表達式對文檔正文的innerHTML
過濾這些樣式和內容。我走了這條路,我建議反對它,贊成我在這裏提出的解決方案。您通過粘貼獲得的HTML會有很大差異,基於正則表達式的解析會很快出現嚴重問題。
編輯:
我想我現在看到:您要刪除內嵌樣式屬性本身,對不對?如果是這樣,你可以通過包含這一行的filterHTML功能中做到這一點:
cursor.removeAttribute('style');
或者,您也可以針對特定去除內嵌樣式像這樣:
cursor.style.fontFamily = '';
我已經更新了filterHTML函數來顯示這些行將在哪裏。
好運和快樂編碼!
很抱歉,您是否將文字複製並粘貼到您的網絡瀏覽器中? – 2011-05-25 13:09:45
葉複製從博客的一個文本,並將其粘貼到HTML編輯器 – 2011-05-25 13:29:14
什麼,你可以嘗試是某種特殊粘貼的像字,但林不知道我完全理解你的問題 – 2011-05-25 15:07:36