2011-05-25 100 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找到最好的所见即所得的编辑器。因此,不要自己创建一些东西,只要使用它并根据您的确切需求进行定制即可。

相关问题