2017-12-04 9 views
1

概要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; 
    } 
} 
+0

一度でも動作しませんか?それとも最初に働いていて失敗していますか? – Arpit

+0

これはプレーンなHTMLイベントハンドラとIE11のReactイベントハンドラでは常に動作しますが、EdgeやChromeのReactイベントハンドラでは一度も動作しません。テキストエリアを作成してテキストを選択しますが、executeCommand(Chromeバージョン62.0.3202.94を使用)ではエラーが発生します。 –

+0

ダミーテキストエリアを作成した後に再レンダリングが発生するため、失敗していますか?再レンダリングの場合に役立つように、JSXコンポーネントに「ID」を追加することができます(すべてのJSXコンポーネントに対して一意のIDを持つことをお勧めします)。 – SteveB

答えて

0

問題は、特定のDOM要素ではなくドキュメントをコピーしようとしていることです。変更することで、コピーのコードを更新します。

let status = document.execCommand("copy"); 

let toCopy = document.getElementById(dummyTextAreaID) 
let status = toCopy.execCommand("copy"); 

にあなたがからコピーするDOM要素にdummyTextAreaID変更する必要があります。

関連する問題