2011-05-25 53 views
6

我正在使用ajax html編輯器進行新聞描述頁面。當我複製粘貼從字或互聯網的東西,它複製該文本,段落等克服了HTML編輯器文本框的默認類風格的樣式,我想要的是擺脫像下面的內聯樣式,而不是HTML有
我要保留到款如何擺脫在ajax html編輯器中複製和粘貼文本樣式

<span id="ContentPlaceHolder1_newsDetaildesc" class="newsDetails"><span style="font-family: arial, helvetica, sans; font-size: 11px; line-height: 14px; color: #000000; "><strong>Lorem Ipsum</strong>&nbsp;is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.<BR /> It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</span></span></p> 

#left_column .newsDetails span[style] { font-family: Arial !important; font-size: small !important; font-weight: normal !important; color: #808080 !important; }

+0

很抱歉,您是否將文字複製並粘貼到您的網絡瀏覽器中? – 2011-05-25 13:09:45

+0

葉複製從博客的一個文本,並將其粘貼到HTML編輯器 – 2011-05-25 13:29:14

+0

什麼,你可以嘗試是某種特殊粘貼的像字,但林不知道我完全理解你的問題 – 2011-05-25 15:07:36

回答

8

首先,請注意,從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粘貼在以下幾個要素:

  1. meta
  2. link
  3. style
  4. o:p(在不同的命名空間中的段落)
  5. shapetype
  6. shape
  7. 評論,如<!-- comment -->
  8. font
  9. 當然還有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函數來顯示這些行將在哪裏。

好運和快樂編碼!

+0

嗨,日Thnx我的問題的詳細解釋,暫時,而不是刪除其粘貼的文本從複製的源繼承了所有的CSS樣式,我用的!在我的CSS重要的是在來的內聯CSS的粘貼文本。它看起來不是一個正確的方式,我已經更新了上述問題 – 2011-06-01 09:12:55

+0

和我正在使用\t http://www.asp.net/ajax/ajaxcontroltoolkit/samples/htmleditor/htmleditor.aspx – 2011-06-01 09:15:18

+0

偉大的輸入。從頭開始建立一個所見即所得的產品,並且對被粘貼的項目有些格式化感到非常興奮(然後感到震驚)。噓內聯樣式,耶限於正則表達式與主要js刪除代碼湯! – 2013-12-29 19:01:10

4

這是一個潛在的解決方案,可以從HTML中去除文本。它首先將HTML文本複製到一個元素中(這可能應該隱藏,但在我的示例中顯示用於比較)。接下來,你得到該元素的innerText。然後,您可以將該文本放到您的編輯器中,無論你喜歡什麼。您必須在編輯器上捕獲粘貼事件,運行該序列以獲取文本,然後將該文本放在編輯器中的任何位置。

這裏是如何做到這一點的例子的小提琴:由我都選擇利用一些已經擁有堅實的客戶端HTML編輯控件中的一個最終用戶支持HTML編輯時Getting text from HTML

2

一般內置了必要的功能來處理像這樣的東西。有許多商業版本,例如Component Art,以及一些很好的免費/開源版本,如CKEditor

所有的好東西都有固體粘貼到Word的支持來去掉/修復這個過多的CSS。我要麼只是利用一個(簡單的方法),要麼看他們如何做(困難的方式)。

1

我總是得到這樣的問題,這是有趣的。我的方式很簡單,只需在Windows中打開記事本並將文本粘貼到記事本中並複製到您的AJAX文本編輯器。它會去除你所有的文字樣式。

:)

+0

這個問題明確要求保持內容的結構 - 保持html標籤從Word粘貼到Web瀏覽器,但刪除CSS樣式。此外,這個答案不適合開發者,但更多的建議是需要傳達給最終用戶的。 – 2011-06-03 17:05:01

1

從我從你的問題明白了,你使用的是所見即所得的編輯器。而當從其他網頁或Word文檔複製和粘貼文本,你會得到一些醜陋的HTML與內聯樣式等

我會建議你不打擾一切來解決這個問題,因爲它是一個混亂的處理這個問題跨瀏覽器。如果你真的想修復它,雖然我會建議使用TinyMCE,它具有你想要的確切行爲。

您可以通過訪問http://tinymce.moxiecode.com/tryit/full.php嘗試在行動,只是一些文本複製到編輯器,然後提交它都可以看到生成的HTML。它很乾淨。

TinyMCE的可能是,你會IMO找到最好的所見即所得的編輯器。因此,不要自己創建一些東西,只要使用它並根據您的確切需求進行定製即可。

相關問題