Очистите вставленный текст Microsoft Word, используя JavaScript - PullRequest
23 голосов
/ 20 мая 2010

Я использую «contenteditable» <div/> и включаю PASTE.

Удивительно, сколько кода разметки вставляется из копии буфера обмена из Microsoft Word. Я борюсь с этим и добился примерно 1/2 пути, используя функцию прототипов stripTags() (, которая, к сожалению, не позволяет мне сохранять некоторые теги ).

Однако, даже после этого, я получаю сногсшибательное количество ненужного кода разметки.

Итак, мой вопрос: есть ли какая-то функция (использующая JavaScript) или подход, который я могу использовать, чтобы очистить большую часть этой ненужной разметки?

Ответы [ 9 ]

21 голосов
/ 20 мая 2010

Вот функция, которую я написал, которая выполняет работу довольно хорошо (насколько я могу судить в любом случае).

Я, безусловно, открыт для предложений по улучшению, если у кого-то есть. Спасибо.

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

Надеюсь, это поможет некоторым из вас.

3 голосов
/ 28 октября 2011

Я использую это:

$(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 необходим, потому что вы не можете захватить текст, пока он фактически не вставлен в элемент, события вставки запускаются, как только начинается вставка.

3 голосов
/ 20 мая 2010

Вы можете использовать полный CKEditor , который очищает при вставке, или посмотреть на источник .

2 голосов
/ 20 мая 2010

Как насчет кнопки «вставить как обычный текст», которая отображает <textarea>, позволяя пользователю вставить туда текст? Таким образом, все теги будут удалены для вас. Это то, что я делаю с моей CMS; Я бросил пытаться навести порядок в Word.

0 голосов
/ 24 марта 2015

У меня была похожая проблема, когда разрывы строк считались символами, и мне пришлось их удалить.

$(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 голосов
/ 07 ноября 2014

Это прекрасно работает для удаления любых комментариев из текста HTML, в том числе из Word:

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 голосов
/ 20 мая 2010

Я сделал что-то подобное очень давно, когда полностью очистил содержимое в текстовом редакторе и преобразовал теги шрифтов в стили, brs в p и т. Д., Чтобы сохранить его согласованность между браузерами и предотвратить попадание определенных уродливых вещей. через пасту. Я взял свою рекурсивную функцию и извлек большую часть из нее, за исключением основной логики, это может быть хорошей отправной точкой («результат» - это объект, который накапливает результат, который, вероятно, занимает второй проход для преобразования в строку), если это то, что вам нужно:

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 голосов
/ 20 мая 2010

Ненавижу это говорить, но в конце концов я бросил TinyMCE обрабатывать Word-чушь так, как я хочу. Теперь мне просто отправляется электронное письмо каждый раз, когда вводимые пользователем данные содержат определенный HTML (например, посмотрите <span lang="en-US">), и я исправляю его вручную.

0 голосов
/ 20 мая 2010

Не могли бы вы вставить в скрытую текстовую область, скопировать из той же текстовой области и вставить в свою цель?

...