Javascript way to explore https:https://cdn.v2ex.com/navatar/a5e0/0132/146_normal.png?m=1650095218 https:https://cdn.v2ex.com/navatar/a5e0/0132/146_large.png?m=1650095218 2025-09-20T16:18:55Z Copyright © 2010-2018, V2EX 有没有前端大佬,帮我看一下这个网站底部的粒子动画怎么做的。 tag:www.v2ex.com,2025-09-18:/t/1160190 2025-09-18T05:45:45Z 2025-09-20T16:18:55Z zhongchunfeng member/zhongchunfeng
https://lusion.co/projects/ 我想做一个差不多,threejs 有没有 demo

]]> 这段前端代码存在并发读取竞态的问题吗? tag:www.v2ex.com,2025-09-04:/t/1156990 2025-09-04T01:58:58Z 2025-08-27T23:22:19Z supuwoerc member/supuwoerc 这两天调试别人项目中的一段 js 代码,作用是刷新 token ,但是验证下来发现有很小的几率会触发多次刷新 token 的动作(下面代码中的 FIXME 位置),特别是 Promise.all 去发送一批请求的时候,我 google 了一圈,没研究明白,因为复现起来很困难,所以请教大家,代码中读取 isRefreshing 是安全的吗?我让 cursor 和 copilot 解释都是说 js 不启用 worker 是不存在并发问题的,但是从结果来看,确实有不止一个请求进入了刷新 token 的分支,我把这个情况描述完,cursor 让我引入 sync-mutex 加锁,和一开始的解释完全不一样,我在 StackOverflow 和 medium 中也找到几篇类似的文章,都是借助了防抖/记忆函数来解决,实在弄不清楚这块读写 isRefreshing 到底是不是安全的。

还看到了一篇锁的文章,感觉很类似我遇到的这个问题: https://jackpordi.com/posts/locks-in-js-because-why-not

伪代码如下:

let isRefreshing = false // 标记是否正在刷新 token let requests: Array<(token: string, err?: string) => void> = [] // 需要重试的请求列表 client.interceptors.response.use((response: AxiosResponse) => { const { config, status } = response const { code } = response.data if (status >= 500) { return Promise.reject("服务器错误") } else if (code == 10003) { // access token 过期,尝试刷新 token const { refreshToken } = user.useLoginStore.getState() if (refreshToken) { // FIXME: ?? 存在并发读取 isRefreshing 为 false 导致发出多次刷新 token 的请求 if (!isRefreshing) { isRefreshing = true return refreshToken() .then(({ data }) => { const { code } = data if (code === 10000) { user.useLoginStore.setState((state) => { state.token = data.data.token }) config.headers["Authorization"] = data.data.token const retry = client(config) requests.forEach((cb) => cb(data.data.token)) requests = [] return retry } else { return Promise.reject(data.message) } }) .catch((err) => { const msg = isError(err) ? err.message : err requests.forEach((cb) => cb("", msg)) requests = [] publishInvalidTokenEvent(msg) }) .finally(() => { isRefreshing = false }) } else { return new Promise((resolve, reject) => { requests.push((token: string, err?: string) => { if (err) { reject(err) } else { config.headers["Authorization"] = token resolve(client(config)) } }) }) } } else { requests.forEach((cb) => cb("", "登录过期") requests = [] publishInvalidTokenEvent("登录过期") } } else if (code === 10000) { return response.data.data } else if (code == 10006) { // 长 token 失效 requests.forEach((cb) => cb("", "登录过期") requests = [] publishInvalidTokenEvent("登录过期") } else { return Promise.reject(response.data.message || response.data.msg) } }) 
]]>
nstr - number → string, but looks good tag:www.v2ex.com,2025-08-23:/t/1154410 2025-08-23T04:59:51Z 2025-08-26T01:06:53Z Livid member/Livid https://nstr.vercel.app/

一个处理数字显示问题的 JS 库。

尤其是在处理有小数点的数字时会很有用。

]]>
前端 js 播放 base64 编码的 mp3,放出来杂音很大,请教是哪里出错了? tag:www.v2ex.com,2025-07-25:/t/1147714 2025-07-25T08:32:25Z 2025-07-25T21:37:31Z lisisi member/lisisi 后端传来是 base64-encoded 的 mp3 音频的字符串,码率、声道这些信息( sampleRate 、numChannels 、bitsPerSample 、dataLength )不知道,直接放在<audio>中播放是正常的:

<audio controls> <source src="data:audio/mpeg;base64, base64-encoded-string" type="audio/mpeg"> </audio> 

重新解码作为 blob 播放,放出来就很多杂音,这中情况是哪里的问题?

<script type="text/Javascript"> const audioCOntext= new (window.AudioContext || window.webkitAudioContext)(); const decoder = new TextDecoder("utf-8"); function base64ToArrayBuffer(base64) { const binary = atob(base64); const len = binary.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = binary.charCodeAt(i); } return bytes.buffer; } function playAudioChunk(base64) { const arrayBuffer = base64ToArrayBuffer(base64); audioContext.decodeAudioData(arrayBuffer).then((audioBuffer) => { const source = audioContext.createBufferSource(); source.buffer = audioBuffer; source.connect(audioContext.destination); source.start(0); }).catch((err) => { console.error("Error decoding audio data", err); }); } // ws-connection ... playAudioChunk(base64-encoded-string); </script> 
]]>
熟悉工业计算的来,是阀门相关的企业 tag:www.v2ex.com,2025-06-25:/t/1141026 2025-06-25T09:22:33Z 2025-06-24T17:21:33Z iisboy member/iisboy 有些 JS 的运算,做过的来,没做过可能沟通困难

]]>
js 不使用 promise 完成一个 sleep 函数,必须支持 await 调用 tag:www.v2ex.com,2025-06-23:/t/1140531 2025-06-23T13:13:04Z 2025-06-25T17:32:32Z wefgonujnopu member/wefgonujnopu 要求:
await sleep(毫秒),让当前 async 函数进入等待,不能阻塞线程

提示: 实现起来非常简单,只要几行,不能使用任何库,要兼容浏览器环境 ]]>
小米手机澎湃系统 AutoJS 的悬浮窗在证券软件打开时就消失 tag:www.v2ex.com,2025-06-17:/t/1139237 2025-06-17T09:47:46Z 2025-06-17T12:47:46Z yolo2020 member/yolo2020 之前使用 autojs 做了一些自动化操作,后来更新了系统,再打开证券软件,autojs 的悬浮窗就消失,其他软件中悬浮窗是可以正常显示的。有人知道怎么解决吗?还是手机系统做了限制。

]]>
关于 js 复制粘贴问题 tag:www.v2ex.com,2025-06-17:/t/1139084 2025-06-17T02:44:55Z 2025-06-17T11:29:14Z co2In member/co2In 从 qq 这种软件复制多张图片,触发粘贴发现是一个 DataTransferItemList 类数组对象,那么既然可以粘贴,应该是可以写入的啊,求大佬解惑 ]]> 求助,无法在 wixsite.com 上使用 document.write tag:www.v2ex.com,2025-06-17:/t/1139078 2025-06-17T02:28:00Z 2025-06-07T10:28:18Z flyn member/flyn 我写了一个需要用到 document.write() 方法的 Bookmarklet ,但是在这个网站中无法正常使用,具体表现总是抛出错误 Uncaught TypeError: Cannot read properties of undefined (reading 'write')

已尝试通过新建 iframe 获取干净的 write 方法并绑定到顶层 document ,依旧无效。问 AI 也没有提供可行的解决方案。

个人水平实在是有限,求助高手帮忙看看这网站用了什么魔法阻止使用这个方法,有解决的可能吗?

]]>
threejs 官方文档看着好难受。 tag:www.v2ex.com,2025-05-06:/t/1129931 2025-05-06T07:30:45Z 2025-05-06T23:06:12Z MrBrand member/MrBrand 如题,有没有 threejs 的入门教程推荐,图文(最好了,单位不方便看视频)、视频都可以,官方文档看着比微信开发文档看着还难理解

]]>
有没有 AI 能一步一步教会伸手党如何使用业务系统? tag:www.v2ex.com,2025-04-18:/t/1126478 2025-04-18T07:17:01Z 2025-04-19T05:45:37Z lambdaq member/lambdaq 不知道大家有没有遇到 文盲+伸手党,明明写了一大堆系统文档,使用教程,甚至录制了教学视频,就是视而不见,每天就重复问你如何使用,哪里找功能,怎么点进去

比如售后如何在订单系统里找到有问题单,怎么从别的页面复制一些参数填表,给用户点一下退款这种简单的事都能问半天。

有没有技术,能实现你问 AI 如何操作 XXX ,AI 在页面上依次给你把步骤圈出来,先点 A 再输入 B 再选 C 这样。

用知识库录入操作手册感觉有局限性,因为系统界面可能改版之后导致某些入口和按钮变了,知识库跟不上

AI 能不能直接通读一遍页面结构,大致摸清楚所有地方的功能按钮怎么对应的,然后对操作使用指南进行回答?

最好直接在页面上给他圈出来,每一步点哪里,高亮爆闪一下;类似游戏上手教学关卡一样。

这种技术一般怎么搭建呀?大家有什么思路不。

]]>
也聊下自己最近用 copilot 写程序的心得,还要讨教下方案 tag:www.v2ex.com,2025-03-31:/t/1122314 2025-03-31T07:25:20Z 2025-03-31T08:39:18Z elboble member/elboble 个人背景:野生写代码的,纯兴趣爱好,编码既不是工作,也不是科班,连培训班都是蹭网课。

需求:买了个小米的摄像头,不支持 ONVIF ,但是当视频录制到 128M 就形成文件,支持存到 smb 上,想写个 web 页面方便查看。后端 express ,前端 vue3 。简单说就是播放一堆 mp4 文件。

实现:视频录制格式是 hvc1+opus 。

1 ,开始用 video 来播放没问题。copilot 帮助下很快前后端搭起来,可以根据日期选择播放视频文件。

2 ,考虑安全,前后端都加了 jwt 认证,但是 video 请求视频文件不支持带 headers.Authorization token 。

3 ,咨询 copilot ,推荐转成 blob ,这样可以了带认证了,但是 blob 必须一次把 128M 都读回来才能播放。

4 ,再咨询 copilot 如何分片,推荐了 mediasource 配合 range ,实现快速播放。

5 ,copilot 再次提示 chrome 的 mediasource 实现不支持 hvc1 ,果然 chrome 提示不支持的类型;换了 safari 的确是可以不缓冲直接播放了。

6 ,copilot 建议在后端 ffmpeg 转码以后再推出来,可是后端只是台 J1900 ,转 4k 的码比播放速度还慢。这条路也不通。

7 ,copilot 又推荐了 m3u8 的切片方法,看起来挺复杂了,感觉搞不定。

现在只有退回原点,取消认证,直接用 video 播放。看看 copilot 的帮扶道路,你说他没用吧,后面每个知识点都是现学的,但是最后还是没解决问题。

]]>
Javascript 继续 套壳 AI 应用类 manus tag:www.v2ex.com,2025-03-31:/t/1122287 2025-03-31T06:21:05Z 2025-03-31T06:21:05Z taixw2 member/taixw2 LuguManus 是用 Electron 和 TypeScript 构建的智能化桌面应用框架。它整合大型语言模型与实用工具,有强大自动化和辅助功能。具备多代理协作、智能任务分解、工具链集成等特点。技术栈涵盖 Electron 、TypeScript 、Prisma ORM 等。适用于智能文档处理、网络信息检索等场景。项目包含 appspackages 目录,开发者可按规范贡献代码,采用 MIT 许可证开源,欢迎反馈共创更好的 AI 桌面工具。

https://github.com/electron-manus/lugumanus

]]>
如何在移动端 h5 页面实现<Select/>搜索下拉选择框! tag:www.v2ex.com,2025-03-19:/t/1119715 2025-03-19T13:03:46Z 2025-03-19T17:11:03Z mumuwen member/mumuwen 背景:移动端 h5 页面,想实现一个类似于管理后台的<Select />支持搜索的下拉框(交互要和管理后台 antd 的 Select 一样),有什么好的实现方案 或者 第三方 js 库吗?

问题:因为考虑到移动端输入框 输入、触碰点击和 pc 端的操作不同。例如边输入变搜索,下拉框遮挡问题...

有没有大佬有方案,感谢

]]>
求前端高频数据绘图库 tag:www.v2ex.com,2025-03-18:/t/1119367 2025-03-18T08:27:27Z 2025-03-19T07:43:10Z lzyong2019 member/lzyong2019 背景

我正在开发一个上位机的工具,是用 tcp 进行连接的。连接完了之后我会接收到数据,格式如下:

demo:>1,2,3 demo:>5,6,7 

我需要对上面的数据进行解析组成每个通道的数据(通道由每一列元素),如上所示就是有 3 个通道[1,5], [2,6], [3,7]。 然后需要实时的绘图,最大的问题是,这个连接数返回的数据很大约 1s 有 1w 行的数据量。我要怎么进行一个比较好的数据绘图呢。

]]>
吐槽一下 Trae tag:www.v2ex.com,2025-03-18:/t/1119227 2025-03-18T01:52:47Z 2025-03-19T05:27:14Z boyzhang member/boyzhang 2 、前端启动的项目,关闭 Trae 后,前端项目还可以访问,要去任务管理器中手动关闭 node 服务 ]]> 记忆中好像在论坛看到有款专门在 iframe 中做前端的 js 库/框架? tag:www.v2ex.com,2025-03-17:/t/1119172 2025-03-17T15:10:22Z 2025-02-25T18:23:38Z MRlaopeng member/MRlaopeng 之前看不是很完善就没收藏起来. 他还有类似于 vue 的双向数据绑定功能, 实在忘记是啥了

]]>
Javascript 中的 Promise 跟异步有关系吗?还是我的理解有问题?谁能把 Promise 解释清楚? Promise 的正确用法应该是什么样的? tag:www.v2ex.com,2025-03-15:/t/1118623 2025-03-15T04:42:53Z 2025-03-28T10:39:04Z burnbrid member/burnbrid 感觉 Promise 跟异步没有关系啊!我理解的异步是 ajax 这样的,ajax 将请求发出去之后,代码就继续往下执行了,等到 ajax 收到响应结果了,再回头执行 ajax 的回调函数,这才是异步。不是说你指定了回调函数就是异步。Promise 构造函数里面的代码是同步执行的,假如在 Promise 构造函数里面执行一个 10 万次的循环,主线程会等这 10 万次执行结束之后,才会继续执行下一行代码,这叫异步吗?异步跟回调函数没有一点关系。 异步就是不在主线程里面执行。

const ps = new Promise(function name(resolve, reject) { let i = 0; while(i<1000000){ i = i+1; console.log('i=',i); } }); console.log('promise 是异步吗?');

等上面这 100 万次循(最耗时的操作)环执行完,我还有必要通过 then 去指定回调函数吗?我直接执行回调函数就可以了,根本不需要通过 then 去执行回调函数。

]]>
求问,小程序的菜单栏怎么和右边的功能键垂直居中? tag:www.v2ex.com,2025-03-11:/t/1117525 2025-03-11T05:05:08Z 2025-03-11T06:33:03Z sugarkeek member/sugarkeek
]]>
自习室小程序的座位图是如何实现的(前端) tag:www.v2ex.com,2025-03-06:/t/1116418 2025-03-06T08:51:47Z 2025-03-08T07:17:54Z YVAN7123 member/YVAN7123 小程序的软件是无老板

我的猜想:
1. 用 canvas 纯画
2. 底图是图片, 上面加一个层, 将座位位置按照定位用 canvas 画上去。

有没有大佬知道啊?


https://imgur.com/qAgwcFM ]]>
谷歌浏览器的 bug tag:www.v2ex.com,2025-03-05:/t/1116142 2025-03-05T09:45:41Z 2025-03-05T12:43:48Z boyzhang member/boyzhang 各位大佬,你们遇到过这种情况没,下列代码不执行

document.addEventListener('visibilitychange', ()=>{console.log('aa')})

我去谷歌 bug 网站也看到有人提了几个了, 哪位大佬知道是啥情况不

]]>
为什么中小公司的前端面试官爱问 array 和 object 有多少种方法 tag:www.v2ex.com,2025-03-05:/t/1116046 2025-03-05T05:27:50Z 2025-04-15T17:08:13Z zhengfan2016 member/zhengfan2016 如题,我感觉这两年面试我碰到至少 3 个面试官问这个问题,真的有人能把 mdn 的所有方法一字不差的背下来吗。

我感觉常用的也就 map 和 filter 那几个,剩下的面试官也不给提示,发现候选者回答那么几个就直接下一题了。

像 join ,pop ,push 我感觉面试官愿意提这个单词甚至就简单描述一下场景,比如我有个先进后出的栈,我想入栈和出栈,可以用什么 array 方法,候选者完全能答上来的。

感觉问点 promise 代码题都比这个好,感觉今年几个面试好像完全都不考 promise 了....

]]>
有什么办法能实现 uniapp 上的离线人脸识别 tag:www.v2ex.com,2025-02-26:/t/1114394 2025-02-26T08:36:45Z 2025-03-22T10:21:35Z Michelangelono member/Michelangelono 就是包括检测授权也是离线的,最好是能批量下发授权那种。 需要能提取人脸特征,这样实现 app 不用密码登录。 好像这个框架能实现: https://github.com/justadudewhohacks/face-api.js 有没有用过这个的 不需要很高的准确度,差不多就行了。

]]>
本人遇到了非常奇怪的关于“注释”ctrl+/ 快捷键问题,需要大佬们指点一二。 tag:www.v2ex.com,2025-02-25:/t/1114210 2025-02-25T14:52:05Z 2025-02-25T16:50:05Z wolffcat member/wolffcat 以前安装过搜狗输入法,但是后来厌恶搜狗输入法静默安装广告软件就卸载了。
然后安装了搜狗医生版,发现 ctrl+/是医生版本热键,即使用 ctrl+/会自动弹出医生版搜狗输入法。
这与 pycharm vscode 产生了冲突,修改输入法绑定按键 ctrl+,,但是不生效,依旧弹出医生版搜狗输入法。

于是卸载搜狗系输入法,geek 删除的应该很干净.
重启,依旧不能使用 ctrl+/pycham 和 vscode ,查 pycharm 按键绑定,绑定没有问题。

重启,在 ubuntu 下发现 pycham 注释没问题,排除 ctrl 按键损坏。

重启回到 win11 ,最神奇的地方来了,在 pycham 我想着重新绑定下注释按键吧,没想到按 ctrl+/始终接收不到编辑器,编辑器根本识别不到 ctrl+/,见下图。

![](

使用 OpenArk64 排查快捷键占用,如下:,并没有发现占用

![]( )

求指点,我向来没有碰见过这么奇怪的问题。

我觉得本问题在技术圈才能够得到解决,遂提问于此。 ]]>
ChatGPT 语音对话技术 tag:www.v2ex.com,2025-02-03:/t/1108736 2025-02-03T08:21:06Z 2025-02-03T11:53:31Z subtleworks member/subtleworks 请教下大家 ChatGPT 里高级语音模式是怎么实现的 有 js 库可以使用吗

之前很早有做过跟 gpt 对话的插件 也加了语音识别 但是做不到戴上耳机后的自由对话 经常会自动中断

]]>
求前端大佬解惑, HTML 里的文本怎么做逐行滚动? tag:www.v2ex.com,2025-01-29:/t/1108305 2025-01-29T17:46:46Z 2025-01-31T20:07:06Z NQ member/NQ 有一个 div 里面有一些文本( div 的大小不固定,文本的内容也不固定),如何实现文本的逐行滚动而不是逐像素滚动? 我让 AI 帮我写了一个 demo ,这个 demo 在用鼠标滚轮的时候可以逐行滚动,但是有个问题,在这个 div 里面点鼠标中键,再往下移动鼠标(在 Windows 下这个行为会自动向下滚动),这个时候 div 会卡住,过了一会,整个 div 里的内容会滚动很大距离,这种情况怎么实现逐行滚动?

下面是 demo 代码: https://codepen.io/Asn-La/pen/RNbvYjY

]]>
快应用问题求助 tag:www.v2ex.com,2025-01-20:/t/1106473 2025-01-20T06:27:48Z 2025-01-20T09:05:24Z Rashomon98 member/Rashomon98 求助,快应用有什么办法达到安卓应用的那种保活拉活么?比如"1 像素保活"、"前台服务保活"、"广播拉活"、"Service 系统机制拉活"之类的。

]]>
2024 JS 生态调查结果出炉: React 遥遥领先, Vue 程序员最穷 tag:www.v2ex.com,2025-01-18:/t/1106064 2025-01-18T06:14:00Z 2025-01-18T20:24:34Z evilStart member/evilStart JS State 2024 调查似乎站子里没人发啊,那我来吧。最新的调查了全球各地的上万名 JS 程序员。

React 使用率高达 82% ,第不知道多少次卫冕冠军。Vue 和 Angular 并列第二,各 50%。,Svelte 26%,剩下的都很低(同一个程序员可能用过多个框架,所以总和超过 100%)。

收入方面,各个框架的 JS 程序员平均年薪在 7 万美元。唯独 Vue 程序员最低,只有 5 万美元。

还有其他很多的结果,比如全栈框架、后端、打包工具、跨平台工具等等,感兴趣可以看看 https://2024.stateofjs.com/ 。以后技术选型也有参考。

]]>
不顾“万人联名请愿”,甲骨文拒绝放弃 Javascript 商标所有权 tag:www.v2ex.com,2025-01-14:/t/1105089 2025-01-14T11:00:16Z 2025-01-15T10:14:52Z VisualStudioCode member/VisualStudioCode https://www.ithome.com/0/824/599.htm

]]>
2025 年,我又把前端"老古董"--AMD 给翻了出来 tag:www.v2ex.com,2025-01-13:/t/1104713 2025-01-13T06:59:01Z 2025-01-13T06:59:01Z pursuer member/pursuer 太长不看省流版:

一个具有较高可扩展性的 JS AMD 规范模块加载器 partic2-iamdee
Github
Gitee

在上面的基础上做了个早期形态的“全栈”包管理 pxseed ,并附带一个 Javascript Notebook 。
Github
Gitee

纯网页模式 Javascript Notebook 演示地址
Github Pages
之前 V 站大佬推广的平台 帽子云


关于做这个的动机和最终想实现的效果

在知道 Typescript 之前不习惯写 JS 的,然后接触到 Typescript 的时候第一个问题就是模块化的问题,当时比较多的模块化方案就是 CommonJS 和 AMD 了,为了在浏览器上用自然用的是 AMD 。虽然有 webpack 了但是 AMD 更简单,然后一直用到了现在。

到了现在已经出现了很多前端构建工具,但遗憾的是,Javascript 还是没有一个扩展性较强的统一的模块机制。
例如 Node ,早期用的 CommonJS ,现在开始转变为 ES Module ,浏览器都支持了 ES Module ,但是各种打包工具又会在打包后使用不同的加载方式。而且还有个特例-ServiceWorker 中不支持 ES Module 中的动态 import 。
同时,可能是照顾到打包工具等实现,ES Module 的可扩展性非常弱,可能只有 Import maps 改变映射这种级别的扩展。例如我想从内存/IndexedDB 中加载模块,ES Module 就不能支持。

同时我也接触了 Jupyter Notebook/Lab ,觉得是个很方便的平台,可以动态的执行 Python 并查看每一步的结果。于是也想在 JS 上实现个类似的东西,虽然有 IJavascript ,但是我想有能不依赖后台 python 的这么一个东西。

然后就有了做包管理的想法。

NPM 分发和获取的经常是编译产物。可以对比下 Golang 。Golang 虽然槽点不少,但包管理工具链还是比较优秀的。分发的是源码,对某个函数有疑问,可以在 IDE 中跟进源码,NPM 上则大多只能跟到类型声明。

Node/NPM 的设计对比 python/PIP 有一些地方对 Notebook 不太友好,PIP 默认装全局,NPM 默认装项目文件夹,当然 NPM 的设计一定程度解决了版本问题,不过我的观点是版本问题还是需要第三方库本身做好,包管理来处理兼容问题多少会有一些难以解决的 corner case 。

因此我尝试做了这个 pxseed“全栈”包管理,在这个框架下,前端浏览器和后端 Node 都可以用一套编译产物,并用 AMD 加载模块,Typescript 源码直接分发和下载,这样 IDE 里点一下可以跟进到源码。为了兼容 NPM 生态,pxseed 也添加了 Rollup 来打包 NPM 模块为 AMD 供前端使用。

当然 AMD 做前端是有致命缺点的,AMD 加载零碎文件的性能差,没有 Tree-Shaking ,没有 SEO 。但如果是想做成个类似 python 的属于 JS 的全栈包管理本地用,还是挺不错的。而且 partic2-iamdee 高度可定制化,也让优化上述问题成为可能,比如,你也可以用 Websocket 来加载 JS 模块。

当然这些东西都有点"路子野",说不定已经早有人做过更好更成熟的实现方案,如果有的话欢迎推荐给我。

]]>
有使用 Javascript 编写 windows cmd 批处理程序的方法吗,类似 coffescript 这样转译的东西 tag:www.v2ex.com,2025-01-13:/t/1104622 2025-01-13T02:15:03Z 2025-01-13T18:02:23Z stx0821 member/stx0821 比如编写:console.log('Hello') 输出 echo Hello

]]>
js 小白,请教一下为什么网页上的播放器, Chrome 控制台不能用 querySelector 直接获取到呢 tag:www.v2ex.com,2024-12-24:/t/1099945 2024-12-24T07:46:25Z 2024-12-24T07:51:34Z linyuzhou member/linyuzhou 想给一个网课网站加一个自动调整播放速度的小插件,按照之前的一些粗浅的经验,从审查元素里复制 JS 路径,然后就可以在控制台或者 extension 里获取到播放器这个元素了

video = document.querySelector("#vidplayer > video") 

大概像这样。但是发现这个网站很神奇的一点是,如果打开新网页直接在控制台输入这句命令,是获取不到 video 的,必须先经过审查元素的这一步,才能在控制台里获取到。

体感上这像是只有进入审查元素了,才会动态生成相关元素,但是进入之前也能使用播放功能,感觉非常神奇。请问有没有老哥懂得这是什么原因呢

对 js 接触得很浅,可能是很粗浅的问题,希望大家不吝赐教

]]>
自荐一个 js 通信的包 tag:www.v2ex.com,2024-12-21:/t/1099336 2024-12-21T15:03:24Z 2024-12-25T00:19:10Z xiaoming1992 member/xiaoming1992 缘起

我的工作内容有写网页游戏,游戏涉及到前后端通信,没找到顺手的通信包,所以手写了一个通用的 js 通信包remote

feature

调用示意

 // 远端 remote.register('something', async (params: Whatever) => { return WhatYouWant }) // 本地 // res === WhatYouWant const res = await remote._.something(xxx) 

与 rpc 相比的优势

协议

由于通信双方是平等的,所以 B 调用 A 的流程也是一样的

protocol.png

更多信息

详见 @zimi/remote/README.md

]]>
Python 代码转换为 Javascript 运算结果不一致 tag:www.v2ex.com,2024-12-07:/t/1095749 2024-12-07T09:05:22Z 2024-12-07T09:37:03Z f360family123 member/f360family123 def cid_hash_file(path): h = hashlib.sha1() size = os.path.getsize(path) with open(path, 'rb') as stream: if size < 0xF000: h.update(stream.read()) else: h.update(stream.read(0x5000)) stream.seek(int(size/3)) h.update(stream.read(0x5000)) stream.seek(size-0x5000) h.update(stream.read(0x5000)) return h.hexdigest().upper()

上面的代码用 chatGPT 转换后是这样的

function cidHashFile(path) { const h = crypto.createHash('sha1'); const size = fs.statSync(path).size; const stream = fs.createReadStream(path); if (size < 0xF000) { stream.on('data', (chunk) => { h.update(chunk); }); } else { stream.on('data', (chunk) => { if (stream.bytesRead <= 0x5000) { h.update(chunk); } else if (stream.bytesRead >= Math.floor(size / 3) && stream.bytesRead < Math.floor(size / 3) + 0x5000) { h.update(chunk); } else if (stream.bytesRead >= size - 0x5000) { h.update(chunk); } }); } stream.on('end', () => { const result = h.digest('hex').toUpperCase(); console.log(result); }); stream.on('error', (err) => { console.error('File reading error:', err); }); } 

试了不同文件计算出来的 hash 不一致,有没有大佬知道原因的?

]]>
css 的 justify-content 等效语法? tag:www.v2ex.com,2024-12-04:/t/1095094 2024-12-04T18:04:45Z 2024-12-04T23:04:45Z humbass member/humbass 记得在哪里见过一次 justify-content 的等效写法,还特意试了一下,效果完全一样,哪位伙伴知道的?

]]>
请教一下使用油猴脚本修改 html 内容后, 样式不生效的问题 tag:www.v2ex.com,2024-11-26:/t/1092842 2024-11-26T09:29:52Z 2024-11-26T14:40:33Z yazinnnn0 member/yazinnnn0 试了下在 console 中 append, 问题一样

但是直接在浏览器 dev tools 编辑元素的话, 样式可以正常展示

请问有什么办法是样式生效吗? ]]>
async 函数中止/task local 方案后记,V8 上的另一个可行思路 tag:www.v2ex.com,2024-11-16:/t/1090081 2024-11-16T06:23:25Z 2024-11-16T18:14:27Z pursuer member/pursuer 之前做了一次失败的尝试,做了一个 hook Promise 的方案。
t/1081474
省流说下这个方案失败的原因是 native code 中(例如 fetch)创建的 promise 不会使用 Hooked 的 Promise ,并且 V8 原生 await 实现不会在 onfulfilled 返回前运行 await 后面的代码,只有通过类似 babel 等工具将 await 编译为生成器函数的情况下才行。
后来我把库改回了生成器函数的模式。

昨天突发奇想,想到另一个方案,这个方案我测试在 node 和 chrome 上是可行的。 就是借助 new Function 自定义一个带标记的函数,就可以将标记的函数名插入到 new Error().stack ,就可以区分当前的任务栈,实现 task local,继而也可以通过 hook promise 实现 async 函数中止。虽然和最早方案的表现有一些差异。这个方案经过测试确实是可行的。

但是这个方案只在 V8 测试是生效的,在 txiki.js(quickjs)上 await 的堆栈会丢失。并且在获取当前 task 时有较高的性能损耗,所以只能说仅供参考,没什么实际应用价值

]]>
如何在前端统计用户观看视频所消耗的流量?求教啊,大神们! tag:www.v2ex.com,2024-11-14:/t/1089586 2024-11-14T08:55:55Z 2024-11-14T10:41:06Z shidu2003 member/shidu2003 问题说明

项目背景

项目使用腾讯云点播服务进行视频内容分发。需要实现前端视频流量监控功能,当用户观看视频消耗的流量达到特定阈值时,自动终止视频播放。同时会将相关数据记录到数据库,为统计页面做准备。

技术环境

已尝试方案

  1. 使用 Performance API 监控
    • 尝试通过 performance.getEntriesByType('resource') 获取视频资源的 transferSize
    • 问题:transferSize 始终返回 0 ,无法获取实际流量数据
  2. 通过播放器的 buffered() 方法估算流量
    • 实现思路:使用公式 (已缓冲时长 / 视频总时长) × 视频文件大小 计算流量消耗
    • 问题:当视频首次缓冲到 100% 后,即使用户拖动进度条触发新的数据下载,缓冲进度依然显示为 100%,导致无法统计到新增的流量消耗

待解决问题

  1. 如何准确获取视频播放过程中的实时流量消耗
]]>
pdfjs 中,通过 findController 可以搜索到对应的文本信息,并且高亮出来。那么, pdfjs 有没有什么 api 可以获取搜索到的信息的位置节点 ?请教 tag:www.v2ex.com,2024-11-12:/t/1088929 2024-11-12T09:06:30Z 2024-11-12T10:03:30Z consensus member/consensus 有没有独立的同时可以 pc 移动端用的三级联动城市选择组件啊 tag:www.v2ex.com,2024-11-11:/t/1088509 2024-11-11T05:51:07Z 2024-11-11T10:32:42Z dzdh member/dzdh 实在不想自己写三个 select 来回改了。编辑的时候好痛苦。

]]>
字幕滚动有没有更好的方式实现 tag:www.v2ex.com,2024-11-09:/t/1088003 2024-11-09T06:16:55Z 2024-11-21T01:50:04Z humbass member/humbass 重复造轮子,网上找了一些字幕工具,没有趁手的感觉,比较喜欢官方原来在右侧的展示形式,根据记忆,重新粗糙的复刻了下,https://i.imgur.com/i9dApFu.png

但是目前的实现方式是 根据 video 播放的进度,找到对应的词条的 dom 高度,向上调整若干 offsetTop ,挺原始的方式

油管字幕内容是一个类似 xml 格式的文件,从内容上看,应该是把 script 直接丢到页面(或者某个容器)里头,没想明白这种方式是如何实现的。 文件大概长这样

https://i.imgur.com/ICMeUIY.png

]]>
请教一个识别课程并归类的 JS 脚本执行不了的问题。 tag:www.v2ex.com,2024-10-31:/t/1085408 2024-10-31T09:27:19Z 2024-10-31T09:27:19Z Akasashic member/Akasashic 这段过滤器和遍历的代码在课程列表出现浏览器点进审查元素再到控制台执行有效果。
在课程列表出现前进审查元素进控制台,再点到课程列表,直接在控制台执行就 0 数据。
油猴的脚本自动重复执行不管进不进审查元素一直都是 0 数据,用按钮手动触发也是 0 数据,最后我直接用标题文字去匹配不用筛选也不行,等 dom 加载完也没用

测试用的代码如下:
// 定义一个数组用于存储视频信息
const videoStatusList = [];

// 遍历每个 courseware-list 的 li 元素
document.querySelectorAll('.courseware-list li').forEach((item, index) => {
let videoTitle = item.querySelector('span').getAttribute('title') || '无标题';
let status;

// 根据 class 设置视频状态
if (item.querySelector('.iconfont.complete')) {
status = '已观看';
} else if (item.querySelector('.state')) {
status = '正在观看';
} else {
status = '未观看';
}

// 将视频信息存入数组
videoStatusList.push({
title: videoTitle,
position: index + 1, // 使用 index + 1 表示位置
status: status
});
});

// 输出结果到控制台
console.log('视频观看状态:', videoStatusList); ]]>
Unexpected end of input 错误,求教 tag:www.v2ex.com,2024-10-26:/t/1083818 2024-10-26T05:28:59Z 2024-10-26T15:05:25Z pcxys member/pcxys 求教各位大佬,这个问题是咋回事,google 上找了一天,也没有找到好的办法。 e55ffb2a28c75f4600df75f9b3f3ae35.png b91a381b833095e96166df68644bebeb.png 41dcfa90fde5947afee578cd350731cb.png

]]>
关于 js 应该如何学习的步骤,进行请教 tag:www.v2ex.com,2024-10-19:/t/1081712 2024-10-19T05:59:29Z 2024-10-25T11:30:43Z pcxys member/pcxys 没有基础,初学者。 想到一个项目,想学习开发,边开发边学习。 都 2024 年了,我不知道我应该从原生的 js 开始学习,然后逐步迭代到 jQuery 、react ,还是应该先用 react 进行开发,然后逐步去补习原生 js 和 jQuery 知识。 请各位给点建议。

]]>
请教一个 js 提交 iframe 表单在 chrome 浏览器不生效的问题 tag:www.v2ex.com,2024-10-12:/t/1079450 2024-10-12T01:50:13Z 2024-10-17T14:10:00Z dreambakerq member/dreambakerq 各位好,最近我在维护一个旧 OA 系统审批功能。

正常流程大致是: 审批人打开页面,iframe 中的表单会填充名称,页面上点击审核完成的按钮时,提交表单后台保存,然后进行后续流程处理。firefox 下上述流程正常。

现在的问题是: 奇安信 chrome 内核浏览器下,提交表单的这步被略过,直接执行了后续流程处理。

提交表单的方式是:(尝试了 js 和 jquery 都有问题)

 $(window.frames['tabcont'].document).find('form').submit(); 

尝试过将提交表单之后的逻辑代码去掉,就又能正常。

想请教下有没有改动比较小的修法,先谢谢各位大佬了。

]]>
Tampermonkey 脚本开发的问题求助 tag:www.v2ex.com,2024-10-11:/t/1079110 2024-10-11T02:07:27Z 2024-10-11T02:56:17Z Chipmunker member/Chipmunker 1. 具体问题简述

我开发了一个 Tampermonkey 脚本,但是往往需要手动刷新页面才能触发。请教该如何优化。(代码附在最后面)

2. 脚本功能描述

inSpirehep.net这个网站可以复制文献的BibTeX引文信息(通过点击文献左下角的cite实现),现在我想在BibTeX内容中加入一个inSpirehep.net网站的编号。为此我使用 Tampermonkey 脚本在文献的右下角添加了一个Copy BibTeX to Clipboard的按钮,点击按钮可以将加入编号的BibTeX内容复制到系统剪贴板。

现在的问题是,这个脚本往往需要重新刷新页面才能触发,在第一次展示文献列表的时候不会出现。不知道该如何修复。PS ,这份代码也是在 ChatGPT 协助下完成的,本人完全没有 JS 开发经验。希望能有高手指点一二。

3. 我的原始代码

// ==UserScript== // @name Copy BibTeX to Clipboard-v2 // @version 2.0 // @description Adds a button to fetch data and copy it to clipboard // @author Chipmunker // @match https://inspirehep.net/literature* // @run-at document-end // @grant GM_xmlhttpRequest // @grant GM_setClipboard // @grant GM_notification // ==/UserScript== (function () { 'use strict'; var maxAttempts = 200; // 最大尝试次数 var attempts = 0; // 当前尝试次数 var copyBtnText = "Copy BibTeX to Clipboard"; var copyBtnColor = "#000008"; var copiedBtnText = "Data Copied to Clipboard"; var copiedBtnColor = "#f44336"; var showDuration = 5000; // ms var regexPattern = /^https:\/\/inspirehep.net\/literature\/(\d+)$/; // 按钮的点击事件处理函数 function CopyToClipOnClick(button, inspireID) { // 发送 GET 请求 GM_xmlhttpRequest({ method: 'GET', url: 'https://inspirehep.net/api/literature/' + inspireID, // 替换为你要请求的 API URL headers: { 'authority': 'inspirehep.net', 'accept': 'application/x-bibtex' }, onload: function (response) { // 获取响应数据 var data = response.responseText; // console.log("|" + data + "|"); // 为 BibTeX 添加 inspireID let BibInspireID = data.replace(/\n\}\n$/, ",\n inspirehepID = \"" + inspireID + "\"\n}\n"); // 将数据写入系统剪贴板 GM_setClipboard(BibInspireID); // 修改复制按钮并在一秒后修复 var textSpan = button.querySelector('.v-top, #span-' + inspireID); textSpan.innerText = copiedBtnText; textSpan.style.color = copiedBtnColor; setTimeout(function () { textSpan.innerText = copyBtnText; textSpan.style.color = copyBtnColor; }, showDuration); // 提示用户数据已复制 // alert('Data copied to clipboard: \n' + BibInspireID); GM_notification({ text: BibInspireID, title: copiedBtnText, // url: 'https:/example.com/', onclick: (event) => { // The userscript is still running, so don't open example.com // event.preventDefault(); // Display an alert message instead // alert('I was clicked!') console.log('NotificationClick') } }); } }); } function findRefSearchBtnAll() { var intervalId = setInterval(function () { // 查找 ref Search button var refSearchBtnAll = document.querySelectorAll('[data-test-id="reference-search-button"]'); if (refSearchBtnAll.length > 0) { // 找到了 ref Search button 元素,可以执行相应的操作 clearInterval(intervalId); // 停止轮询 console.log('找到了 ref Search button 元素'); var Btn = document.querySelector('.CopyBtn'); if (Btn) { return; } for (var refSearchBtn of refSearchBtnAll) { var button = createCopyBtn(refSearchBtn, copyBtnText); // 按钮点击事件处理函数 button.addEventListener('click', function () { var inspireID = this.id; CopyToClipOnClick(this, inspireID); }); } } else { attempts++; // 增加尝试次数 // console.log('未找到 ref Search button 元素'); if (attempts >= maxAttempts) { clearInterval(intervalId); // 达到最大尝试次数,停止轮询 console.log('未找到 ref Search button 元素, 达到最大尝试次数'); } } }, 100); // 每隔 100 毫秒钟检查一次 } const observer = new MutationObserver(function (mutationsList, observer) { // 在 div 变化时重新运行脚本的代码 // 例如,重新加载页面 // location.reload(); findRefSearchBtnAll(); }); var currentURL = window.location.href; if (regexPattern.test(currentURL)) { findRefSearchBtnAll(); } else { findRefSearchBtnAll(); // 监听目标 div 的变化 const targetDiv = document.querySelector('[class="ant-col ant-col-xs-24 ant-col-lg-17"]');//'[data-test-id="search-results"]'); if (targetDiv) { observer.observe(targetDiv, { attributes: false, childList: true, subtree: true }); } } })(); function createCopyBtn(refSearchBtn, copyBtnText) { var refSearchSpan = refSearchBtn.parentNode; // 构造 copy icon var copyImgSpan = document.createElement('span'); copyImgSpan.role = "img"; copyImgSpan.innerHTML = '<svg viewBox="64 64 896 896" focusable="false" data-icon="copy" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z"></path></svg>'; // 构造 icon span var icOnSpan= document.createElement('span'); iconSpan.className = "icon"; iconSpan.appendChild(copyImgSpan); // 获取文献 ID var inspireMatch = refSearchBtn.href.match(/citedby:recid:(\d+)$/); var inspireID = inspireMatch[1]; // 构造 __IconText__ var IcOnTextSpan= document.createElement("span"); IconTextSpan.className = "__IconText__"; var textSpan = document.createElement("span"); textSpan.className = "v-top"; textSpan.innerText = copyBtnText; // "Copy BibTeX to Clipboard"; textSpan.id = "span-" + inspireID; IconTextSpan.appendChild(iconSpan); IconTextSpan.appendChild(textSpan); // 构造 Button var button = document.createElement('button'); button.type = "button"; button.id = inspireID; button.className = "CopyBtn"; button.appendChild(IconTextSpan); var UserActiOnSpan= document.createElement("span"); UserActionSpan.className = "__UserAction__"; UserActionSpan.appendChild(button); refSearchSpan.parentElement.insertBefore(UserActionSpan, refSearchSpan); return button; } 
]]>
最近用到了 Naive UI,感觉以后前端写 css 是不是也要用 js 来写了呀。 tag:www.v2ex.com,2024-10-09:/t/1078582 2024-10-09T07:38:58Z 2024-10-10T16:28:13Z yayaluoya481 member/yayaluoya481 如果前端的 html ,css 全部用 js 来写的话其实感觉还行,如果用 ts 来写的话就有类型约束了更爽。

]]>
请教 JSEncrypt.js 的一个代码问题 tag:www.v2ex.com,2024-10-02:/t/1077431 2024-10-02T12:08:09Z 2024-10-04T01:57:04Z pinocc012 member/pinocc012 var pk ='MFswDQYJKoZIhvcNAQEBBQADSgAwRwJA4eeQZu0GkgzXYypfcKRxRiclJC0Q5A5+T+EXcSpcaZlq/eMyy4oJIUfvYsCsvIhAENB2YCTVmdLjWeHbSPXKJQIDAQAB';
jse.setPublicKey(pk);
console.log(jse.getPublicKeyB64());

结果输出是 MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOHnkGbtBpIM12MqX3CkcUYnJSQtEOQOfk/hF3EqXGmZav3jMsuKCSFH72LArLyIQBDQdmAk1ZnS41nh20j1yiUCAwEAAQ==

key 竟然变了,请问是 JSEncrypt 内部做了啥转换? ]]>
() => void = (): void =>是什么意思: tag:www.v2ex.com,2024-09-29:/t/1076716 2024-09-29T02:29:33Z 2024-09-29T06:43:59Z Rust2015 member/Rust2015 没见过这么复杂的箭头函数

]]>
避免 Math.ceil(1.1 * 100) == 111 的最佳实践是什么?用户支付金额不对不能入账,排查了半天才发现 JS 这个逆天设计,好像别的语言也有这样的 tag:www.v2ex.com,2024-09-28:/t/1076556 2024-09-28T08:40:44Z 2024-10-01T15:21:13Z drymonfidelia member/drymonfidelia ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86