概要React mouse event handlerからexecCommand( 'copy')への呼び出しを成功させるには?
私はこのような単純なHTMLボタンのイベントハンドラのコードをトリガーする場合(クローム、エッジとIE11で)働くクリップボードにテキストをコピーするために、小さな方法を書いた:
class MyController
{
constructor()
{
...
testButton_.onclick = (event: MouseEvent) => { this.onTestButtonClicked(event); }
...
}
onTestButtonClicked(event: MouseEvent)
{
Utilities.copyTextToClipboard("Testing the clipboard functionality!");
}
...
}
ここで、testButton_はHTMLButtonElementです。
Reactコンポーネントのイベントハンドラからこの同じメソッドを呼び出すと、このメソッドはEdgeとChromeでは失敗しますが、IE11では成功します。 document.execCommand("copy")
呼び出しがfalseを返すようです。
Reactマウスイベントハンドラ内からdocument.execCommand("copy")
への呼び出しを成功させる方法を教えてください。
注:ここではhttps://w3c.github.io/editing/execCommand.html#dfn-the-copy-commandの他のさまざまな記事を読んだことがありますが、これはすべてユーザー(右クリック)イベントから呼び出されるため、これがうまくいくと思います(普通のHTMLイベントハンドラ)もReactにあります。
詳細
はこれが反応コンポーネントに何である(私は途中で反応し、活字体使用しています):
class DashboardItemComponent extends React.Component<DashboardItemComponentProps, DashboardItemComponentState>
{
static defaultProps: DashboardItemComponentProps = {
projectName: ""
};
constructor(props: DashboardItemComponentProps)
{
super(props);
this.onContextMenu = this.onContextMenu.bind(this);
}
render(): JSX.Element
{
return (
<div onContextMenu={this.onContextMenu}>
<div className="inner">
<header>
<h2>{this.props.projectName}</h2>
</header>
<div>more text</div>
</div>
</div>
);
}
protected onContextMenu(e: React.MouseEvent)
{
e.preventDefault();
Utilities.copyTextToClipboard("testing 1 2 3");
}
}
そして、これはcopyTextToClipboard方法には何があります私のUtilitiesクラス(SOの他の投稿から集められた部分ですが、このコードはうまくいきます):
static copyTextToClipboard(text: string): boolean
{
// Find the dummy text area or create it if it doesn't exist
const dummyTextAreaID = "utilities-copyTextToClipboard-hidden-TextArea-ID";
let dummyTextArea: HTMLTextAreaElement = document.getElementById(dummyTextAreaID) as HTMLTextAreaElement;
if (!dummyTextArea)
{
console.log("Creating dummy textarea for clipboard copy.");
let textArea = document.createElement("textarea");
textArea.id = dummyTextAreaID;
// Place in top-left corner of screen regardless of scroll position.
textArea.style.position = "fixed";
textArea.style.top = "0";
textArea.style.left = "0";
// Ensure it has a small width and height. Setting to 1px/1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = "1px";
textArea.style.height = "1px";
// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = "0";
// Clean up any borders.
textArea.style.border = "none";
textArea.style.outline = "none";
textArea.style.boxShadow = "none";
// Avoid flash of white box if rendered for any reason.
textArea.style.background = "transparent";
document.querySelector("body").appendChild(textArea);
dummyTextArea = document.getElementById(dummyTextAreaID) as HTMLTextAreaElement;
console.log("The dummy textarea for clipboard copy now exists.");
}
else
{
console.log("The dummy textarea for clipboard copy already existed.")
}
// Set the text in the text area to what we want to copy and select it
dummyTextArea.value = text;
dummyTextArea.select();
// Now execute the copy command
try
{
let status = document.execCommand("copy");
if (!status)
{
console.error("Copying text to clipboard failed.");
return false;
}
else
{
console.log("Text copied to clipboard.");
return true;
}
}
catch (error)
{
console.log("Unable to copy text to clipboard in this browser.");
return false;
}
}
一度でも動作しませんか?それとも最初に働いていて失敗していますか? – Arpit
これはプレーンなHTMLイベントハンドラとIE11のReactイベントハンドラでは常に動作しますが、EdgeやChromeのReactイベントハンドラでは一度も動作しません。テキストエリアを作成してテキストを選択しますが、executeCommand(Chromeバージョン62.0.3202.94を使用)ではエラーが発生します。 –
ダミーテキストエリアを作成した後に再レンダリングが発生するため、失敗していますか?再レンダリングの場合に役立つように、JSXコンポーネントに「ID」を追加することができます(すべてのJSXコンポーネントに対して一意のIDを持つことをお勧めします)。 – SteveB