开发者

Remove formatting from a contentEditable div

I have a contentEditable Div and I want remove any formatting especially for 开发者_如何转开发copy and paste text.


You can add a listener to the "paste" event and reformat the clipboard contents. Like so:

let editableDiv = document.querySelector('div[contenteditable="true"]');

editableDiv.addEventListener("paste", function(e) {
  e.preventDefault();
  var text = e.clipboardData.getData("text/plain");
  document.execCommand("insertHTML", false, text);
});

Here another example for all containers in the body:

let allEditableDivs = document.querySelectorAll('div[contenteditable="true"]');

[].forEach.call(allEditableDivs, function (el) {
  el.addEventListener('paste', function(e) {
    e.preventDefault();
    var text = e.clipboardData.getData("text/plain");
    document.execCommand("insertHTML", false, text);
  }, false);
}

Saludos.


Have you tried using innerText?

ADDED:

If you want to strip markup from content pasted into the editable div, try the old hack of creating a temporary div -- see example below.

<!DOCTYPE html>
<html>

<head> 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
  <title>Strip editable div markup</title>

  <script type="text/javascript">
    function strip(html) {
      var tempDiv = document.createElement("DIV");
      tempDiv.innerHTML = html;
      return tempDiv.innerText;
    }
  </script>
</head>

<body>
  <div id="editableDiv" contentEditable="true"></div>
  <input type="button" value="press" onclick="alert(strip(document.getElementById('editableDiv').innerText));" />
</body>

</html>


Was looking for answer to this for ages and ended up writing my own.

I hope this helps others. At the time of writing this it appears to work in ie9, latest chrome and firefox.

<div contenteditable="true" onpaste="OnPaste_StripFormatting(this, event);" />

<script type="text/javascript">

    var _onPaste_StripFormatting_IEPaste = false;

    function OnPaste_StripFormatting(elem, e) {

        if (e.originalEvent && e.originalEvent.clipboardData && e.originalEvent.clipboardData.getData) {
            e.preventDefault();
            var text = e.originalEvent.clipboardData.getData('text/plain');
            window.document.execCommand('insertText', false, text);
        }
        else if (e.clipboardData && e.clipboardData.getData) {
            e.preventDefault();
            var text = e.clipboardData.getData('text/plain');
            window.document.execCommand('insertText', false, text);
        }
        else if (window.clipboardData && window.clipboardData.getData) {
            // Stop stack overflow
            if (!_onPaste_StripFormatting_IEPaste) {
                _onPaste_StripFormatting_IEPaste = true;
                e.preventDefault();
                window.document.execCommand('ms-pasteTextOnly', false);
            }
            _onPaste_StripFormatting_IEPaste = false;
        }

    }

</script>


Try <div id="editableDiv" contentEditable="plaintext-only"></div>


I know it's been a while, but I had the same problem. On my case, it's a GWT application to make it even worse. Anyway, resolved the problem with:

var clearText = event.clipboardData.getData('text/plain');
document.execCommand('inserttext', false, clearText);

See: https://jsfiddle.net/erikwoods/Ee3yC/

I preferred "inserttext" command instead of "insertHTML", because the documentation says it's exactly to insert plain text, so seems more suitable. See https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand


With Jquery you can use .text() method, so, when blur for example you can replace the content with the text content

$("#element").blur(function(e) {
    $(this).html($(this).text());
});


You can't access the system clipboard so you'll need a hack. See this question: JavaScript get clipboard data on paste event (Cross browser)


I'd like to add my solution to this issue:

ContentEditableElement.addEventListener('input', function(ev) {
  if(ev.target.innerHTML != ev.target.textContent) {

    // determine position of the text caret
    var caretPos = 0,
      sel, range;
    sel = window.getSelection();
    if (sel.rangeCount) {
      range = sel.getRangeAt(0);
      var children = ev.target.childNodes;
      var keepLooping = true;
      for(let i = 0; keepLooping; i++) {
        if(children[i] == range.commonAncestorContainer || children[i] == range.commonAncestorContainer.parentNode) {
          caretPos += range.endOffset;
          keepLooping = false;
        } else {
          caretPos += children[i].textContent.length;
        }
      }

      // set the element's innerHTML to its textContent
      ev.target.innerHTML = ev.target.textContent;

      // put the caret where it was before
      range = document.createRange();
      range.setStart(ev.target.childNodes[0], caretPos);
      range.collapse(true);
      sel.removeAllRanges();
      sel.addRange(range);
    }
  }
});

(this isn't compatible with older versions of IE)


Just for my later life. ;)

styles.css

/* Not easy to look exactly like input field: */
/* https://stackoverflow.com/a/8957518/1707015 */
.contenteditable_div {
    /* box-shadow: 1px 1px 1px 0 lightgray inset; */
    background-color:#dddddd;
    overflow-wrap:break-word;
    padding:3px;
}

index.html

<!-- Firefox doesn't support contenteditable="plaintext-only" yet! -->
<div class="contenteditable_div" contenteditable="true" id="blubbi">abc</div>

script.js

// Optional: Copy font from other input field:
// $('#blubbi').css('font', $('#blubbi_input_field').css('font'));

$('.contenteditable_div').on('input', function(){
    // problems with setting cursor to beginning of div!
    // this.innerHTML = this.innerText;
    $(this).text($(this).text());
});

Keep in mind that this solution doesn't support or care about line breaks.

And keep in mind that setting the text like this will set the cursor to the beginning of your contenteditable div - while you are typing. Still a good solution if you need it only for copy & paste. Please write a comment if you have an easy solution for this "reverse typing problem" (under 10 lines of code please). ;)

Tested on Firefox 89, Chrome 90 and Safari 14.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜