2023-01-10 17:11:39 +08:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="en">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<title>临时粘贴板</title>
|
|
|
|
|
<link rel="stylesheet" type="text/css" href="./waves.min.css?v=0.7.2">
|
|
|
|
|
<style>
|
|
|
|
|
|
|
|
|
|
body {
|
|
|
|
|
width: 100%;
|
|
|
|
|
margin: 5px -10px;
|
|
|
|
|
padding: 0 5px 0 14px;
|
|
|
|
|
position: absolute;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 输入框 */
|
|
|
|
|
.dzm-textarea {
|
|
|
|
|
padding: 5px;
|
2023-03-03 11:07:59 +08:00
|
|
|
|
width: 95%;
|
|
|
|
|
border: 1px solid #019aff;
|
2023-01-10 17:11:39 +08:00
|
|
|
|
border-radius: 3px;
|
|
|
|
|
position: fixed;
|
2023-03-03 11:07:59 +08:00
|
|
|
|
height: 97%;
|
2023-01-10 17:11:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 输入框为空时显示 placeholder */
|
|
|
|
|
.dzm-textarea:empty:before {
|
|
|
|
|
content: attr(placeholder);
|
|
|
|
|
color: red;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 输入框获取焦点时移除 placeholder */
|
|
|
|
|
.dzm-textarea:focus:before {
|
|
|
|
|
content: none;
|
2023-03-03 11:32:56 +08:00
|
|
|
|
border: 5px solid #019aff;
|
2023-01-10 17:11:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.textcopy {
|
|
|
|
|
position: fixed;
|
2023-03-03 11:07:59 +08:00
|
|
|
|
height: 100px;
|
|
|
|
|
width: 90px;
|
|
|
|
|
right: 5%;
|
|
|
|
|
bottom: 270px;
|
2023-01-10 17:11:39 +08:00
|
|
|
|
transform: translateX(-50%) translateY(-50%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.textcopy a,
|
|
|
|
|
.textcopy a:hover {
|
|
|
|
|
background: #01BCFF;
|
|
|
|
|
margin: 5px;
|
2023-03-03 11:07:59 +08:00
|
|
|
|
width: 60px;
|
|
|
|
|
height: 40px;
|
|
|
|
|
line-height: 1.3em;
|
|
|
|
|
font-size: 30px;
|
2023-01-10 17:11:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.btn {
|
|
|
|
|
color: #fff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
</style>
|
|
|
|
|
<script type="text/javascript" src="./jquery.min.js"></script>
|
|
|
|
|
<script type="text/javascript" src="./waves.min.js?v=0.7.1"></script>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<!-- textarea -->
|
|
|
|
|
<div oninput="textInput()" id="textarea" class="dzm-textarea" contenteditable="true" placeholder="请输入内容"
|
|
|
|
|
style="resize: both; overflow: auto;"></div>
|
|
|
|
|
<label for="copy_content"></label><input id="copy_content" type="text" value="" style="position: fixed;top: -100px;z-index: -10;"/>
|
|
|
|
|
<div class="textcopy">
|
|
|
|
|
<a class="btn float-buttons waves-effect waves-button waves-float" onclick="copyText()">复制</a>
|
|
|
|
|
<a class="btn float-buttons waves-effect waves-button waves-float" onclick="pasteText()">粘贴</a>
|
|
|
|
|
<a class="btn float-buttons waves-effect waves-button waves-float" onclick="openUrl()">打开</a>
|
2023-03-03 11:07:59 +08:00
|
|
|
|
<a class="btn float-buttons waves-effect waves-button waves-float" onclick="clearText()">清除</a>
|
2023-01-10 17:11:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
<script>
|
|
|
|
|
|
|
|
|
|
Waves.attach('.flat-buttons', ['waves-button']);
|
|
|
|
|
Waves.attach('.float-buttons', ['waves-button', 'waves-float']);
|
|
|
|
|
Waves.attach('.float-button-light', ['waves-button', 'waves-float', 'waves-light']);
|
|
|
|
|
$(document).on('ready', function () {
|
|
|
|
|
Waves.init();
|
|
|
|
|
Waves.attach('.drag-ripple', 'waves-block', true);
|
|
|
|
|
Waves.attach('#bg-pattern', null, true);
|
|
|
|
|
});
|
|
|
|
|
const textarea = document.querySelector(".dzm-textarea")
|
|
|
|
|
|
|
|
|
|
function copyText() {
|
|
|
|
|
let nowValue = textarea.innerText;
|
|
|
|
|
if (nowValue === "") {
|
|
|
|
|
nowValue = document.querySelector("#textarea > img").src
|
|
|
|
|
// base64 image
|
|
|
|
|
if (nowValue.startsWith("data")) {
|
|
|
|
|
let type = nowValue.substring(5, nowValue.indexOf(';'))
|
|
|
|
|
let clipboardItemInput
|
|
|
|
|
switch (type) {
|
|
|
|
|
case "image/png":
|
|
|
|
|
clipboardItemInput = new ClipboardItem({
|
|
|
|
|
"image/png": nowValue.slice(23),
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "image/jpeg":
|
|
|
|
|
clipboardItemInput = new ClipboardItem({
|
|
|
|
|
"image/jpeg": nowValue.slice(23),
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "image/gif":
|
|
|
|
|
clipboardItemInput = new ClipboardItem({
|
|
|
|
|
"image/gif": nowValue.slice(23),
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "application/pdf":
|
|
|
|
|
clipboardItemInput = new ClipboardItem({
|
|
|
|
|
"application/pdf": nowValue.slice(23),
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "application/vnd.ms-excel":
|
|
|
|
|
clipboardItemInput = new ClipboardItem({
|
|
|
|
|
"application/vnd.ms-excel": nowValue.slice(23),
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
|
|
|
|
|
clipboardItemInput = new ClipboardItem({
|
|
|
|
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": nowValue.slice(23),
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
|
|
|
|
|
clipboardItemInput = new ClipboardItem({
|
|
|
|
|
"application/vnd.openxmlformats-officedocument.presentationml.presentation": nowValue.slice(23),
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "application/vnd.ms-powerpoint":
|
|
|
|
|
clipboardItemInput = new ClipboardItem({
|
|
|
|
|
"application/vnd.ms-powerpoint": nowValue.slice(23),
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
|
|
|
|
clipboardItemInput = new ClipboardItem({
|
|
|
|
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": nowValue.slice(23),
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "application/msword":
|
|
|
|
|
clipboardItemInput = new ClipboardItem({
|
|
|
|
|
"application/msword": nowValue.slice(23),
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (clipboardItemInput != null) {
|
|
|
|
|
navigator.clipboard.write([clipboardItemInput]);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
const selection = window.getSelection();
|
|
|
|
|
if (selection.rangeCount > 0) selection.removeAllRanges();
|
|
|
|
|
const range = document.createRange();
|
|
|
|
|
range.selectNode(document.querySelector("#textarea > img")); //传入dom
|
|
|
|
|
selection.addRange(range);
|
|
|
|
|
document.execCommand("copy"); //copy是复制
|
|
|
|
|
selection.removeAllRanges(); //清除缓存
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
//获取要赋值的input的元素
|
|
|
|
|
var inputElement = document.getElementById("copy_content");
|
|
|
|
|
// 设置只读,否则移动端会弹出软键盘
|
|
|
|
|
inputElement.setAttribute("readonly", "readonly");
|
|
|
|
|
//给input框赋值
|
|
|
|
|
inputElement.value = textarea.innerText;
|
|
|
|
|
//选中input框的内容
|
|
|
|
|
inputElement.select();
|
|
|
|
|
inputElement.setSelectionRange(0, 9999999999999);
|
|
|
|
|
// 执行浏览器复制命令
|
|
|
|
|
// document.execCommand("Copy");
|
|
|
|
|
navigator.clipboard.writeText(textarea.innerText)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function pasteText() {
|
|
|
|
|
navigator.clipboard.readText()
|
|
|
|
|
.then(text => {
|
|
|
|
|
textarea.innerText = text
|
|
|
|
|
})
|
|
|
|
|
}
|
2023-03-03 11:07:59 +08:00
|
|
|
|
|
|
|
|
|
function clearText() {
|
|
|
|
|
textarea.innerText = ""
|
|
|
|
|
}
|
2023-01-10 17:11:39 +08:00
|
|
|
|
//
|
|
|
|
|
// function appendText() {
|
|
|
|
|
// navigator.clipboard.readText()
|
|
|
|
|
// .then(text => {
|
|
|
|
|
// textarea.innerText = textarea.innerText + text
|
|
|
|
|
// })
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
function openUrl() {
|
2023-03-03 11:07:59 +08:00
|
|
|
|
let url = textarea.innerText;
|
|
|
|
|
if (url.startsWith("http:")) {
|
|
|
|
|
window.open(url)
|
|
|
|
|
} else {
|
|
|
|
|
window.open("https://" + url)
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-10 17:11:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let lastUpdate = null
|
|
|
|
|
let lastValue = ""
|
|
|
|
|
let saveInterval
|
|
|
|
|
window.onload = function () {
|
|
|
|
|
loadValue()
|
|
|
|
|
// 监听页面状态
|
|
|
|
|
document.addEventListener('visibilitychange', function () {
|
|
|
|
|
// 页面状态变化为可见时触发
|
|
|
|
|
if (document.visibilityState === 'hidden') {
|
|
|
|
|
if (lastUpdate != null && Date.now() - lastUpdate > 5000) {
|
|
|
|
|
clearInterval(saveInterval)
|
|
|
|
|
}
|
|
|
|
|
} else if (document.visibilityState === 'visible') {
|
|
|
|
|
loadValue()
|
|
|
|
|
saveInterval = setInterval(() => {
|
|
|
|
|
saveValue()
|
|
|
|
|
}, 1000)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
saveInterval = setInterval(() => {
|
|
|
|
|
saveValue()
|
|
|
|
|
}, 1000)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function saveValue() {
|
|
|
|
|
let nowValue = textarea.innerText;
|
|
|
|
|
if (nowValue === "") {
|
|
|
|
|
nowValue = textarea.innerHTML
|
|
|
|
|
}
|
|
|
|
|
if (lastValue !== nowValue && lastUpdate != null && Date.now() - lastUpdate > 3000) {
|
|
|
|
|
lastValue = nowValue
|
|
|
|
|
var httpRequest = new XMLHttpRequest();// new对象
|
|
|
|
|
httpRequest.open('PUT', '/clipboard', true);// get表示请求方式、url请求的地址
|
|
|
|
|
httpRequest.setRequestHeader("Content-type", "application/json");//post方式需要设置请求头
|
|
|
|
|
var reqParam = {
|
|
|
|
|
'value': nowValue,
|
|
|
|
|
}
|
|
|
|
|
httpRequest.send(JSON.stringify(reqParam));//发送请求 将请求体写在send中
|
|
|
|
|
// 返回处理
|
|
|
|
|
httpRequest.onreadystatechange = function () {
|
|
|
|
|
if (httpRequest.readyState === 4 && httpRequest.status === 200) {
|
|
|
|
|
//success
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function loadValue() {
|
|
|
|
|
var httpRequest = new XMLHttpRequest();// new对象
|
|
|
|
|
httpRequest.open('GET', window.origin + "/clipboard", true);// get表示请求方式、url请求的地址
|
|
|
|
|
httpRequest.send();// 发送请求
|
|
|
|
|
// 返回处理
|
|
|
|
|
httpRequest.onreadystatechange = function () {
|
|
|
|
|
if (httpRequest.readyState === 4 && httpRequest.status === 200) {
|
|
|
|
|
if (httpRequest.responseText.startsWith("<img")) {
|
|
|
|
|
textarea.innerHTML = httpRequest.responseText
|
|
|
|
|
} else {
|
|
|
|
|
textarea.innerText = httpRequest.responseText.replaceAll("\n", "")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function textInput() {
|
|
|
|
|
lastUpdate = Date.now()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
document.querySelector('#textarea').addEventListener('paste', function (e) {
|
|
|
|
|
var cbd = e.clipboardData;
|
|
|
|
|
var ua = window.navigator.userAgent;
|
|
|
|
|
// 如果是 Safari 直接 return
|
|
|
|
|
if (!(e.clipboardData && e.clipboardData.items)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// Mac平台下Chrome49版本以下 复制Finder中的文件的Bug Hack掉
|
|
|
|
|
if (cbd.items && cbd.items.length === 2 && cbd.items[0].kind === "string" && cbd.items[1].kind === "file" &&
|
|
|
|
|
cbd.types && cbd.types.length === 2 && cbd.types[0] === "text/plain" && cbd.types[1] === "Files" &&
|
|
|
|
|
ua.match(/Macintosh/i) && Number(ua.match(/Chrome\/(\d{2})/i)[1]) < 49) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for (var i = 0; i < cbd.items.length; i++) {
|
|
|
|
|
var item = cbd.items[i];
|
|
|
|
|
if (item.kind === "file") {
|
|
|
|
|
var blob = item.getAsFile();
|
|
|
|
|
if (blob.size === 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var reader = new FileReader();
|
|
|
|
|
var imgs = new Image();
|
|
|
|
|
imgs.file = blob;
|
|
|
|
|
reader.onload = (function (aImg) {
|
|
|
|
|
return function (e) {
|
|
|
|
|
aImg.src = e.target.result;
|
|
|
|
|
// chrome下有Bug显示两张图片,此处为兼容处理
|
|
|
|
|
let imgary = $('#textarea > img')
|
|
|
|
|
if (imgary.length > 1) {
|
|
|
|
|
imgary.eq(-1).remove()
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
})(imgs);
|
|
|
|
|
reader.readAsDataURL(blob);
|
|
|
|
|
document.querySelector("#textarea").innerHTML = ""
|
|
|
|
|
document.querySelector('#textarea').appendChild(imgs);
|
|
|
|
|
lastUpdate = Date.now()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, false);
|
|
|
|
|
</script>
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|