如何在ReactJS中将富文本格式复制到剪贴板?

时间:2020-03-25 14:56:23

标签: javascript reactjs clipboard richtext

单击按钮时,我需要将JSX元素复制到剪贴板。这种特殊的JSX具有不同的颜色和样式,没有什么太复杂的。实际上,它与我在互联网上找到的唯一可行的解​​决方案非常相似:https://codepen.io/theXstar/pen/EJxWNo

当我在Codepen中运行时,代码可以完美运行。在我的测试环境中,不是。我不知道这是否与无法在React App中运行的本机JavaScript有关。好吧,我以为是JavaScript,对吧?

这就是我一直在尝试的东西:

import React from 'react';
import { Button } from 'antd';
//import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from 'react-html-parser';

const foof = (
    <div className='toBeCopied'>
        You can write some JS to generate this data. 
        It can contain rich stuff.
        <b> test </b> me <i> also </i>
        <div className="green" style={{color: 'green'}}>Hello world</div> , <h3 className="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>
)

class CopyTest extends React.Component {

    enterLoading = () => {
        CopyToClipboard(foof);
    };

    render () {
        return (
            <div>
                <Button type="primary" onClick={this.enterLoading}>
                        Copy To Clipboard
                </Button>

                <div>{ foof }</div>;
            </div>
        )
    }
}

export default CopyTest;

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 vhange 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('*');

    console.log(element)
    console.log(descendents)

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

    console.log(doc.body.createTextRange, window.getSelection)
    console.log(document)
    console.log("document.body", document.body)
    console.log("newElem", newelment)

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

console.log的存在是因为我试图了解它可能在哪里出错,但似乎返回的值很好。唯一返回 undefined 的东西是 doc.body.createTextRange ,但我认为这与我使用的浏览器(Chrome)有关。

代码运行正常。没有错误,没事。但是它不会将任何内容复制到剪贴板。我在做什么错了?

0 个答案:

没有答案
相关问题