首页
壁纸
直播
留言
关于
友链
统计
Search
1
tampermonkey油猴和谷歌访问助手的安装---破解谷歌访问助手
13,642 阅读
2
安装postcss-px-to-viewport,将px单位转换为视口单位的 (vw, vh, vmin, vmax) 的 PostCSS 插件(有更新postcss弃用,附带vite.config.ts文件)
3,211 阅读
3
编译asar文件与electron反编译
3,177 阅读
4
websocket封装带心跳和重连机制(vue3+ts+vite)
2,782 阅读
5
js一些小功能(持续更新)
2,442 阅读
大前端
JavaScript
CSS
HTML
框架
Vue
electron
element-ui/plus
小程序
微信小程序
uni-app
服务端
Node.js
nginx
PHP
MySQL
工具
杂记
登录
Search
标签搜索
Vue3
Vue
Axios
微信小程序
Javascript
Vuex
js
请求
request
前端
tampermonkey
Google
助手
脚本
小程序云开发
Bootstrap
壁纸
鼠标事件
跨域
css
大祥子i
累计撰写
55
篇文章
累计收到
128
条评论
首页
栏目
大前端
JavaScript
CSS
HTML
框架
Vue
electron
element-ui/plus
小程序
微信小程序
uni-app
服务端
Node.js
nginx
PHP
MySQL
工具
杂记
页面
壁纸
直播
留言
关于
友链
统计
搜索到
10
篇与
JavaScript
的结果
2022-08-18
websocket封装带心跳和重连机制(vue3+ts+vite)
import { mitts } from "./tool"; /* * @Author: lzx * @Date: 2022-05-25 15:42:37 * @LastEditors: lzx * @LastEditTime: 2022-08-18 15:01:38 * @Description: Fuck Bug * @FilePath: \talk_pc\src\utils\socket.ts */ let socketUrl: any = ""; // socket地址 let websocket: any = null; // websocket 实例 let heartTime: any = null; // 心跳定时器实例 let socketHeart: number = 0; // 心跳次数 let HeartTimeOut: number = 3000; // 心跳超时时间 let socketError: number = 0; // 错误次数 // 初始化socket const initWebSocket = (url: any) => { socketUrl = url; // 初始化 websocket websocket = new WebSocket(url); websocketonopen(); websocketonmessage(); sendSocketHeart() }; // socket 连接成功 const websocketonopen = () => { websocket.onopen = function (e: any) { console.log("连接 websocket 成功", e); resetHeart(); }; }; // socket 连接失败 const websocketonerror = () => { websocket.onerror = function (e: any) { console.log("连接 websocket 失败", e); }; }; // socket 断开链接 const websocketclose = () => { websocket.onclose = function (e: any) { console.log("断开连接", e); }; }; // socket 接收数据 const websocketonmessage = () => { websocket.onmessage = function (e: any) { let msg = JSON.parse(e.data); if (msg.type === 'heartbeat') { resetHeart() console.log("心跳"); } // console.log("收到socket消息", JSON.parse(e.data)); test(msg) // 测试数据 }; }; // socket 发送数据 const sendMsg = (data: any) => { websocket.send(data); }; // socket 错误 const websocketError = () => { websocket.onerror = function (e: any) { console.log("socket 错误", e); }; }; // socket 重置心跳 const resetHeart = () => { socketHeart = 0; socketError = 0; clearInterval(heartTime); sendSocketHeart(); }; // socket心跳发送 const sendSocketHeart = () => { heartTime = setInterval(() => { if (socketHeart <= 2) { console.log("心跳发送:", socketHeart); websocket.send( JSON.stringify({ content: "", requestId: "aa9872be-d5b9-478e-aba4-50527cd3ef32", type: "heartbeat" }) ); socketHeart = socketHeart + 1; } else { reconnect() } }, HeartTimeOut); }; // socket重连 const reconnect = () => { if (socketError <= 2) { clearInterval(heartTime); initWebSocket(socketUrl); socketError = socketError + 1; console.log("socket重连", socketError); } else { console.log("重试次数已用完的逻辑", socketError); clearInterval(heartTime); } }; // 测试收到消息传递 const test = (msg: any) => { switch (msg.type) { case 'heartbeat': //加入会议 mitts.emit('heartbeat', msg) break; } } export { initWebSocket, websocketonmessage, sendMsg, websocketonopen, websocketonerror, websocketclose, websocketError, resetHeart, sendSocketHeart, reconnect, };
2022年08月18日
2,782 阅读
2 评论
2 点赞
2022-07-08
PresentationAPI使用教程(Vue3&html)
W3C在2020年12月份出台了Presentation API规范,这个api接口允许用户自由控制投放在其他屏幕上,并和投放窗口通信,查看W3C规范。演示地址:投屏演示,详细demo(Vue3/HTML)见文章末尾{alert type="error"} 特别注意:需要注意必须为https环境{/alert} 1、创建一个PresentationRequest对象,该对象将包含我们要在辅助附加显示器上显示的地址。const presentationRequest = new PresentationRequest('receiver.html'); 2、做控制及监听事件/* * @Author: lzx * @Date: 2022-07-08 15:34:16 * @LastEditors: lzx * @LastEditTime: 2022-07-08 17:14:31 * @Description: Fuck Bug * @FilePath: \test\js\index.js */ // 创建个投屏对象 const presentationRequest = new PresentationRequest(['https://blog.fxnws.com']); // 投屏网址 // const presentationRequest = new PresentationRequest(['test.html']);//投屏页面 // Make this presentation the default one when using the "Cast" browser menu. navigator.presentation.defaultRequest = presentationRequest; let presentationConnection; //监视连接是否可用 presentationRequest.addEventListener('connectionavailable', function (event) { presentationConnection = event.connection; presentationConnection.addEventListener('close', function () { console.log('> Connection closed.'); }); presentationConnection.addEventListener('terminate', function () { console.log('> Connection terminated.'); }); presentationConnection.addEventListener('message', function (event) { console.log('> ' + event.data); }); }); //监视可用的显示器 presentationRequest.getAvailability() .then(availability => { console.log('Available presentation displays: ' + availability.value); availability.addEventListener('change', function () { console.log('> Available presentation displays: ' + availability.value); }); }) .catch(error => { console.log('Presentation availability not supported, ' + error.name + ': ' + error.message); }); // 开启投屏 function startProjectionScreen () { presentationRequest.start() .then(connection => { console.log('Connected to ' + connection.url + ', id: ' + connection.id); }) .catch(error => { console.log(error); }); } //发送消息 function sendMsg () { const message = '发送消息测试'; const lang = document.body.lang || 'en-US'; console.log('Sending "' + message + '"...'); presentationConnection.send(JSON.stringify({ message, lang })); } //关闭连接,关闭连接后无法再控制弹出窗口 function closeLink () { console.log('Closing connection...'); presentationConnection.close(); } //关闭连接后,换可以重新再次连接,这里需要指定id // presentationRequest.reconnect(presentationId); //关闭弹窗,结束连接调用 function endLink () { console.log('Terminating connection...'); presentationConnection.terminate(); } 3、连接端页面消息的展示(搬运的官方)/* * @Author: lzx * @Date: 2022-07-08 15:34:16 * @LastEditors: lzx * @LastEditTime: 2022-07-08 15:34:30 * @Description: Fuck Bug * @FilePath: \test\js\test.js */ let connectionIdx = 0; let messageIdx = 0; //如果有连接建立,则调用该函数 function addConnection (connection) { connection.connectionId = ++connectionIdx; addMessage('New connection #' + connectionIdx); connection.addEventListener('message', function (event) { messageIdx++; const data = JSON.parse(event.data); const logString = 'Message ' + messageIdx + ' from connection #' + connection.connectionId + ': ' + data.message; addMessage(logString, data.lang); maybeSetFruit(data.message); connection.send('Received message ' + messageIdx); }); connection.addEventListener('close', function (event) { addMessage('Connection #' + connection.connectionId + ' closed, reason = ' + event.reason + ', message = ' + event.message); }); }; const fruitEmoji = { 'grapes': '\u{1F347}', 'watermelon': '\u{1F349}', 'melon': '\u{1F348}', 'tangerine': '\u{1F34A}', 'lemon': '\u{1F34B}', 'banana': '\u{1F34C}', 'pineapple': '\u{1F34D}', 'green apple': '\u{1F35F}', 'apple': '\u{1F34E}', 'pear': '\u{1F350}', 'peach': '\u{1F351}', 'cherries': '\u{1F352}', 'strawberry': '\u{1F353}' }; function addMessage (content, language) { const listItem = document.createElement("li"); if (language) { listItem.lang = language; } listItem.textContent = content; document.querySelector("#message-list").appendChild(listItem); }; function maybeSetFruit (message) { const fruit = message.toLowerCase(); if (fruit in fruitEmoji) { document.querySelector('#main').textContent = fruitEmoji[fruit]; } }; //文档载入后,监听连接 document.addEventListener('DOMContentLoaded', function () { if (navigator.presentation.receiver) { navigator.presentation.receiver.connectionList.then(list => { list.connections.map(connection => addConnection(connection)); list.addEventListener('connectionavailable', function (event) { addConnection(event.connection); }); }); } }); 4、接收端页面构<!-- * @Author: lzx * @Date: 2022-07-08 15:34:05 * @LastEditors: lzx * @LastEditTime: 2022-07-08 15:35:13 * @Description: Fuck Bug * @FilePath: \test\test.html --> <!doctype html> <html> <head> <meta charset="utf-8"> <title>Demo Receiver</title> <style type="text/css"> html, body { height: 100%; margin: 0; font-family: sans-serif; background: radial-gradient(ellipse at center, #333333 0%, #000000 100%); color: #fff; } #main { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; font-size: 54px; } </style> <script type="text/javascript" src="引入3的代码块"></script> </head> <body> <div id="main">Hello World!</div> <ul id="message-list"> </ul> </body> </html> 5、vue3页面<template> <div class="container"> <button @click="startProjectionScreen">开启投屏</button> <button @click="sendMsg">发送消息</button> <!-- <button @click="closeLink">关闭连接</button> --> <button @click="endLink">结束调用</button> </div> </template> <script lang="ts"> // @ts-nocheck 不在当前文件中执行类型检查 import { toRefs, reactive, onMounted, watchEffect, onUnmounted } from 'vue' export default { props: {}, components: {}, setup () { const presentationRequest = new PresentationRequest(['https://blog.fxnws.com']); // 投屏网址 // const presentationRequest = new PresentationRequest(['test.html']); // 投屏本地页面 navigator.presentation.defaultRequest = presentationRequest; let presentationConnection; // 传参 const state = reactive({ }) const startProjectionScreen = () => { presentationRequest.start() .then(connection => { console.log('Connected to ' + connection.url + ', id: ' + connection.id); }) .catch(error => { console.log(error); }); } //发送消息 const sendMsg = () => { const message = '发送消息测试'; const lang = document.body.lang || 'en-US'; console.log('Sending "' + message + '"...'); presentationConnection.send(JSON.stringify({ message, lang })); } //关闭连接,关闭连接后无法再控制弹出窗口 const closeLink = () => { console.log('Closing connection...'); presentationConnection.close(); } //关闭连接后,换可以重新再次连接,这里需要指定id // presentationRequest.reconnect(presentationId); //关闭弹窗,结束连接调用 const endLink = () => { console.log('Terminating connection...'); presentationConnection.terminate(); } // 挂载 onMounted(() => { //监视连接是否可用 presentationRequest.addEventListener('connectionavailable', function (event) { presentationConnection = event.connection; presentationConnection.addEventListener('close', function () { console.log('> Connection closed.'); }); presentationConnection.addEventListener('terminate', function () { console.log('> Connection terminated.'); }); presentationConnection.addEventListener('message', function (event) { console.log('> ' + event.data); }); }); //监视可用的显示器 presentationRequest.getAvailability() .then(availability => { console.log('Available presentation displays: ' + availability.value); availability.addEventListener('change', function () { console.log('> Available presentation displays: ' + availability.value); }); }) .catch(error => { console.log('Presentation availability not supported, ' + error.name + ': ' + error.message); }); }) // 监听 watchEffect(() => { console.log('监听') }) // 页面卸载 onUnmounted(() => { console.log('页面卸载') }) return { ...toRefs(state), endLink, closeLink, sendMsg, startProjectionScreen } } } </script> <style scoped> </style> 6、详细demo附件下载隐藏内容,请前往内页查看详情2024年11月04日更新,看到评论区有部分朋友,遇到问题,我更新了相关Git完整Demo地址见下文1、vue3+ts+vite 报错 PresentationRequest 未定义 答:应该是ts未定义的报错,我当时做这个的时候,这个功能刚推出ts支持应该不完善,我也不想去定义相关的ts就直接使用// @ts-nocheck(这个指令用于告诉TypeScript编译器不在当前文件中执行类型检查)2、发现用ip访问不行,用127.0.0.1可以 答:直接用IP不行是因为没有https支持吧,我记得这个协议是需要https的支持的,具体要看下报错信息了,127.0.0.1是本机地址所以没事{alert type="warning"} 码云 {/alert}{alert type="warning"} Github {/alert}
2022年07月08日
813 阅读
43 评论
0 点赞
2022-02-24
小程序防抖节流方法封装
/* * @Author: lzx * @Date: 2022-05-06 13:33:43 * @LastEditors: lzx * @LastEditTime: 2022-05-06 13:57:06 * @Description: Fuck Bug * @FilePath: \reconsitution_talk_vant\utils\tool.js */ /*函数节流*/ const throttle = (fn, interval) => { let enterTime = 0; // 触发的时间 let gapTime = interval || 500; // 间隔时间,如果interval不传,则默认300ms return function () { var context = this; var backTime = new Date(); // 第一次函数return即触发的时间 if (backTime - enterTime > gapTime) { fn.call(context, arguments); enterTime = backTime; // 赋值给第一次触发的时间,这样就保存了第二次触发的时间 } }; } /*函数防抖*/ const debounce = (fn, interval) => { let timer; let gapTime = interval || 500; // 间隔时间,如果interval不传,则默认500ms return function () { clearTimeout(timer); var context = this; var args = arguments; // 保存此处的arguments,因为setTimeout是全局的,arguments不是防抖函数需要的。 timer = setTimeout(function () { fn.call(context, args); }, gapTime); }; } export default { throttle, debounce }; // 说明 // 页面引入:import tool from '../../utils/tool' // 调用示例: // 防抖 // test1: tool.debounce(function () { // console.log('防抖') // }, 5000) // 节流 // test2: tool.throttle(function () { // console.log('节流') // }, 5000)
2022年02月24日
472 阅读
0 评论
0 点赞
2021-10-09
js操作数组、数组对象案例集合-持续更新-记录工作用到的一些常见或不常见功能
在vue中遇到个需求,需要将后端给的列表倒叙展示(找后端直接给倒叙过的最简单),将数组或者数组对象倒叙输出 let arr = ["Vue","JavaScript","Array"]; //创建数组 let arrObj = [ { id: 1, name: 'vue', }, { id: 2, name: 'JavaScript', } ]; //创建数组对象 reverse函数: console.log(arr.reverse()) //颠倒顺序并输出
2021年10月09日
364 阅读
0 评论
0 点赞
2021-09-15
Vue前端模拟生成验证码并且效验功能
遇到个登陆功能需要输入验证码,后端没接口,但是为了防止机器人恶意登陆还是要写个验证码效验的,活就跑到前端来了,利用随机数写的一个4位验证码。{mtitle title="js核心代码如下"/}//定义code用于存放验证码 var code = '' // 设置长度,这里看需求,我这里设置为4 var codeLength = 4 // 设置随机字符 // 这里可以写成字母,这样就可以随机生成字母验证码了 var random = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) // 循环codeLength 我设置的4就是循环4次 for (var i = 0; i < codeLength; i++) { // 设置随机数范围,这设置为0 ~ 36 var index = Math.floor(Math.random() * 9) // 字符串拼接 将每次随机的字符 进行拼接 code += random[index] } // 将拼接好的字符串赋值给展示的code this.code = code 效验功能就不写了,就是获取用户输入的验证码,和生成的验证码做对比,对就OK不对就告诉用户:吊毛你输入的验证码有误!{mtitle title="这里CSS对样式改进"/}/* 让验证码变形,看起来更加像一点*/ letter-spacing: 15px; transform:skew(45deg); transform: scale(1.,0.5);
2021年09月15日
633 阅读
0 评论
0 点赞
1
2