以前にウェブサイト上表示されているログをボタンを押すことでクリップボードにコピーできる機能を vue-clipboard2 (opens new window)というモジュールを使って実装したのですが、調べてみたら JavaScript にも Clipboard API というクリップボードをハンドリングできる API があったので調べてみました。
ブラウザの対応状況ですが、IE では全く使えず、他ブラウザは最新バージョンであればサポートされています。
Clipboard API | MDN Web Docs (opens new window)
クリップボードへ書き込み(コピー)するには navigator.clipboard オブジェクトの writeText メソッド を使います。
const text = "コピーテキスト";
navigator.clipboard.writeText(text).then(() => {
alert("コピーしました。");
});
クリップボードへ書き込み(コピー)するには navigator.clipboard オブジェクトの readText メソッド を使います。
navigator.clipboard.readText(text).then(text => {
alert(text);
});
クリップボードの読み書きの他にも、イベントリスナーを登録して、「コピーされた時に〇〇する」といったハンドリングも可能です。
クリップボードにコピーされた時にイベントハンドリングする場合はイベントリスナーにcopy
を登録します。
document.addEventListener("copy", e => {
console.log(e);
});
クリップボードにカットされた時にイベントハンドリングする場合はイベントリスナーにcut
を登録します。
document.addEventListener("cut", e => {
console.log(e);
});
クリップボードにペーストされた時にイベントハンドリングする場合はイベントリスナーにpaste
を登録します。
document.addEventListener("paste", e => {
console.log(e);
});
上記で解説した実装サンプルのコードとプレビューになります。
<template>
<div class="clipboard">
<div class="buttons">
<span class="button" @click="onClickWriteText">Sample Text Clip</span>
<span class="button" @click="onClickReadText">Get Clipboard Text</span>
</div>
<textarea class="textarea" rows="4" ref="textarea">
コピー、カット、ペーストしてみてください。
</textarea>
</div>
</template>
<script>
export default {
data() {
return {
text: `Hello
World!`
};
},
mounted() {
const textarea = this.$refs.textarea;
textarea.addEventListener("copy", this.copyEvent);
textarea.addEventListener("cut", this.cutEvent);
textarea.addEventListener("paste", this.pasteEvent);
},
destroyed() {
const textarea = this.refs.textarea;
textarea.removeEventListener("copy", this.copyEvent);
textarea.removeEventListener("cut", this.cutEvent);
textarea.removeEventListener("paste", this.pasteEvent);
},
methods: {
onClickWriteText() {
const text = this.text;
navigator.clipboard
.writeText(text)
.then(() => {
alert(
"サンプルテキストをコピーしました。\n右のボタンを押してみてください。"
);
})
.catch(e => {
console.log(e);
});
},
onClickReadText() {
navigator.clipboard
.readText()
.then(text => {
alert(`クリップボードにコピーされているテキスト:\n${text}`);
})
.catch(e => {
console.log(e);
});
},
copyEvent(e) {
alert("テキストがコピーされました。");
console.log(e);
},
cutEvent(e) {
alert("テキストがカットされました。");
console.log(e);
},
pasteEvent(e) {
alert("テキストがペーストされました。");
console.log(e);
}
}
};
</script>
<style lang="stylus" scoped>
.clipboard
.buttons
margin-bottom 8px
.button
display: inline-block;
padding 4px 16px 6px
border 1px solid #cfcfcf
border-radius 4px
color #fff
background-color #101010
cursor pointer
.textarea
width 240px
</style>