6

ニュースの説明ページに ajax html エディターを使用しています。Word または Internet からコピー ペーストすると、そのテキスト、段落などのスタイルがコピーされ、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; }

4

6 に答える 6

8

まず、Word(またはその他のHTMLソース)から貼り付けることで受け取るHTMLは、ソースによって大きく異なることに注意してください。Wordのバージョンが異なっていても、入力は根本的に異なります。使用しているバージョンのMSWordのコンテンツで完全に機能するコードを設計した場合、別のバージョンのMSWordではまったく機能しない可能性があります。

また、一部のソースはHTMLのように見えるが、実際にはゴミであるコンテンツを貼り付けます。HTMLコンテンツをブラウザのリッチテキスト領域に貼り付ける場合、ブラウザはそのHTMLの生成方法とは何の関係もありません。あなたの想像力の範囲によってそれが有効であると期待しないでください。さらに、ブラウザは、リッチテキスト領域のDOMに挿入されるHTMLをさらに変更します。

潜在的な入力は非常に変化し、許容可能な出力を定義するのは難しいため、この種のものに適切なフィルターを設計することは困難です。さらに、MS Wordの将来のバージョンがHTMLコンテンツを処理する方法を制御できないため、コードの将来性を保証することは困難です。

しかし、心を持ってください!世界の問題がすべて簡単なものだとしたら、それはかなり退屈な場所になるでしょう。いくつかの潜在的な解決策があります。HTMLの良い部分を保持し、悪い部分を破棄することが可能です。

HTMLベースのRTEは、ほとんどのHTMLエディタと同じように機能するようです。具体的には、iframeがあり、iframe内のドキュメントではdesignMode「オン」に設定されています。

そのiframe内のドキュメントpasteの要素で発生したイベントをトラップする必要があります。<body>私はここで非常に具体的である必要があります。iframeにトラップしないでください。iframeのウィンドウにトラップしないでください。iframeのドキュメントにトラップしないでください。<body>iframe内のドキュメントの要素にトラップします。非常に重要です。

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関数を更新して、これらの行がどこに行くかを示しました。

幸運と幸せなコーディング!

于 2011-05-31T14:31:00.890 に答える
2

一般に、エンドユーザーによるHTML編集をサポートする場合、このような処理に必要な機能がすでに組み込まれている、クライアント側の堅実なHTML編集コントロールの1つを利用することを選択しました。Component Artなどの商用バージョンのほか、 CKEditorなどの優れたフリー/オープンソースバージョンがいくつかあります。

すべての優れたものは、この過剰なCSSを取り除く/修正するためのWordからの貼り付けをしっかりとサポートしています。私は1つを活用するか(簡単な方法)、またはそれらがどのようにそれを行うかを確認します(難しい方法)。

于 2011-05-29T02:16:22.503 に答える
2

Firefox を使用している場合は、次の拡張機能をインストールできます: https://addons.mozilla.org/en-US/firefox/addon/extended-copy-menu-fix-vers/。書式設定なしで任意の Web サイトからテキストをコピーできます。

于 2011-05-27T21:06:56.350 に答える
1

私はいつもこの種の問題を抱えていますが、それは興味深いものです。Windows でメモ帳を開き、テキストをメモ帳に貼り付けて、AJAX テキスト エディターにコピーするだけです。すべてのテキスト スタイルが削除されます。

:)

于 2011-06-03T09:09:22.690 に答える
1

あなたの質問から私が理解していることから、あなたは WYSIWYG エディターを使用しています。また、他の Web ページや Word 文書からテキストをコピーして貼り付けると、インライン スタイルなどの醜い html が表示されます。

この問題をクロスブラウザーで処理するのは面倒なので、これを修正する必要はまったくないことをお勧めします。本当に修正したい場合は、TinyMCE を使用することをお勧めします。

http://tinymce.moxiecode.com/tryit/full.phpにアクセスして実際に試してみてください。エディタにテキストをコピーし、それをすべて送信して、生成された html を確認してください。きれいです。

TinyMCE はおそらく、あなたが見つけることができる最高の WYSIWYG エディターです。したがって、自分で何かを構築する代わりに、それを使用して、正確なニーズに合わせてカスタマイズしてください。

于 2011-06-03T09:13:55.470 に答える