【问题标题】:Copy text to clipboard in vaadin 8在vaadin 8中将文本复制到剪贴板
【发布时间】:2019-09-28 06:34:37
【问题描述】:

我想问一下如何在 vaadin 8 java web 应用程序中正确地将一些文本复制到剪贴板。我找到了适用于 Chrome 和 IE 的解决方案,但不适用于 Firefox。

Firefox 总是在控制台中显示错误“document.execCommand('cut'/'copy') was denied because it was not called from inside a short running user-generated event handler.” .

如何让 Firefox 将文本复制到剪贴板的唯一方法是通过一些用户触发的事件处理程序(单击或焦点事件)。但我未能创建或注入此类处理程序到 vaadin 组件(例如 Button 或 MenuItem)。

或者 Firefox 中是否有设置/策略来克服这种行为?

所以我想问一下如何让它工作。

我的解决办法是:

在 my_ui.js 中定义 javascript 辅助函数:

function copy_to_clipboard(elementId, text) {
    if (document.queryCommandSupported('copy')) {
        var e = document.getElementById(elementId);
        if (e != null) {
            e.value = text;
            e.select();
            document.execCommand('copy');
        }
    }
}

在 vaadin 中包含 javascript 依赖项。

Page.getCurrent().addDependency(new Dependency(Type.JAVASCRIPT, "vaadin://my_ui.js"));

使用 HTML 内容创建标签,将几乎不可见的文本区域放入标签中(在 Chrome 中需要至少 1x1px)。

Label clipboardHelperLabel = new Label();
clipboardHelperLabel.setContentMode(ContentMode.HTML);
clipboardHelperLabel.setValue(
    "<textarea " +
        "id=\"clipboard-helper-id\"" +
        "style=\"width: 1px; height: 1px; border: 0px solid black; padding: 0px; margin: 0px;\" " +
    ">" +
    "</textarea>"
);

在java中定义辅助函数。

public static void copyToClipboard(String text) {
    String code = "copy_to_clipboard('clipboard-helper-id','" + text + "');";
    JavaScript.getCurrent().execute(code);
}

在 UI 的 MenuBar 中使用操作定义 MenuItem。

MenuBar toolbar = new MenuBar();
MenuItem copyToClipboardMenuItem = toolbar.addItem(
    "Copy to clipboard",
    e -> {
        String text = "Hello clipboard";
        copyToClipboard(text);
    }
);

这个解决方案在 Chrome 和 IE 中运行良好,我需要让它在 Firefox 中也能运行。

【问题讨论】:

    标签: javascript java web-applications vaadin vaadin8


    【解决方案1】:

    我认为在 Firefox 中没有任何方法可以解除该限制。

    您必须改为使用 JavaScript 向应该触发复制操作的按钮添加客户端点击侦听器,但您还需要主动将内容发送到客户端,而不是仅填充按需提供。用代码表示,可能是这样的:

    JavaScript.getCurrent().execute(
      "document.getElementById('button').addEventListener('click', function() {" +
        "copy_to_clipboard('clipboard-helper-id','" + text + "');" +
      "})");
    

    编辑: 我注意到还有一个用于此目的的附加组件:https://vaadin.com/directory/component/jsclipboard-add-on/overview

    【讨论】:

    • 感谢您的回答。最后我使用了 vaadin jsclipboard 插件。我已将JSClipboard 附加到全局几乎不可见的TextArea 对象和Button 对象。我在 Button 的 focus 事件处理程序中填充 TextArea 内容(在 click 事件之前触发 - 所以当 click 发生时,剪贴板文本已在 TextArea 中准备就绪)。唯一的问题是宽度和高度设置为 1 px 的 TextArea 不是 1x1 px。一些小区域(12x12 像素)仍然可见(可能是滚动按钮)。
    • 我正在使用相同的插件,但使用不透明度来隐藏文本区域,以便它对我的程序可见,但对用户不可见
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 2013-03-22
    • 1970-01-01
    相关资源
    最近更新 更多