圆弧派博客 - 专注于网络技术 - JavaScript https://www.iarc.top/group/JavaScript/ JavaScript代码分享 五分钟开发ToDoListAPP后端 https://www.iarc.top/499.html 2025-08-14T21:15:00+08:00 使用CodeBuddy IDE五分钟内即可完成ToDoList基础后端开发,在这个AI工具发达的时代,我们已不需要将全部的知识装进大脑,只需有一个大的框架,细节交给AI即可快速建立项目。环境配置:Node.js将项目需求描述给codebuddy,我这里模型选的是GPT-5-nano,只需稍等几十秒钟,项目将会完全构建以下是codebuddy生成的项目(未进行任何修改)index.js:const express = require('express'); const app = express(); const port = process.env.PORT || 3000; // In-memory storage let todos = []; let nextId = 1; function findTodo(id) { return todos.find(t => t.id === id); } app.use(express.json()); // Get all todos, with optional filtering by completion status app.get('/todos', (req, res) => { const completed = req.query.completed; if (completed !== undefined) { const isDone = completed === 'true'; return res.json(todos.filter(t => t.completed === isDone)); } res.json(todos); }); // Get a single todo by id app.get('/todos/:id', (req, res) => { const id = parseInt(req.params.id, 10); const t = todos.find(t => t.id === id); if (!t) return res.status(404).json({ error: 'Todo not found' }); res.json(t); }); // Create a new todo app.post('/todos', (req, res) => { const { title, description } = req.body; if (!title) return res.status(400).json({ error: 'title is required' }); const todo = { id: nextId++, title, description: description || '', completed: false, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }; todos.push(todo); res.status(201).json(todo); }); // Update an existing todo app.put('/todos/:id', (req, res) => { const id = parseInt(req.params.id, 10); const t = todos.find(t => t.id === id); if (!t) return res.status(404).json({ error: 'Todo not found' }); const { title, description, completed } = req.body; if (title !== undefined) t.title = title; if (description !== undefined) t.description = description; if (completed !== undefined) t.completed = completed; t.updatedAt = new Date().toISOString(); res.json(t); }); // Delete a todo app.delete('/todos/:id', (req, res) => { const id = parseInt(req.params.id, 10); const idx = todos.findIndex(t => t.id === id); if (idx === -1) return res.status(404).json({ error: 'Todo not found' }); const removed = todos.splice(idx, 1); res.json(removed[0]); }); // Health check (optional) app.get('/health', (req, res) => { res.json({ status: 'ok', todoCount: todos.length }); }); app.listen(port, () => { console.log(`Todo backend listening at http://localhost:${port}`); }); package.json{ "name": "todolist-backend", "version": "1.0.0", "description": "In-memory Todo List backend using Node.js + Express", "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "express": "^4.18.2" } }接下来进行npm安装项目运行所需的库,安装完后直接开始运行看看能不能正常跑起来测试阶段:测试接口:(内存存储,重启丢失数据)请求方式路径功能GET/todos获取所有待办,可通过查询参数 completed=true/false 进行筛选POST/todos创建待办,body 示例 { "title": "示例", "description": "可选" }GET/todos/:id获取指定待办PUT/todos/:id更新待办,支持 title、description、completedDELETE/todos/:id删除待办GET/health健康检查获取所有待办:目前初始化成功但还没有添加数据创建待办由于我没有进行前端的编写,这里直接在浏览器控制台模拟前端js发送请求完成接下来的测试,js代码如下:fetch("/todos", { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ "title": "待办名字", "description": "待办描述" }) })已成功创建两个待办事项,重新get请求todos可查看已成功添加通过id获取指定待办信息更新已有待办事项内容成功更新删除待办事项健康检测注意事项: 该版本的待办事项数据仅保存在内存,重启后将全部丢失,仅适合开发/测试阶段。不过接下来可以让codebuddy优化成使用json文件存储或者使用数据库(SQLite、PostgreSQL、MongoDB 等)存储数据,交给各位去继续探索了。评论区留言“CodeBuddy”抽5位送永久体验码!CodeBuddyIDE官网:https://www.codebuddy.ai/我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=6g36nynyzup 萤火虫氛围效果(纯CSS) https://www.iarc.top/376.html 2024-02-15T00:21:00+08:00 .circle-container {position: fixed;top: 0;left: 0;z-index: 1} var firefly = ""; for (var i = 1; i 在手机端不加载JS文件并根据id删除元素的JS代码 https://www.iarc.top/268.html 2023-07-03T21:54:11+08:00 续接上篇JS特效,因为那个鼠标背景JS特效啊,他在手机上的效果比较差还吃手机性能会使得网页变卡,所以下面这段JS代码就来了if (!(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent))) { var script = document.createElement("script"); script.src = "https://www.iarc.top/CDN/js/sbxg.js?v1"; document.head.appendChild(script); } else { var canvas = document.getElementById("sbcanvas"); if (canvas) { canvas.parentNode.removeChild(canvas); } }这样,如果当前设备不是移动设备,则加载js文件;否则,如果sbcanvas元素存在,则从DOM中移除它,这样就直接把它删的彻彻底底不占用手机性能了,而PC端则正常运作。 为自己博客or网页加上鼠标流光背景JS特效 https://www.iarc.top/264.html 2023-07-02T16:06:00+08:00 鼠标流光背景特效(乱起的名别太在意 :@(献花) ),canvas画布配合JS即可实现,这个版本是我从一个人单页里面抄下来的,顺便优化了一下后将其加入到了本站夜间模式{card-default label="快速实现" width=""}<canvas id="sbcanvas" class="sbcanvas"></canvas> <script src="https://www.iarc.top/CDN/js/sbxg.js"></script> <style> .sbcanvas{ display: block; position: fixed; top: 0; z-index: -9; } </style>{/card-default}将特效设为博客夜间模式1.先在body写入<canvas id="sbcanvas" class="sbcanvas"></canvas> <script src="https://www.iarc.top/CDN/js/sbxg.js"></script>2.更改css属性display为none(日间模式不显示该元素).sbcanvas{ display: none; position: fixed; top: 0; z-index: -9; } </style>3.在joe.mode.css文件夹最下面加入以下代码html[data-night='night'] .sbcanvas{display:block;}完成以上操作即可大功告成,快去开启夜间模式试一下吧 简单的Joe主题自动切换日夜间模式JS代码 https://www.iarc.top/262.html 2023-07-02T15:31:00+08:00 由于我最近给夜间模式美化了很多特效 :@(高兴) 希望更多的人能够在晚上看到这些,故自己基于Joe的夜间模式按钮写了一个自动根据时间判断进入日/夜间模式的代码为了实现的效果:每天6~20点默认主题为?日间模式,20~6点为?夜间模式最终版JS代码document.addEventListener("DOMContentLoaded", function () { var now = new Date(); var hour = now.getHours(); if (hour >= 20 || hour < 6) { $(".joe_action_item.mode .icon-1").addClass("active"); $(".joe_action_item.mode .icon-2").removeClass("active"); $("html").attr("data-night", "night"); localStorage.setItem("data-night", "night"); } else { $(".joe_action_item.mode .icon-1").removeClass("active"); $(".joe_action_item.mode .icon-2").addClass("active"); $("html").removeAttr("data-night"); localStorage.removeItem("data-night"); } });{card-default label="? 原理:" width=""}创建一个事件监听函数,它会在网页的DOM内容加载完成后执行。具体来说,它会获取当前时间,并根据时间判断是否处于夜间模式。如果当前时间在晚上8点到早上6点之间(包括8点但不包括6点),就会执行if语句块内的代码。if语句这部分代码是我根据右边的日/夜间模式切换按钮扒出来的{/card-default} script标签中的defer和async可提高网页加载速度 https://www.iarc.top/214.html 2023-06-07T23:59:00+08:00 普通script:1.文档解析的过程中,如果遇到script脚本, 停止页面的解析渲染, 下载script脚本。2.如果是多个script脚本, 近似于同时并行下载script脚本。(虽然说是遇到script脚本, 就停止后面标签的解析渲染; 但chrome做了优化, 遇到script脚本, 会快速的查看后边有没有需要下载其他资源的, 一起并行下载, 为了节省一部分下载的时间。 )3.不论script脚本哪个先下载好, 都按照html中的先后顺序依此执行。 即如果后面的script脚本先下载好, 要等前面的script脚本下载好并执行后, 才能执行。4.执行script脚本时, 也是停止页面的解析渲染。5.执行完script脚本, 继续页面的解析渲染。6.执行完script脚本和页面解析渲染完, 才会依此触发DOMContentLoaded, loaded事件总结:普通script的 下载和执行 都阻塞页面的解析渲染。多个script的下载是并行, 但按照页面中顺序依此执行。考虑到不支持defer和async的老浏览器, 最佳实践是script放在body底部, 避免阻塞页面的解析渲染。执行完script脚本, 继续页面的解析渲染。页面解析渲染完, 才会触发DOMContentLoaded。所以普通script脚本的下载和执行如果慢, 会延迟DOMContentLoaded事件的触发时间。defer:文档解析时,遇到设置了defer的script脚本,就会在后台进行下载,下载并不会阻止文档的解析渲染。如果是多个设置了defer的script脚本, 近似于同时并行下载defer脚本。当页面解析渲染完毕后, 会等到所有的defer脚本下载完毕并按照顺序执行,执行完毕后会触发DOMContentLoaded事件。如果defer脚本下载较快, 会等到页面解析渲染完毕后, 才按照顺序执行defer脚本。执行完毕后会触发DOMContentLoaded事件。如果defer脚本下载较慢, 在下载完前, 页面解析渲染已完毕; 等defer脚本下载完后, 才按照顺序执行defer脚本。执行完毕后会触发DOMContentLoaded事件。总结:defer脚本的 下载和执行 都不会阻塞页面的解析渲染。因为等到页面的解析渲染完毕后, defer脚本才执行, 所以defer脚本执行 也不会阻塞页面的解析渲染。多个defer脚本的下载是并行, 但按照顺序依此执行。等页面的解析渲染完毕后, 触发DOMContentLoaded事件前, defer脚本才依次执行。 所以defer脚本的下载和执行如果慢, 会延迟DOMContentLoaded事件的触发时间。考虑有的浏览器不支持 defer场景, 多个defer脚本不一定会按照顺序执行, 最佳实践是只使用一个defer脚本。推荐场景:如果你的脚本代码依赖于页面中的DOM元素(文档是否解析完毕),或者被其他脚本文件依赖。例:评论框代码语法高亮polyfill.jsasync:文档解析时,遇到设置了async的script脚本,就会在后台进行下载,下载并不会阻止文档的解析渲染。如果是多个设置了async的script脚本, 近似于同时并行下载async脚本。async脚本的执行会阻止文档的解析渲染。哪个async脚本先下载完, 就立刻执行, 执行时阻止文档的解析渲染。async脚本执行顺序不按照页面中的脚本先后顺序。async脚本的下载和执行不计入DOMContentLoaded事件统计。因async脚本下载不阻塞文档的解析渲染; 如果async脚本下载较快, 趁async脚本下载很短时间内, 文档的解析渲染未完成, async下载后立即执行, 执行时会阻塞文档的解析渲染; 执行后, 继续文档的解析渲染, 等页面的解析渲染完毕后, 触发DOMContentLoaded事件。这种场景, async脚本的执行如果慢, 会延迟DOMContentLoaded事件的触发时间。如果async脚本下载较慢, 当async还在下载时, 文档的解析渲染已完成, 这时不会等待async的下载, 会直接触发DOMContentLoaded事件。这种场景, async脚本的下载和执行不会延迟DOMContentLoaded事件的触发时间。总结:async脚本的 下载 不会阻塞页面的解析渲染。async脚本的 执行 会阻塞页面的解析渲染。多个async脚本的下载是并行, 但执行不按照页面中的脚本先后顺序。哪个async脚本先下载完, 哪个async脚本就先立刻执行。async脚本的下载和执行不计入DOMContentLoaded事件统计。async脚本的执行有可能在 DOMContentLoaded 事件前, 也有可能在 DOMContentLoaded 事件后。当async脚本的执行在 DOMContentLoaded 事件前时, async脚本的执行时间才会影响DOMContentLoaded事件的触发时间。又因为脚本的执行时间一般都比较短, 所以可以认为async脚本基本不影响DOMContentLoaded事件的触发时间。推荐场景:如果你的脚本并不关心页面中的DOM元素(文档是否解析完毕),并且也不会产生其他脚本需要的数据。例:百度统计和Google Analytics 普通script, defer, async同时存在页面中:普通script执行完, 继续页面解析渲染; 页面解析渲染完, 才触发DOMContentLoaded事件。defer脚本是在页面解析渲染完, DOMContentLoaded事件的触发前, 才执行defer脚本。由于1,2这两点, 所以一定先执行普通script, 再执行defer脚本。async脚本的下载和执行不计入DOMContentLoaded事件统计。async脚本下载完, 就立刻执行, 且多个async脚本执行不按照页面中的脚本先后顺序。由于4,5这两点, 所以async脚本执行与普通script, defer脚本无关, 那个时间点都有可能执行。ps:defer,async只对外联script脚本文件有效, 内联script脚本设置无效。 动态引入JS文件方法和一个网页狂欢代码 https://www.iarc.top/203.html 2023-06-04T19:15:00+08:00 {gird column="2" gap="3"}{gird-item}{/gird-item}{gird-item}狂欢插件效果:点击我开启网页狂欢 function loadScript() { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'https://iarc.top/tool/firer.js'; document.head.appendChild(script); script.onload = function() { testFun(); } } 使用方法:在网页头部引入firer.js{/gird-item}{/gird}<script src="https://iarc.top/tool/firer.js"></script>或者新建一个浏览器书签,地址填下面这个:javascript:void(function(){var d = document,a = 'setAttribute',s = d.createElement('script');s[a]('type','text/javascript');s[a]('src','https://iarc.top/tool/firer.js');d.head.appendChild(s);})();动态引入JS文件代码:用户未点击按钮前不引入JS文件,用户点击按钮后引入外部JS文件并执行<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>动态引入JS文件</title> </head> <body> <button onclick="loadScript()">点击我加载并执行JS</button> <script> function loadScript() { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'https://iarc.top/tool/firer.js'; // 外部JS文件路径或者链接 document.head.appendChild(script); script.onload = function() { // JS文件加载完成后执行函数 testFun(); //调用外部JS文件中的函数 } } </script> </body> </html> 在 body 标签中添加一个点击按钮触发事件并执行 loadScript() 函数。该函数通过创建一个 script 元素,并设置其 src 属性为外部JS文件的路径,在页面中动态加载了外部JS文件。同时,使用 onload 事件监听文件加载完毕后执行的操作,这里将调用外部JS文件中的函数(例子中为 testFun())。 为typecho joe添加评论区语录 https://www.iarc.top/179.html 2023-05-14T14:58:00+08:00 前言博客之前经常有人回复一些无意义的内容,导致很多垃圾评论所以我在想既然很多游客喜欢回复一些垃圾评论,不如我直接设置一个随机一言,让他们省去了垃圾评论的打字时间,同时又能让我的评论区少一些无意义的评论而且那些真正认真回复的人只需要一键删除即可,也不会很影响评论体验,所以就给自己的评论框添加了随机一言效果展示先来一波效果展示本教程仅以Joe主题为例,其他主题可自行发挥能力,如有技术问题,博主可提供简单的指导教程开始一、添加后台控制在 Joe/functions.php内添加以下代码// 评论框随机语录功能 $Comment_Citation = new Typecho_Widget_Helper_Form_Element_Select( 'Comment_Citation', array('off' => '关闭(默认)', 'on' => '开启'), 'off', '是否开启评论框随机语录功能', '介绍:开启后,评论框自动随机填充随机语录' ); $Comment_Citation->setAttribute('class', 'joe_content joe_other'); $form->addInput($Comment_Citation->multiMode()); //评论框随机语录链接/文字 $Comment_Citation__text = new Typecho_Widget_Helper_Form_Element_Textarea( 'Comment_Citation__text', NULL, "https://api.vvhan.com/api/ian", '评论框随机语录', '介绍:用于修改评论框随机语录(可以为api地址) <br /> 格式:一行一个,可以为api地址,也可为文字,可以填写多个API地址<br /> 注意:必须填写JSON格式的API,API需要开启跨域权限才能调取,否则会调取失败!<br /> 如果为api地址可在前台按钮刷新内容,如果为文字只能刷新页面来刷新内容(建议使用api地址)<br /> 推荐API:https://api.vvhan.com/api/ian' ); $Comment_Citation__text->setAttribute('class', 'joe_content joe_other'); $form->addInput($Comment_Citation__text);二、添加刷新按钮(可省略)在 Joe/public/comment.php 添加以下代码,不添加则不设置刷新按钮{tabs-pane label="添加位置"}{/tabs-pane}{tabs-pane label="添加代码"}<?php if ($this->options->Comment_Citation !== "off") : ?> <div class="Comment_Citation" title="语录"> <div class='comment_box'> <i class='fa fa-fw fa-refresh' aria-hidden='true'></i> <span class="title">语录</span> </div> </div> <?php endif; ?>{/tabs-pane}三、添加内容获取1、添加后端获取在 Joe/core/function.php 添加以下代码{tabs-pane label="添加位置"}{/tabs-pane}{tabs-pane label="添加代码"}/* 获取评论框随机语录 */ function _getComment_Citation() { $CitationRandom = explode("\r\n", Helper::options()->Comment_Citation__text); echo $CitationRandom[array_rand($CitationRandom)]; }{/tabs-pane}2、添加前端获取在 Joe/public/config.php 添加以下代码{tabs-pane label="添加位置"}{/tabs-pane}{tabs-pane label="添加代码"}CITATION: `<?php _getComment_Citation() ?>`, // 评论随机语录{/tabs-pane}四、添加核心代码{hide}在 Joe/assets/js/joe.global.min.js 添加以下代码if ($(".Comment_Citation").length) {function e() {let e = Joe.CITATION,t = /(https?:\/\/[^\s]+)/g;t.test(e)? $.ajax({url: e,dataType: "text",success: (e) => $(".joe_comment__respond-form .body textarea").val(e),}) : $(".joe_comment__respond-form .body textarea").val(e);}e(),$(".Comment_Citation").click(function () { e(); });}{/hide}五、添加刷新按钮样式(可省略)这是刷新按钮样式,如果前面没添加刷新按钮,可跳过此步骤在 Joe/assets/css/joe.global.min.css添加以下代码.joe_owo__contain { position: static; .box { position: absolute; bottom: 100%; margin-bottom: 6px; left: 0px; padding-top: 5px; border: 1px solid rgba(0, 0, 0, 0.15); border-color: transparent; box-shadow: 0 0 10px 8px rgb(116 116 116 / 8%); } } .comment_box { cursor: pointer; text-align: center; color: var(--routine); height: 26px; line-height: 26px; background: var(--background); opacity: 0.85; border-radius: 13px; width: 70px; margin-left: 5px; &:hover { background: var(--theme); color: #fff; }}结语教程稍有点复杂,但其实是沿用侧栏随机一言的方法,所以如果你能看懂核心js的话,可以仅修改 第四步 中ajax的 url 来实现,那样会简单很多很多 「公益」MetingApi接口(可解网易云音乐黑胶歌曲) https://www.iarc.top/149.html 2023-02-05T21:12:00+08:00 我们都是苦旅人,因为一点善念、一丝感动、一处荫蔽走在山水间,也曾发宏愿把世界走遍,却止步于尘烟。2023年应是改变的一年,势必遇见新的自己!给各位拜个晚年,元宵节快乐!Github开源地址:https://github.com/metowolf/MetingMeting自带的接口目前无法解析网易云黑胶音乐了(只能放40秒),所以圆弧免费为广大站长提供一个能解析网易云黑胶和QQ音乐VIP歌曲的MetingApi接口:https://v.iarc.top/在Meting.js文件里第40行左右的API替换成上面的即可再附上一个第三方接口:https://api.mizore.cn/meting/api.php第个直接请求会403,并非接口失效,带上参数请求即可,例:https://api.mizore.cn/meting/api.php?server=netease&type=playlist&id=7783760543&r=:r 参数 默认 描述 id require 歌曲 ID / 播放列表 ID / 专辑 ID / 搜索关键字 server require 音乐平台: netease, tencent, kugou, xiami, baidu type require song, playlist, album, search, artist auto options 音乐链接,支持: netease, tencent, xiami fixed false 固定模式 mini false 迷你模式 autoplay false 自动播放 theme #2980b9 主题色 loop all 播放器循环播放,值: 'all', 'one', 'none' order list 播放顺序: 'list', 'random' preload auto 预加载值: 'none', 'metadata', 'auto' volume 0.7 默认音量,注意播放器会记住用户设置,用户自己设置音量后默认音量将不起作用 mutex true 防止同时播放,当这个播放开始时暂停其他播放 lrc-type 0 歌词类型 list-folded false 指示列表是否应该首先折叠 list-max-height 340px 列出最大高度 storage-name metingjs 存储播放器设置的 localStorage 键 {abtn icon="fa-bandcamp" color="#ff6800" href="https://www.iarc.top/57.html" radius="17.5px" content="Meting使用方法"/}该解析接口的网易云黑胶不会到期。绿钻到期了,QQ音乐只能解析非会员音乐了。 JavaScript实现音乐单曲循环 https://www.iarc.top/87.html 2022-12-25T19:08:00+08:00 步骤1.创建audio对象var audio= new Audio("./musics/bgm.mp3");//这里的路径写上mp3文件在项目中的绝对路径2.获取audio的时长,audio的 duration 属性 前往w3schools查看audio属性var duration; duration=audio.duration;//长度单位是秒3.定义播放audio的函数function bgm(){ audio.play();//播放 } bgm();//定义完成之后开始调用第一次4.再创建定时器window.setInterval("bgm()",duration*1000+1000);完整代码var audio= new Audio("./musics/bgm.mp3");//这里的路径写上mp3文件在项目中的绝对路径 var duration; duration=audio.duration;//长度单位是秒 function bgm(){ audio.play();//播放 } window.setInterval("bgm()",duration*1000+1000);