How to Copy Rich Text Contents to the Clipboard With JavaScript

How can I copy rich text contents to the clipboard with JavaScript?

i searched for a week now and finally found my answer!!!
for those of you looking to copy rich text to the clipboard with javascript, then use the function at the link below, works like a charm.
no need of flash and other stuff suggested :)

Copying an image to clipboard using JavaScript/jquery

Copy rich text to clipboard with styles from css-classes

The line break added to copied text happen because the "block level elements" even if you add "display : inline" in css sheet

See W3 HTML Block and Inline Elements

To avoid this we need to change any block level elements that has display inline and restore all style include default style to new tag

Finally the code will be like :

Codepen

Note : explanation in code comment

function CopyToClipboard(element) { // array off all block level elements var block_level_elements = ['P','H1', 'H2', 'H3', 'H4', 'H5', 'H6','OL', 'UL','DIV','FORM','HR','TABLE']; 
//create new Element so we can change elments like we need var newelment = document.createElement("div");
//copy target Element to the new Element newelment.innerHTML = document.getElementById(element).innerHTML;
//hide new Element to body newelment.style.opacity = 0; // add new Element to body document.body.appendChild(newelment);
//get all element childs var descendents = newelment.getElementsByTagName('*');
//loop in childs for (var i = 0; i < descendents.length; ++i) { //get defult Style var style = window.getComputedStyle(descendents[i]); var dis = style.getPropertyValue('display'); //get defult tag name var tagname = descendents[i].tagName; //--------------------------- //this part is little tricky //--------------------------- //true : Element is a block level elements and css display is inline if(dis.includes("inline") && block_level_elements.includes(tagname)){ //get all Element style include default style var defultcss = document.defaultView.getComputedStyle(descendents[i], "").cssText; //chang Element tag from block level elements to inline level elements (span) descendents[i].outerHTML = descendents[i].outerHTML.replace(new RegExp(tagname, "ig"),"span"); //todo: need to change RegExp to tag name only not inner text //add all Element style include default style to new tag descendents[i].style.cssText = defultcss; } } //-----------------copy new Element-------------- var doc = document; var range, selection; if (doc.body.createTextRange) { range = doc.body.createTextRange(); range.moveToElementText(newelment); range.select(); } else if (window.getSelection) { selection = window.getSelection(); range = doc.createRange(); range.selectNodeContents(newelment); selection.removeAllRanges(); selection.addRange(range); } document.execCommand('copy'); window.getSelection().removeAllRanges(); // remove new Element from document document.body.removeChild(newelment); document.getElementById("copybtn").innerHTML="Copied"; }
.green {  display: inline;  color: green;  white-space: nowrap;}
  <button id='copybtn' onclick="CopyToClipboard('foo')">  Copy the stuff  </button>  <div id='foo'>  You can write some JS to generate this data.   It can contain rich stuff.  <b> test </b> me <i> also </i>  <div class="green" style="color: green;">Hello world</div> , <h3 class="green" style="color: green;">header3</h3> You can use setData to put TWO COPIES into the same clipboard, one that is plain and one that is rich. That way your users can paste into either a  <ul>    <li>plain text editor</li>    <li>or into a rich text editor</li>  </ul></div>

Copy content of rich editor using Javascript

I've been working on this for a while, and I finally got it! The vue2-editor uses a contenteditable div for it's text editor. This is why you can't use the .select() method. Use

console.log("selecting");
const e = document.querySelector("#app .ql-editor");
const textNode = e.childNodes[0];
const r = document.createRange();
const startIndex = 0;
r.setStart(e, startIndex);
r.setEnd(e, e.children.length);
const s = window.getSelection();
s.removeAllRanges();
s.addRange(r);
document.execCommand("copy")

I'm not a vue expert that's why I'm not using refs, I'm sure you should here is an example that shows what I mean.

Javascript - Copy string to clipboard as text/html

I have done a few modifications on Loilo's answer above:

  • setting (and later restoring) the focus to the hidden div prevents FF going into endless recursion when copying from a textarea

  • setting the range to the inner children of the div prevents chrome inserting an extra <br> in the beginning

  • removeAllRanges on getSelection() prevents appending to existing selection (possibly not needed)

  • try/catch around execCommand

  • hiding the copy div better

On OSX this will not work. Safari does not support execCommand and chrome OSX has a known bug https://bugs.chromium.org/p/chromium/issues/detail?id=552975

code:

clipboardDiv = document.createElement('div');
clipboardDiv.style.fontSize = '12pt'; // Prevent zooming on iOS
// Reset box model
clipboardDiv.style.border = '0';
clipboardDiv.style.padding = '0';
clipboardDiv.style.margin = '0';
// Move element out of screen
clipboardDiv.style.position = 'fixed';
clipboardDiv.style['right'] = '-9999px';
clipboardDiv.style.top = (window.pageYOffset || document.documentElement.scrollTop) + 'px';
// more hiding
clipboardDiv.setAttribute('readonly', '');
clipboardDiv.style.opacity = 0;
clipboardDiv.style.pointerEvents = 'none';
clipboardDiv.style.zIndex = -1;
clipboardDiv.setAttribute('tabindex', '0'); // so it can be focused
clipboardDiv.innerHTML = '';
document.body.appendChild(clipboardDiv);

function copyHtmlToClipboard(html) {
clipboardDiv.innerHTML=html;

var focused=document.activeElement;
clipboardDiv.focus();

window.getSelection().removeAllRanges();
var range = document.createRange();
range.setStartBefore(clipboardDiv.firstChild);
range.setEndAfter(clipboardDiv.lastChild);
window.getSelection().addRange(range);

var ok=false;
try {
if (document.execCommand('copy')) ok=true; else utils.log('execCommand returned false !');
} catch (err) {
utils.log('execCommand failed ! exception '+err);
}

focused.focus();
}

see jsfiddle where you can enter html segment into the textarea and copy to the clipboard with ctrl+c.



Related Topics



Leave a reply



Submit