如何在ajax html编辑器中摆脱复制粘贴文本样式的问题

|| 我将ajax html编辑器用于新闻描述页面。当我从Word或Internet复制粘贴内容时,它会复制该文本,段落等的样式,从而克服了html编辑器文本框的默认类样式,我想要的是摆脱如下所示的内联样式,而不是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;
}
    
已邀请:
首先,请注意,从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
注释,例如
<!-- comment -->
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函数以显示这些行的位置。 祝您好运,编码愉快!     
这是一个潜在的解决方案,可以从HTML中剥离文本。它的工作原理是首先将文本作为HTML复制到一个元素中(该元素可能应该隐藏,但在我的示例中显示为进行比较)。接下来,您将获得该元素的innerText。然后,您可以随时随地将该文本放入编辑器中。您将必须在编辑器上捕获粘贴事件,运行此序列以获取文本,然后将其放置在编辑器中的任意位置。 这是如何执行此操作的示例的小提琴:从HTML获取文本     
如果您使用的是Firefox,则可以安装此扩展程序:https://addons.mozilla.org/en-US/firefox/addon/extended-copy-menu-fix-vers/。它允许您从任何网站复制文本而无需格式化。     
通常,当支持最终用户进行HTML编辑时,我选择利用许多可靠的客户端HTML编辑控件之一,这些控件已经内置了处理此类问题所需的功能。有许多商业版本,例如来自Component Art,以及一些很棒的免费/开源版本,例如CKEditor。 所有优秀的插件都有可靠的Word粘贴支持,可以去除/修复过多的CSS。我要么只是利用一种方法(简单的方法),要么看看他们是如何做到的(困难的方法)。     
我总是会遇到这种问题,这很有趣。好吧,我的操作非常简单,只需在Windows中打开记事本,然后将文本粘贴到记事本中,然后复制到AJAX文本编辑器中即可。它将删除所有文本样式。 :)     
据我对您所提问题的了解,您正在使用所见即所得的编辑器。从其他网页或Word文档复制和粘贴文本时,您会得到一些带有内联样式的难看的html。 我建议您根本不要去解决此问题,因为跨浏览器处理此问题很麻烦。如果您确实要修复它,我建议您使用TinyMCE,它获得了您想要的确切行为。 您可以通过访问http://tinymce.moxiecode.com/tryit/full.php来尝试使用它,然后将一些文本复制到编辑器中,然后全部提交以查看生成的html。很干净 TinyMCE可能是imo最好的WYSIWYG编辑器。因此,与其单独构建,不如使用它并根据您的实际需求对其进行自定义。     

要回复问题请先登录注册