30

'contenteditable'を使用していて、<div/>PASTEを有効にしています。

MicrosoftWordのクリップボードコピーから貼り付けられるマークアップコードの量は驚くべきものです。私はこれと戦っていて、プロトタイプのstripTags()関数を使用してそこに約1/2の方法で到達しました(残念ながら、いくつかのタグを保持することはできないようです)。

しかし、その後も、驚異的な量の不要なマークアップコードになってしまいます。

だから私の質問は、この不要なマークアップの大部分をクリーンアップするいくつかの関数(JavaScriptを使用)、または私が使用できるアプローチはありますか?

4

10 に答える 10

24

これが私が書いた関数で、かなりうまく機能します(とにかく私が知る限り)。

誰かが何かを持っているなら、私は確かに改善の提案を受け入れています。ありがとう。

function cleanWordPaste( in_word_text ) {
 var tmp = document.createElement("DIV");
 tmp.innerHTML = in_word_text;
 var newString = tmp.textContent||tmp.innerText;
 // this next piece converts line breaks into break tags
 // and removes the seemingly endless crap code
 newString  = newString.replace(/\n\n/g, "<br />").replace(/.*<!--.*-->/g,"");
 // this next piece removes any break tags (up to 10) at beginning
 for ( i=0; i<10; i++ ) {
  if ( newString.substr(0,6)=="<br />" ) { 
   newString = newString.replace("<br />", ""); 
  }
 }
 return newString;
}

これがあなたの何人かに役立つことを願っています。

于 2010-05-20T18:16:06.680 に答える
3

私はこれを使用しています:

$(body_doc).find('body').bind('paste',function(e){
                var rte = $(this);
                _activeRTEData = $(rte).html();
                beginLen = $.trim($(rte).html()).length; 

                setTimeout(function(){
                    var text = $(rte).html();
                    var newLen = $.trim(text).length;

                    //identify the first char that changed to determine caret location
                    caret = 0;

                    for(i=0;i < newLen; i++){
                        if(_activeRTEData[i] != text[i]){
                            caret = i-1;
                            break;  
                        }
                    }

                    var origText = text.slice(0,caret);
                    var newText = text.slice(caret, newLen - beginLen + caret + 4);
                    var tailText = text.slice(newLen - beginLen + caret + 4, newLen);

                    var newText = newText.replace(/(.*(?:endif-->))|([ ]?<[^>]*>[ ]?)|(&nbsp;)|([^}]*})/g,'');

                    newText = newText.replace(/[·]/g,'');

                    $(rte).html(origText + newText + tailText);
                    $(rte).contents().last().focus();
                },100);
            });

body_docは編集可能なiframeです。編集可能なdivを使用している場合は、.find('body')部分を削除できます。基本的に、貼り付けイベントを検出し、場所をチェックして新しいテキストをクリーンアップしてから、クリーンアップしたテキストを貼り付けた場所に戻します。(紛らわしいように聞こえます...しかし、それは思ったほど悪くはありません。

setTimeoutが必要なのは、テキストが実際に要素に貼り付けられるまでテキストを取得できないためです。貼り付けが開始されるとすぐに貼り付けイベントが発生します。

于 2011-10-27T20:03:32.403 に答える
3

貼り付けでクリーンアップする完全なCKEditorを使用するか、ソースを確認することができます。

于 2010-05-20T15:21:05.880 に答える
2

を表示する「プレーンテキストとして貼り付け」ボタンを使用<textarea>して、ユーザーがそこにテキストを貼り付けることができるようにしてはどうでしょうか。そうすれば、すべてのタグが削除されます。それが私のCMSで行っていることです。私はWordの混乱を一掃しようとするのをあきらめました。

于 2010-05-20T15:17:47.337 に答える
0

私はずっと前にそのようなことをしました。そこでは、リッチテキストエディタですべてをクリーンアップし、フォントタグをスタイルに、brsをpに変換して、ブラウザ間で一貫性を保ち、特定の醜いものが貼り付けられないようにしました。私は再帰関数を取り、コアロジックを除いてそのほとんどを取り除いたので、これは良い出発点かもしれません(「結果」は結果を蓄積するオブジェクトであり、おそらく文字列に変換するために2回目のパスが必要です)。それがあなたが必要とするものです:

var cleanDom = function(result, n) {
var nn = n.nodeName;
if(nn=="#text") {
    var text = n.nodeValue;

    }
else {
    if(nn=="A" && n.href)
        ...;
    else if(nn=="IMG" & n.src) {
        ....
        }
    else if(nn=="DIV") {
        if(n.className=="indent")
            ...
        }
    else if(nn=="FONT") {
        }       
    else if(nn=="BR") {
        }

    if(!UNSUPPORTED_ELEMENTS[nn]) {
        if(n.childNodes.length > 0)
            for(var i=0; i<n.childNodes.length; i++) 
                cleanDom(result, n.childNodes[i]);
        }
    }
}
于 2010-05-20T18:16:23.090 に答える
0

これは、Wordからのコメントを含め、HTMLテキストからコメントを削除するのに最適です。

function CleanWordPastedHTML(sTextHTML) {
  var sStartComment = "<!--", sEndComment = "-->";
  while (true) {
    var iStart = sTextHTML.indexOf(sStartComment);
    if (iStart == -1) break;
    var iEnd = sTextHTML.indexOf(sEndComment, iStart);
    if (iEnd == -1) break;
    sTextHTML = sTextHTML.substring(0, iStart) + sTextHTML.substring(iEnd + sEndComment.length);
  }
  return sTextHTML;
}
于 2014-11-07T16:11:37.423 に答える
0

改行が文字としてカウントされるという同様の問題があり、それらを削除する必要がありました。

$(document).ready(function(){

  $(".section-overview textarea").bind({
    paste : function(){
    setTimeout(function(){
      //textarea
      var text = $(".section-overview textarea").val();
      // look for any "\n" occurences and replace them
      var newString = text.replace(/\n/g, '');
      // print new string
      $(".section-overview textarea").val(newString);
    },100);
    }
  });
  
});

于 2015-03-24T18:07:08.623 に答える
0

あなたは正規表現でそれを行うことができます

  1. ヘッドタグを外す

  2. スクリプトタグを削除する

  3. スタイルタグを削除する

    let clipboardData = event.clipboardData || window.clipboardData;
    let pastedText = clipboardData.getData('text/html');
    pastedText = pastedText.replace(/\<head[^>]*\>([^]*)\<\/head/g, '');
    pastedText = pastedText.replace(/\<script[^>]*\>([^]*)\<\/script/g, '');
    pastedText = pastedText.replace(/\<style[^>]*\>([^]*)\<\/style/g, '');
    // pastedText = pastedText.replace(/<(?!(\/\s*)?(b|i|u)[>,\s])([^>])*>/g, '');
    

ここにサンプルがあります:https ://stackblitz.com/edit/angular-u9vprc

于 2021-08-01T08:16:56.640 に答える
-1

非表示のテキストエリアに貼り付け、同じテキストエリアからコピーして、ターゲットに貼り付けることができますか?

于 2010-05-20T15:23:42.067 に答える
-4

それを言うのは嫌いですが、私は結局、TinyMCEにWordのがらくたを私が望む方法で処理させることをあきらめました。<span lang="en-US">これで、ユーザーの入力に特定のHTML(たとえば、を探す)が含まれるたびに電子メールが送信され、手動で修正します。

于 2010-05-20T15:25:44.467 に答える