复制内容显示navigator.clipboard undefined的问题与解决Cannot read properties of undefined (reading 'writeText')
分析问题
起因是测试提了个不管:点击单号复制小图标,会报脚本错误。
报错信息显示的就是 TypeError: Cannot read properties of undefined (reading ‘writeText’)
但是我自己在本地测试时,是没有问题的,在demo网站也没有问题。
在我要了测试的ip地址去测试,发现确实是会报错。
在查看相关代码发现问题在于,navigator对象下是否有clipboard对象。
复制内容显示navigator.clipboard undefined的问题与解决Cannot read properties of undefined (reading 'w ...
在翻阅MDN文档后,发现问题所在。这个Navigator的clipboard属性是有限制的,必须是在支持的浏览器和安全上下文中可用。那么像我们的本地localhost,和我刚才的demo网站是用https的这些都属于安全上下文,所以测试并没有问题。在测试的机器里,因为是自己的ip域,并不是https。这个功能就会失效,所以就会报错undefined了
复制内容显示navigator.clipboard undefined的问题与解决Cannot read properties of undefined (reading 'w ...
我们可以通过window.isSecureContext来判断是否是安全上下文。
复制内容显示navigator.clipboard undefined的问题与解决Cannot read properties of undefined (reading 'w ...
复制内容显示navigator.clipboard undefined的问题与解决Cannot read properties of undefined (reading 'w ...
如何解决1.代码兼容非安全域的写法。 在安全域下使用 navigator.clipboard 提升效率,非安全域退回到 document.execCommand(‘copy’); 保证功能一直可用。
- const handleCopy = (val) => {
- if (window.isSecureContext && navigator.clipboard) {
- navigator.clipboard
- .writeText(val)
- .then(() => {
- ElMessage({
- showClose: false,
- message: t('audit_center.other_source.success_copy'),
- type: 'success',
- });
- })
- .catch((err) => {
- ElMessage({
- showClose: false,
- message: `${t('audit_center.other_source.fail_copy')}:${err}`,
- type: 'error',
- });
- });
- } else {
- const copyElem = document.createElement('textarea');
- let styles = copyElem.style;
- styles.position = 'fixed';
- styles.zIndex = '0';
- styles.left = '-500px';
- styles.top = '-500px';
- copyElem.value = val;
- document.body.appendChild(copyElem);
- copyElem.focus();
- copyElem.select();
- let result = false;
- result = document.execCommand('copy');
- if (result) {
- ElMessage({
- showClose: false,
- message: t('audit_center.other_source.success_copy'),
- type: 'success',
- });
- copyElem.remove();
- } else {
- ElMessage({
- showClose: false,
- message: `${t('audit_center.other_source.fail_copy')}`,
- type: 'error',
- });
- }
- }
- };
复制代码社区上有很多开源的复制剪切的jS库可以使用,第三方库考虑的比较全面,兼容问题都会处理好。 https://github.com/soerenmartius/vue3-clipboard https://github.com/x-extends/xe-clipboard
PS:上面两个库如果无法下载,可以从本文附件中下载(两个都在附件中) --------------------------vue3-clipboard---------------------------------- Install - npm install --save @soerenmartius/vue3-clipboard
复制代码Import the v-clipboard directive globally src/main.ts - import { createApp } from 'vue'
- import App from './App.vue'
- import { VueClipboard } from '@soerenmartius/vue3-clipboard'
- createApp(App).use(VueClipboard).mount('#app')
复制代码Apply the v-clipboard directive to an element - <template>
- <input v-model="value" />
- <button v-clipboard="value">Copy</button>
- </template>
- <script lang="ts">
- import { defineComponent, ref } from 'vue'
- export default defineComponent({
- setup() {
- const value = ref('lorem')
- return { value }
- },
- })
- </script>
复制代码Copy value of an input, and handle events separately. - <template>
- <input v-model="value" />
- <button
- v-clipboard:copy="value"
- v-clipboard:success="onSuccess"
- v-clipboard:error="onError"
- >
- Copy
- </button>
- </template>
- <script lang="ts">
- import { defineComponent, ref } from 'vue'
- export default defineComponent({
- setup() {
- const value = ref('lorem')
- const onSuccess = () => {
- console.log('success')
- }
- const onError = () => {
- console.log('error')
- }
- return { value, onSuccess, onError }
- },
- })
- </script>
复制代码Standalone usage of the toClipboard function - <template>
- <input v-model="value" />
- <button @click="toClipboard(value)">Copy</button>
- </template>
- <script lang="ts">
- import { defineComponent, ref } from 'vue'
- import { toClipboard } from '@soerenmartius/vue3-clipboard'
- export default defineComponent({
- setup() {
- const value = ref('lorem')
- return { value, toClipboard }
- },
- })
- </script>
复制代码本文示例: - import { toClipboard } from '@soerenmartius/vue3-clipboard';
- const handleCopy = (val) => {
- toClipboard(val)
- .then((res) => {
- ElMessage({
- showClose: false,
- message: t('audit_center.other_source.success_copy'),
- type: 'success',
- });
- })
- .catch((err) => {
- ElMessage({
- showClose: false,
- message: `${t('audit_center.other_source.fail_copy')}:${err}`,
- type: 'error',
- });
- });
- };
复制代码---------------------------------xe-clipboard----------------------------------- Installing - <script src="https://cdn.jsdelivr.net/npm/xe-clipboard"></script>
复制代码Example - <button id="btn1">Copy</button>
复制代码- document.getElementById('btn1').addEventListener('click', function (evnt) {
- // 由于浏览器的安全机制,操作剪贴板必须在事件之内才能有效
- if (XEClipboard.copy('Copy this content to the clipboard.')) {
- alert('Copy success.')
- } else {
- alert('The browser is not supported.')
- }
- })
复制代码
游客,本帖隐藏的内容需要积分高于 2 才可浏览,您当前积分为 0 提取码下载:
|