Skip to content

navigator.clipboard.readText()和document.execCommand('copy');无法在popup中复制,且无法动态更新popup中的内容 #681

Open
@liangyining

Description

@liangyining

BUG描述
在popup弹窗中,无法执行复制内容(点击复制按钮,剪切板内容还是不改变)

代码如下:

from pywebio import *
from pywebio.output import *
  
  def copy_to_clipboard(text):
      """复制文本到剪贴板,优先使用 Clipboard API,回退到 document.execCommand"""
      run_js("""
          async function copyTextToClipboard(text) {
              try {
                  if (navigator.clipboard) {
                      // 尝试使用现代 Clipboard API
                      await navigator.clipboard.writeText(text);
                      const clipboardContent = await navigator.clipboard.readText(); // 验证剪贴板内容
                      if (clipboardContent === text) {
                          window.alert("复制成功!剪贴板内容已更新。");
                      } else {
                          throw new Error("剪贴板内容未更新!");
                      }
                  } else {
                      // 回退到旧方法:document.execCommand('copy')
                      fallbackCopyTextToClipboard(text);
                  }
              } catch (err) {
                  console.error('Failed to copy text using Clipboard API:', err);
                  fallbackCopyTextToClipboard(text); // 使用回退方法
              }
          } 

          function fallbackCopyTextToClipboard(text) {
              try {
                  const input = document.createElement('textarea');
                  input.style.position = 'fixed'; // 确保元素不会影响页面布局
                  input.style.opacity = 0;         // 隐藏输入框
                  input.value = text;
                  document.body.appendChild(input);
                  input.select();
                  input.setSelectionRange(0, text.length);
  
                  // 尝试复制文本
                  const successful = document.execCommand('copy');
                  document.body.removeChild(input);
  
                  if (successful) {
                      window.alert("复制成功(使用备用方法)!");
                  } else {
                      throw new Error("复制失败:document.execCommand('copy') 返回 false。");
                  }
              } catch (err) {
                  console.error('Failed to copy text using fallback method:', err);
                  window.alert(`复制失败,请检查浏览器权限设置或确保运行在 HTTPS 环境下。\n错误详情:${err.message}`);
              }
          }
          copyTextToClipboard(arguments[0]);
      """, text)
  
  def show_popup(title, valuelist):
     // 显示弹出窗口,并提供复制功能
      if not valuelist:
          toast("没有数据可供显示!", color="error")
          return
  
      with popup(title, size=PopupSize.LARGE, implicit_close=False):
          put_scope('aaa')
  
          # 动态生成表格
          table_data = [
              [index, put_html(f'<span>{v}</span>'), 
               put_button("复制到剪贴板", onclick=lambda x=v: copy_to_clipboard(x))]
              for index, v in enumerate(valuelist, 1)
          ]
  
          # 插入表格到指定 scope
          put_table(
              table_data,
              header=['序号', '节点名称', '操作'],
              scope='aaa'
          ).style(
              "user-select: text; -webkit-user-select: text; "
              "-moz-user-select: text; -ms-user-select: text;"
          )
  
  def main():
      put_markdown("## 弹窗与剪贴板交互示例")
      data = ["节点A", "节点B", "节点C", "节点D"]
      put_button("打开弹窗", onclick=lambda: show_popup("节点列表", data))
  
  if __name__ == '__main__':
      start_server(main, port=8080, debug=True)

环境信息

  • 操作系统及版本: WIN
  • 浏览器及版本: chrome
  • Python版本: 使用 python3.12 查看
  • PyWebIO版本: 使用1.8.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions