zoukankan      html  css  js  c++  java
  • 关于Javascript中的复制

    在做项目时有一个需求,是需要复制内容到剪切板,因为有众多浏览器,所以要兼容性很重要

    1、最简单的copy,只能在IE下使用

    使用clipboardData方法

    <script type="text/javascript">
        function copy(){
            window.clipboardData.setData("text",document.getElementById("name").value);
            alert("The text is on the clipboard, try to paste it!");
        }
    </script> 

    2、跨浏览器的,但是Firefox无法复制

    <head>
        <script type="text/javascript">
            function CopyToClipboard () {
                var input = document.getElementById ("toClipboard");
                var textToClipboard = input.value;
                
                var success = true;
                if (window.clipboardData) { // Internet Explorer
                    window.clipboardData.setData ("Text", textToClipboard);
                }
                else {
                        // create a temporary element for the execCommand method
                    var forExecElement = CreateElementForExecCommand (textToClipboard);
    
                            /* Select the contents of the element 
                                (the execCommand for 'copy' method works on the selection) */
                    SelectContent (forExecElement);
    
                    var supported = true;
    
                        // UniversalXPConnect privilege is required for clipboard access in Firefox
                    try {
                        if (window.netscape && netscape.security) {
                            netscape.security.PrivilegeManager.enablePrivilege ("UniversalXPConnect");
                        }
    
                            // Copy the selected content to the clipboard
                            // Works in Firefox and in Safari before version 5
                        success = document.execCommand ("copy", false, null);
                    }
                    catch (e) {
                        success = false;
                    }
                    
                        // remove the temporary element
                    document.body.removeChild (forExecElement);
                }
    
                if (success) {
                    alert ("The text is on the clipboard, try to paste it!");
                }
                else {
                    alert ("Your browser doesn't allow clipboard access!");
                }
            }
    
            function CreateElementForExecCommand (textToClipboard) {
                var forExecElement = document.createElement ("div");
                    // place outside the visible area
                forExecElement.style.position = "absolute";
                forExecElement.style.left = "-10000px";
                forExecElement.style.top = "-10000px";
                    // write the necessary text into the element and append to the document
                forExecElement.textContent = textToClipboard;
                document.body.appendChild (forExecElement);
                    // the contentEditable mode is necessary for the  execCommand method in Firefox
                forExecElement.contentEditable = true;
    
                return forExecElement;
            }
    
            function SelectContent (element) {
                    // first create a range
                var rangeToSelect = document.createRange ();
                rangeToSelect.selectNodeContents (element);
    
                    // select the contents
                var selection = window.getSelection ();
                selection.removeAllRanges ();
                selection.addRange (rangeToSelect);
            }
        </script>
    </head>
    <body>
        <input id="toClipboard" value="text to clipboard"/>
        <button onclick='CopyToClipboard ()'>Copy text to clipboard</button>
    </body>

    测试后,Firefox访问失败

    3、万能的flash

    不要重复造轮子了,有一个使用广泛的类库ZeroClipboard

    Zero Clipboard 的实现原理 

    Zero Clipboard 利用 Flash 进行复制,之前有 Clipboard Copy 解决方案,其利用的是一个隐藏的 Flash。但最新的 Flash Player 10 只允许在 Flash 上进行操作才能启动剪贴板。所以 Zero Clipboard 对此进行了改进,用了一个透明的 Flash ,让其漂浮在按钮之上,这样其实点击的不是按钮而是 Flash ,也就可以使用 Flash 的复制功能了。 

    • 创建一个透明的flash

    • 将这个flash浮在按钮上层

    • 确定要复制的文本是什么

    • 监听这个透明flash的鼠标点击事件

    • 该flash被点击之后,完成剪切板处理

    对于这几件事,ZeroClipboard分别提供了不同的api,来完成整个需求


    如何使用 Zero Clipboard 

    完整代码直接下载即可

    git clone https://github.com/chenpingzhao/easycopy.git
    

    关于ZeroClipboard.js

    var ZeroClipboard = {
        version: "1.0.7",
        clients: {},
        moviePath: "zeroclipboard.swf",
        nextId: 1,
        $: function(A) {
            if (typeof(A) == "string") {
                A = document.getElementById(A)
            }
            if (!A.addClass) {
                A.hide = function() {
                    this.style.display = "none"
                };
                A.show = function() {
                    this.style.display = ""
                };
                A.addClass = function(B) {
                    this.removeClass(B);
                    this.className += " " + B
                };
                A.removeClass = function(D) {
                    var E = this.className.split(/s+/);
                    var B = -1;
                    for (var C = 0; C < E.length; C++) {
                        if (E[C] == D) {
                            B = C;
                            C = E.length
                        }
                    }
                    if (B > -1) {
                        E.splice(B, 1);
                        this.className = E.join(" ")
                    }
                    return this
                };
                A.hasClass = function(B) {
                    return !!this.className.match(new RegExp("\s*" + B + "\s*"))
                }
            }
            return A
        },
        setMoviePath: function(A) {
            this.moviePath = A
        },
        dispatch: function(D, B, C) {
            var A = this.clients[D];
            if (A) {
                A.receiveEvent(B, C)
            }
        },
        register: function(B, A) {
            this.clients[B] = A
        },
        getDOMObjectPosition: function(C, A) {
            var B = {
                left: 0,
                top: 0,
                 C.width ? C.width : C.offsetWidth,
                height: C.height ? C.height : C.offsetHeight
            };
            while (C && (C != A)) {
                B.left += C.offsetLeft;
                B.top += C.offsetTop;
                C = C.offsetParent
            }
            return B
        },
        Client: function(A) {
            this.handlers = {};
            this.id = ZeroClipboard.nextId++;
            this.movieId = "ZeroClipboardMovie_" + this.id;
            ZeroClipboard.register(this.id, this);
            if (A) {
                this.glue(A)
            }
        }
    };
    ZeroClipboard.Client.prototype = {
        id: 0,
        ready: false,
        movie: null,
        clipText: "",
        handCursorEnabled: true,
        cssEffects: true,
        handlers: null,
        //我们可以通过下面这个api,将flash和按钮重叠,且浮在按钮之上
        glue: function(D, B, E) {
            this.domElement = ZeroClipboard.$(D);
            var F = 99;
            if (this.domElement.style.zIndex) {
                F = parseInt(this.domElement.style.zIndex, 10) + 1
            }
            if (typeof(B) == "string") {
                B = ZeroClipboard.$(B)
            } else {
                if (typeof(B) == "undefined") {
                    B = document.getElementsByTagName("body")[0]
                }
            }
            var C = ZeroClipboard.getDOMObjectPosition(this.domElement, B);
            this.div = document.createElement("div");
            var A = this.div.style;
            A.position = "absolute";
            A.left = "" + C.left + "px";
            A.top = "" + C.top + "px";
            A.width = "" + C.width + "px";
            A.height = "" + C.height + "px";
            A.zIndex = F;
            if (typeof(E) == "object") {
                for (addedStyle in E) {
                    A[addedStyle] = E[addedStyle]
                }
            }
            B.appendChild(this.div);
            this.div.innerHTML = this.getHTML(C.width, C.height)
        },
    
        /*IE 的 Flash JavaScript 通信接口上有一个 bug 。
        你必须插入一个 object 标签到一个已存在的 DOM 元素中。并且在写入 innerHTML 之前请确保该元素已经 appendChild 方法插入到 DOM 中*/
        getHTML: function(D, A) {
            var C = "";
            var B = "id=" + this.id + "&width=" + D + "&height=" + A;
            if (navigator.userAgent.match(/MSIE/)) {
                var E = location.href.match(/^https/i) ? "https://" : "http://";
                C += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="' + E + 'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="' + D + '" height="' + A + '" id="' + this.movieId + '" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="' + ZeroClipboard.moviePath + '" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="' + B + '"/><param name="wmode" value="transparent"/></object>'
            } else {
                C += '<embed id="' + this.movieId + '" src="' + ZeroClipboard.moviePath + '" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="' + D + '" height="' + A + '" name="' + this.movieId + '" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="' + B + '" wmode="transparent" />'
            }
            return C
        },
        hide: function() {
            if (this.div) {
                this.div.style.left = "-2000px"
            }
        },
        show: function() {
            this.reposition()
        },
        destroy: function() {
            if (this.domElement && this.div) {
                this.hide();
                this.div.innerHTML = "";
                var A = document.getElementsByTagName("body")[0];
                try {
                    A.removeChild(this.div)
                } catch (B) {}
                this.domElement = null;
                this.div = null
            }
        },
        /* 因为按钮上漂浮有一个 Flash 按钮,所以当页面大小发生变化时,Flash 按钮可能会错位,就点不着了
         Zero Clipboard 提供了一个 reposition() 方法,可以重新计算 Flash 按钮的位置。我们可以将它绑定到 resize 事件上
         bind(window, "resize", function(){ clip.reposition(); }); 
        
        function bind(obj, type, fn) {
            if (obj.attachEvent) {
                obj['e' + type + fn] = fn;
                obj[type + fn] = function() {
                    obj['e' + type + fn](window.event);
                }
                obj.attachEvent('on' + type, obj[type + fn]);
            } else
                obj.addEventListener(type, fn, false);
        }*/
    
        reposition: function(C) {
            if (C) {
                this.domElement = ZeroClipboard.$(C);
                if (!this.domElement) {
                    this.hide()
                }
            }
            if (this.domElement && this.div) {
                var B = ZeroClipboard.getDOMObjectPosition(this.domElement);
                var A = this.div.style;
                A.left = "" + B.left + "px";
                A.top = "" + B.top + "px"
            }
        },
        setText: function(A) {
            this.clipText = A;
            if (this.ready) {
                this.movie.setText(A)
            }
        },
        addEventListener: function(A, B) {
            A = A.toString().toLowerCase().replace(/^on/, "");
            if (!this.handlers[A]) {
                this.handlers[A] = []
            }
            this.handlers[A].push(B)
        },
        setHandCursor: function(A) {
            this.handCursorEnabled = A;
            if (this.ready) {
                this.movie.setHandCursor(A)
            }
        },
    
        /*鼠标移到按钮上或点击时,由于有 Flash 按钮的遮挡,所以像 css ":hover", ":active" 等伪类可能会失效。
        setCSSEffects() 方法就是解决这个问题。首先我们需要将伪类改成类
         copy - botton: hover {
            border - color: #FF6633;
        }
        可以改成下面的 ":hover" 改成 ".hover" 
        
        copy - botton.hover {
            border - color: #FF6633;
        }
        我们可以调用 clip.setCSSEffects( true ); 这样 Zero Clipboard 会自动为我们处理:将类 .hover 当成伪类 :hover*/
    
        setCSSEffects: function(A) {
            this.cssEffects = !! A
        },
        /*Zero Clipboard 提供了一些事件,你可以自定义函数处理这些事件。
        Zero Clipboard 事件处理函数为 addEventListener(); 例如当 Flash 完全载入后会触发一个事件 "load" 
    
        clip.addEventListener( "load", function(client) { 
            alert("Flash 加载完毕!"); 
        });*/
    
        receiveEvent: function(D, E) {
            D = D.toString().toLowerCase().replace(/^on/, "");
            switch (D) {
                case "load":
                    this.movie = document.getElementById(this.movieId);
                    if (!this.movie) {
                        var C = this;
                        setTimeout(function() {
                            C.receiveEvent("load", null)
                        }, 1);
                        return
                    }
                    if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {
                        var C = this;
                        setTimeout(function() {
                            C.receiveEvent("load", null)
                        }, 100);
                        this.ready = true;
                        return
                    }
                    this.ready = true;
                    this.movie.setText(this.clipText);
                    this.movie.setHandCursor(this.handCursorEnabled);
                    break;
                case "mouseover":
                    if (this.domElement && this.cssEffects) {
                        this.domElement.addClass("hover");
                        if (this.recoverActive) {
                            this.domElement.addClass("active")
                        }
                    }
                    break;
                case "mouseout":
                    if (this.domElement && this.cssEffects) {
                        this.recoverActive = false;
                        if (this.domElement.hasClass("active")) {
                            this.domElement.removeClass("active");
                            this.recoverActive = true
                        }
                        this.domElement.removeClass("hover")
                    }
                    break;
                case "mousedown":
                    if (this.domElement && this.cssEffects) {
                        this.domElement.addClass("active")
                    }
                    break;
                case "mouseup":
                    if (this.domElement && this.cssEffects) {
                        this.domElement.removeClass("active");
                        this.recoverActive = false
                    }
                    break
            }
            if (this.handlers[D]) {
                for (var B = 0, A = this.handlers[D].length; B < A; B++) {
                    var F = this.handlers[D][B];
                    if (typeof(F) == "function") {
                        F(this, E)
                    } else {
                        if ((typeof(F) == "object") && (F.length == 2)) {
                            F[0][F[1]](this, E)
                        } else {
                            if (typeof(F) == "string") {
                                window[F](this, E)
                            }
                        }
                    }
                }
            }
        }
    };
    

      

     参考文章

    http://www.jb51.net/article/22403.htm

    http://www.cnblogs.com/yangjunhua/archive/2012/09/10/2678817.html

    http://jiongks.name/blog/zeroclipboard-intro/

  • 相关阅读:
    主键、外键
    SpringBoot定时任务Scheduled
    启动报DataSource错误
    SpringBoot整合aop
    元数据MetaData(五)
    普通结果集ResultSet和离线结果集RowSet(四)
    Statements、PreparedStatement及CallableStatement(三)
    JDBC数据库连接(二)
    JDBC简介(一)
    【Oracle】常用函数
  • 原文地址:https://www.cnblogs.com/chenpingzhao/p/5165024.html
Copyright © 2011-2022 走看看