Ниже представлена упрощенная версия моего приложения, в которой на странице отображается шаблон, который заполняется с помощью двух текстовых полей ввода.
Это приложение типа «генератор шаблонов», и я хочу иметь возможность копировать готовый шаблон, отображаемый на странице, чтобы его можно было вставить в другое место. Чтобы сделать это обычно, вы должны щелкнуть + перетащить, чтобы выделить визуализированный html, затем щелкните правой кнопкой мыши + скопировать или ctrl + c.
Как я могу преобразовать свой HTML-код в визуализированную версию, чтобы я мог скопировать его в буфер обмена с помощью моей кнопки react-clipboard? Или есть другой способ добиться этого?
Если что-то непонятно, дайте мне знать - заранее спасибо
TL; DR: в настоящее время, когда вы нажимаете «копировать в буфер обмена», приложение копирует HTML. Я хочу, чтобы он скопировал содержимое, как если бы оно отображалось на веб-странице. Например, преобразованный и скопированный hello world должен копировать красный h1, который говорит hello world.
import React, { Component } from 'react';
import { TextField } from 'material-ui';
import Clipboard from 'react-clipboard.js';
import './App.css';
const logo = 'https://www.google.co.uk/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png';
class App extends Component {
constructor() {
super();
this.state = {
name: 'Default Name',
title: 'Default Title'
};
}
componentDidMount() {
this.setState({template: this.createTemplate(this.state.name, this.state.title) });
}
createTemplate(name, title) {
const template = `<!DOCTYPE html>
<html>
<head>
<link href = "https://fonts.googleapis.com/css?family=Montserrat:400,700" rel = "stylesheet">
</head>
<body>
<h1>${name}</h1>
<h2>${title}</h2>
</body>
</html>`
this.setState({template});
}
updateValue(event, type) {
if (type === 'name') {
this.setState({name: event.target.value});
this.createTemplate(event.target.value, this.state.title);
} else {
this.setState({title: event.target.value});
this.createTemplate(this.state.name, event.target.value);
}
}
render() {
return (
<div className = "App">
<header className = "App-header">
<img src = {logo} className = "App-logo" alt = "logo" />
<h1 className = "App-title">Signature Builder</h1>
</header>
<div>
<br/>
<TextField hintText = "Name" onChange = {(e) => this.updateValue(e, 'name')} />
<TextField hintText = "Title" onChange = {(e) => this.updateValue(e, 'title')} />
<div style = {{textAlign: 'left', margin: 10}} dangerouslySetInnerHTML = {{ __html: this.state.template }} />
<Clipboard data-clipboard-text = {this.state.template}>
copy to clipboard
</Clipboard>
</div>
</div>
);
}
}
export default App;



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете использовать ReactDOMServer.renderToStaticMarkup для преобразования вашего компонента React в строку без каких-либо специфичных для React тегов. Если вы ожидаете, что HTML будет гидратирован позже, вы можете вместо этого использовать renderToString.
https://reactjs.org/docs/react-dom-server.html
Ой, извините, я совершенно неправильно понял. Вы хотите скопировать форматированный текст из фрагмента HTML? Вы можете попытаться отобразить HTML на странице, выделить его и запустить копию, но никаких гарантий.
Проблема в том, что react-clipboard не поддерживает копирование текста HTML; вам просто нужно будет сделать это с помощью обычного JS. К сожалению, API буфера обмена довольно привередливы.
Некоторые проблемы можно обойти, просто не используя кнопку и фиксируя событие onCopy для изменения содержимого, скопированного в буфер обмена.
const copyAction = e => {
e.preventDefault()
e.clipboardData.setData('text/plain', 'This is plaintext; try pasting into a program that supports rich text')
e.clipboardData.setData('text/html', '<h1>Hello</h1><h2>World</h2>')
console.info('Copy event captured!')
}
const App = () => (
<div onCopy = {copyAction}>
Copy me!
</div>)
ReactDOM.render(<App />,
document.getElementById('root'))<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='root' />Конечно, содержимое самого HTML-текста может быть создано как угодно, будь то с помощью литералов вашего шаблона или с помощью ReactDOMServer, такого как Коривард предложил.
Больше информации:
Это не компонент реакции, хотя это строка (см.
const template) - это, по сути, то, что я хочу скопировать, но «визуализировать», как на веб-странице (или как там это слово). Будет ли с этим работать так же?