/*
查询参数 id
*/
function getQuery(id){
let urlSearchParams = new URLSearchParams(window.location.search);
let params = Object.fromEntries(urlSearchParams.entries());
return params[id];
}
const myStorage = {
//存储
set(key, value) {
localStorage.setItem(key, JSON.stringify(value));
},
//取出数据
get(key) {
try {
const value = localStorage.getItem(key);
if (value === null || value === undefined || value === "") {
return null;
}
return JSON.parse(localStorage.getItem(key));
} catch (err) {
return null
}
},
// 删除数据
remove(key) {
localStorage.removeItem(key);
}
}
function loadJs(url) {
let script = document.createElement('script')
script.src = url
document.querySelector('head').appendChild(script)
}
/*
content : 下载的文本内容
filename :下载的文件名
*/
let html='<div style="color:#f60">++++5555+</div>'
let downloadF = function (content, filename) {
// 创建a标签
let linkNode = document.createElement('a');
linkNode.download = filename;
linkNode.style.display = 'none';
// 利用Blob对象将字符内容转变成二进制数据
let blob = new Blob([content]);
linkNode.href = URL.createObjectURL(blob);
// 点击
document.body.appendChild(linkNode);
linkNode.click();
// 移除
document.body.removeChild(linkNode);
};
let input = document.querySelector("input");//获取到 input 元素对象 用于得到file对象
let img = document.querySelector("img"); //获取 img 元素对象 用于预览
function filedown(e) {
let file = e.target.files[0]; //blob
img.src = URL.createObjectURL(file)
// 创建一个 DOMString,其中包含一个表示参数中给出的对象的URL
}
/*
blob二进制 to base64
*/
function blobToDataURI(blob, callback) {
var reader = new FileReader();
reader.onload = function (e) {
callback(e.target.result);
}
reader.readAsDataURL(blob);
}
/**
* base64 to blob二进制
*/
function dataURItoBlob(dataURI) {
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; // mime类型
var byteString = atob(dataURI.split(',')[1]); //base64 解码
var arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组
var intArray = new Uint8Array(arrayBuffer); //创建视图
for (var i = 0; i < byteString.length; i++) {
intArray[i] = byteString.charCodeAt(i);
}
return new Blob([intArray], {type: mimeString});
}
/*
e : 移动的元素选择器
*/
class move {
constructor(e) {
this.targetElement = document.querySelector(e)
this.x = 0
this.y = 0
this.ismove = 0
this.init()
}
init() {
this.targetElement.style.position = 'fixed'
this.targetElement.style.zIndex = '9999999'
this.targetElement.addEventListener('mousedown', (e) => {
this.ismove = 1
this.x = e.offsetX
this.y = e.offsetY
})
window.addEventListener('mouseup', () => {
this.ismove = 0
})
window.addEventListener('mousemove', (e) => {
if (this.ismove == 1) {
this.targetElement.style.left = e.clientX - this.x + 'px'
this.targetElement.style.top = e.clientY - this.y + 'px'
}
})
}
}
/*
content : 粘贴的文本内容
*/
function copy(content) {
let value = toString.call(content)=='[object Array]'?content.join('\n'):content
let textarea = document.createElement("textarea");
// let value = '第一行字符串\n第二行字符串'
document.body.appendChild(textarea);
textarea.value = value;
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
}
let root = this;
/**
* WebSocket连接状态枚举
* @type {Readonly<{INIT: symbol, RECONNECTING: symbol, LIVING: symbol, CLOSED: symbol}>}
*/
const SocketState = Object.freeze({
INIT: Symbol("init"),
LIVING: Symbol("living"),
RECONNECTING: Symbol("reconnecting"),
CLOSED: Symbol("green"),
});
/**
* WebSocket重连状态枚举
* @type {Readonly<{INIT: symbol, RECONNECTING: symbol, FAILED: symbol}>}
*/
const ReconnectState = Object.freeze({
INIT: Symbol("init"),
RECONNECTING: Symbol("reconnecting"),
FAILED: Symbol("failed"),
});
class WebsocketClient {
constructor({url, onOpen, onWsMsg, reconnectable=true, reconnectCount=1000}) {
this.url = url;
this.handleOnOpen = onOpen;
this.handleOnMsg = onWsMsg;
//是否允许重连
this.reconnectable = reconnectable;
this.state = SocketState.INIT;
//重连次数, 如果等于-1,会一直重连下去
this.reconnectCount = reconnectCount;
this.socket = undefined;
this.isToClose = false;
}
connect() {
if ('WebSocket' in root) {
this.socket = new WebSocket(this.url);
} else if ('MozWebSocket' in root) {
console.log('ss', 1)
this.socket = new MozWebSocket(this.url);
} else {
throw '当前浏览器不支持websocket';
}
this.socket.binaryType = 'arraybuffer';
this.socket.onopen = this.onOpen;
this.socket.onclose = this.onClose;
this.socket.onmessage = this.onMessage;
this.socket.onerror = this.onError;
}
onOpen = ()=>{
if (this.state === SocketState.RECONNECTING) {
console.log('websocket onOpen: 重连建立完成');
}else{
console.log('websocket onOpen: 连接建立完成');
}
this.state = SocketState.LIVING;
this.handleOnOpen();
}
onClose = ({ code, reason }) => {
console.log(`websocket onClose: 连接被关闭, code: ${code}, reason: ${reason}`);
if (!this.isToClose) {
this.reconnect();
}else{
this.state = SocketState.CLOSED;
}
}
/**
* 收到websocket发来的消息时,直接将其送给wasm
* @param event
*/
onMessage = ({ data }) => {
if (data.byteLength <= 20) {
console.log('websocket recv msg:', data);
}
this.handleOnMsg(data);
}
/**
* 错误处理方法
* @param event
*/
onError = event => {
console.log('websocket onError: 连接出现异常', event);
this.socket = null;
if (this.state === SocketState.LIVING) {
this.reconnect();
}
//这个是重连websocket之后,再次接收到的失败
else if(this.state === SocketState.RECONNECTING){
this.reconnectState = ReconnectState.FAILED;
}
}
reconnect(){
if (this.state === SocketState.RECONNECTING) {
// console.log('临时消息:已经处于重连状态,退出重连处理');
return;
}
this.state = SocketState.RECONNECTING;
this.tryIndex = 0;
if (this.reconnectable) { // 开启了断线重连
console.warn('websocket reconnect: 开始websocket重连流程...');
this.reconnectState = ReconnectState.INIT;
// 断线重连
let tryInterval = setInterval(()=> {
if (this.isToClose) {
console.log('websocket: 连接被标记为退出,则清理掉重连计时器')
clearInterval(tryInterval);
return;
}
if (this.state === SocketState.LIVING) {
console.log('websocket: 重连成功之后,退出重连流程');
clearInterval(tryInterval);
return;
}
//只有等上一次重连失败了,再发起一次新的重连
if ([ReconnectState.INIT, ReconnectState.FAILED].includes(this.reconnectState)) {
this.reconnectState = ReconnectState.RECONNECTING;
this.connect();
}else if(this.reconnectState === ReconnectState.RECONNECTING){
// console.log('正在重连WebSocket中,请耐心等待结果');
return;
}
if (this.reconnectCount>0 && this.tryIndex >= this.reconnectCount) {
console.warn('websocket: 重连websocket失败,超出重连次数' + this.reconnectCount);
clearInterval(tryInterval);
return;
}
this.tryIndex++;
}, 500);
}
}
stop() {
try {
if (this.socket?.readyState === WebSocket.OPEN) {
console.log('websocket stop: 准备断开websocket连接');
this.isToClose = true;
this.socket.close();
} else {
console.log('websocket stop: 连接已经断开,不需要重复操作')
}
}catch (e) {
console.warn('websocket stop: 停止websocket异常', e)
}
}
sendMessage(msg) {
if (this.socket == null) return;
if (this.state === SocketState.LIVING) {
this.socket.send(msg);
}
}
}
let onOpen = () => {
console.log('websocket connection is ok');
}
let onWsMsg = msg => {
console.log('we get a message');
}
//初始化websocket
webSocketClient = new WebsocketClient({url:wsUrl, onOpen, onWsMsg, reconnectable:true});
webSocketClient.connect();
//发送消息
webSocketClient.sendMessage(...)
function formatFileSize(fileSize) {
if (fileSize < 1024) {
return fileSize + 'B';
} else if (fileSize < (1024*1024)) {
var temp = fileSize / 1024;
temp = temp.toFixed(2);
return temp + 'KB';
} else if (fileSize < (1024*1024*1024)) {
var temp = fileSize / (1024*1024);
temp = temp.toFixed(2);
return temp + 'MB';
} else {
var temp = fileSize / (1024*1024*1024);
temp = temp.toFixed(2);
return temp + 'GB';
}
}
// 这里用到一个很实用的 npm 模块,用以在同一行打印文本
var slog = require("single-line-log").stdout;
// 封装的 ProgressBar 工具
function ProgressBar(description, bar_length) {
// 两个基本参数(属性)
this.description = description || "Progress"; // 命令行开头的文字信息
this.length = bar_length || 25; // 进度条的长度(单位:字符),默认设为 25
// 刷新进度条图案、文字的方法
this.render = function (opts) {
var percent = (opts.completed / opts.total).toFixed(4); // 计算进度(子任务的 完成数 除以 总数)
var cell_num = Math.floor(percent * this.length); // 计算需要多少个 █ 符号来拼凑图案
// 拼接黑色条
var cell = "";
for (var i = 0; i < cell_num; i++) {
cell += "█";
}
// 拼接灰色条
var empty = "";
for (var i = 0; i < this.length - cell_num; i++) {
empty += "░";
}
// 拼接最终文本
var cmdText =
this.description +
": " +
(100 * percent).toFixed(2) +
"% " +
cell +
empty +
" " +
opts.completed +
"/" +
opts.total;
// 在单行输出文本
slog(cmdText);
};
}