AngularJS复制到剪贴板

25

有没有一种方法可以创建一个复制按钮,带有复制功能,可以复制模态框的所有内容,并将其粘贴到记事本中?


可能是一个重复的问题:如何在AngularJS中获取剪贴板数据 - cbass
7个回答

30

由于需要复制的文本是动态的,所以我需要在我的Controller中实现此功能,这是基于ngClipboard模块中的代码编写的简单函数:

function share() {
    var text_to_share = "hello world";

    // create temp element
    var copyElement = document.createElement("span");
    copyElement.appendChild(document.createTextNode(text_to_share));
    copyElement.id = 'tempCopyToClipboard';
    angular.element(document.body.append(copyElement));

    // select the text
    var range = document.createRange();
    range.selectNode(copyElement);
    window.getSelection().removeAllRanges();
    window.getSelection().addRange(range);

    // copy & cleanup
    document.execCommand('copy');
    window.getSelection().removeAllRanges();
    copyElement.remove();
}

附言:
欢迎您现在添加评论,告诉我从控制器操作DOM有多糟糕 manipulate DOM from a Controller


1
“从控制器操作DOM是多么糟糕”,就像软件工程中的大多数其他“最佳实践”一样,在某些情况下打破最佳实践是有意义的。我认为这个答案很棒! - Jesus is Lord
ALWAYS!在剪贴板中给我[Object object]... [我的文本是JSON,但我修改了appendChild行为: copyElement.appendChild(document.createTextNode(JSONstringify(text_to_share))); 所以这不应该是问题。 - Hobbamok
@Hobbamok,将最后两行注释掉(清理),然后检查您的开发控制台,看看copyElement是什么样子以及它包含了什么。 - marmor
1
如果您使用createElement("pre")而不是span,那么您可以复制/粘贴漂亮打印的JSON(这样您的漂亮打印的JSON就不会在分配给span内的文本节点时变成单行)。 在Chrome中测试过。 - Dimitry K
or textarea instead of span - regeter

12
如果您使用jquery支持,请使用此指令
.directive('copyToClipboard', function () {
        return {
            restrict: 'A',
            link: function (scope, elem, attrs) {
                elem.click(function () {
                    if (attrs.copyToClipboard) {
                        var $temp_input = $("<input>");
                        $("body").append($temp_input);
                        $temp_input.val(attrs.copyToClipboard).select();
                        document.execCommand("copy");
                        $temp_input.remove();
                    }
                });
            }
        };
    });

HTML

<a href="" copy-to-clipboard="Text to copy">Copy text</a>

10

如果您不想向项目添加新的库并希望自行创建它,这里有一个简单易用的解决方案:

注意:我使用了 Promise 功能来创建它(很棒)

这是 CopyToClipboard.js 模块文件

angular.module('CopyToClipboard', [])
        .controller('CopyToClipboardController', function () {

        })
        .provider('$copyToClipboard', [function () {

            this.$get = ['$q', '$window', function ($q, $window) {
                var body = angular.element($window.document.body);
                var textarea = angular.element('<textarea/>');
                textarea.css({
                    position: 'fixed',
                    opacity: '0'
                });
                return {
                    copy: function (stringToCopy) {
                        var deferred = $q.defer();
                        deferred.notify("copying the text to clipboard");
                        textarea.val(stringToCopy);
                        body.append(textarea);
                        textarea[0].select();

                        try {
                            var successful = $window.document.execCommand('copy');
                            if (!successful) throw successful;
                            deferred.resolve(successful);
                        } catch (err) {
                            deferred.reject(err);
                            //window.prompt("Copy to clipboard: Ctrl+C, Enter", toCopy);
                        } finally {
                            textarea.remove();
                        }
                        return deferred.promise;
                    }
                };
            }];
        }]);

就是这样,感谢https://gist.github.com/JustMaier/6ef7788709d675bd8230

现在让我们来使用它

angular.module('somthing')
   .controller('somthingController', function ($scope, $copyToClipboard) {
       // you are free to do what you want
            $scope.copyHrefToClipboard = function() {
            $copyToClipboard.copy(/*string to be coppied*/$scope.shareLinkInfo.url).then(function () {
                //show some notification
            });
        };
   }

最后是 HTML

<i class="fa fa-clipboard" data-ng-click="copyHrefToClipboard($event)"></i>

希望这可以节省您的时间。


5

document.execCommand现已弃用。您可以使用以下方法:

HTML:

<i class="fa fa-copy" ng-click="copyToClipboard('some text to copy')"></i>

控制器:

$scope.copyToClipboard = function(string) {
    navigator.clipboard.writeText(string)
        .then(console.log('copied!'));          
}

这个是正确的答案!!document.execCommand现在无法工作。 - Ronald Babu
太棒了....运行正常。谢谢兄弟节省时间。造物主保佑你。 - undefined

4

2
谢谢提供的示例,但在Safari中似乎无法正常工作。 - Phil O
干得好,传奇人物。用 ng-copyable 指令救了我的一天。 - Mohammedsalim Shivani

2
在HTML中:
<a href="#" ><img src="/Images/copy.png" ng-click="copyToClipboard("TEXT_YOU_WANTTO_COPY")"></img></a>

在控制器中:

$scope.copyToClipboard = function (name) {
    var copyElement = document.createElement("textarea");
    copyElement.style.position = 'fixed';
    copyElement.style.opacity = '0';
    copyElement.textContent =  decodeURI(name);
    var body = document.getElementsByTagName('body')[0];
    body.appendChild(copyElement);
    copyElement.select();
    document.execCommand('copy');
    body.removeChild(copyElement);
}

document.execCommand现在无法工作。请参考下面@fullstack的答案。 - Ronald Babu

0
尝试这个:
app.service('ngCopy', ['$window', function ($window) {
    var body = angular.element($window.document.body);
    var textarea = angular.element('<textarea/>');
    textarea.css({
        position: 'fixed',
        opacity: '0'
    });

    return function (toCopy) {
        textarea.val(toCopy);
        body.append(textarea);
        textarea[0].select();

        try {
            var successful = document.execCommand('copy');
            if (!successful)
                throw successful;
           
        } catch (err) {
            window.prompt("Copy to clipboard: Ctrl+C, Enter", toCopy);
        }
        textarea.remove();
    }
}]);

你需要在控制器中调用此服务。你可以这样做:

controllers.MyController = ['$scope', 'ngCopy',
function ($scope, ngCopy) {
      ngCopy(copyText);
}];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接