歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 關於JavaScript中的復制

關於JavaScript中的復制

日期:2017/3/1 9:18:53   编辑:Linux編程

在做項目時有一個需求,是需要復制內容到剪切板,因為有眾多浏覽器,所以要兼容性很重要

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,

width: 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)

}

}

}

}

}

}

};

Copyright © Linux教程網 All Rights Reserved