web-dev-qa-db-ja.com

JavaScriptを使用してMicrosoft Wordの貼り付けたテキストを消去する

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

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

しかし、その後も、不要なマークアップコードが驚くほど増えます。

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

27
OneNerd

これは、筆者がかなりうまく機能している関数です(とにかくわかる範囲で)。

誰か改善案があれば、私は間違いなく改善の提案を受け入れます。ありがとう。

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;
}

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

21
OneNerd

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

$(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が必要です。貼り付けが開始するとすぐに、pasteイベントが発生します。

3
Daniel Sellers

貼り付け時にクリーンアップする完全な CKEditor または ソースを確認 のいずれかを使用できます。

3
Todd Main

<textarea>、ユーザーがそこにテキストを貼り付けることを許可しますか?そうすれば、すべてのタグが削除されます。それが私のCMSで行うことです。私はWordの混乱を片付けようとあきらめました。

2
Josh

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

$(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);
    }
  });
  
});
0
ericmotil

これは、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;
}
0
user759463

私はずっと前にそのようなことをしました、そこで私はリッチテキストエディターでものを完全にクリーンアップし、フォントタグをスタイル、brsからp'sなどに変換して、ブラウザー間で一貫性を保ち、特定の醜いものがペーストから入り込まないようにしました。私は再帰関数を取り、コアロジックを除いてそのほとんどを取り除きました。これは良い出発点である可能性があります( "結果"は結果を蓄積するオブジェクトであり、おそらく文字列に変換するために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]);
        }
    }
}
0
rob